Flutter Engine
The Flutter Engine
dl_vertices.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/display_list/dl_vertices.h"
6
7#include "flutter/display_list/utils/dl_accumulation_rect.h"
8#include "flutter/fml/logging.h"
9
10namespace flutter {
11
13
14static void DlVerticesDeleter(void* p) {
15 // Some of our target environments would prefer a sized delete,
16 // but other target environments do not have that operator.
17 // Use an unsized delete until we get better agreement in the
18 // environments.
19 // See https://github.com/flutter/flutter/issues/100327
20 ::operator delete(p);
21}
22
23static size_t bytes_needed(int vertex_count, Flags flags, int index_count) {
24 int needed = sizeof(DlVertices);
25 // We always have vertices
26 needed += vertex_count * sizeof(SkPoint);
27 if (flags.has_texture_coordinates) {
28 needed += vertex_count * sizeof(SkPoint);
29 }
30 if (flags.has_colors) {
31 needed += vertex_count * sizeof(DlColor);
32 }
33 if (index_count > 0) {
34 needed += index_count * sizeof(uint16_t);
35 }
36 return needed;
37}
38
39std::shared_ptr<DlVertices> DlVertices::Make(
41 int vertex_count,
42 const SkPoint vertices[],
43 const SkPoint texture_coordinates[],
44 const DlColor colors[],
45 int index_count,
46 const uint16_t indices[]) {
47 if (!vertices || vertex_count <= 0) {
48 vertex_count = 0;
49 texture_coordinates = nullptr;
50 colors = nullptr;
51 }
52 if (!indices || index_count <= 0) {
53 index_count = 0;
54 indices = nullptr;
55 }
56
58 FML_DCHECK(!flags.has_texture_coordinates);
59 FML_DCHECK(!flags.has_colors);
62 }
63 if (colors) {
65 }
67
68 builder.store_vertices(vertices);
70 builder.store_texture_coordinates(texture_coordinates);
71 }
72 if (colors) {
73 builder.store_colors(colors);
74 }
75 if (indices) {
76 builder.store_indices(indices);
77 }
78
79 return builder.build();
80}
81
82size_t DlVertices::size() const {
83 return bytes_needed(vertex_count_,
84 {{texture_coordinates_offset_ > 0, colors_offset_ > 0}},
85 index_count_);
86}
87
89 AccumulationRect accumulator;
90 for (int i = 0; i < count; i++) {
91 accumulator.accumulate(points[i]);
92 }
93 return accumulator.bounds();
94}
95
96DlVertices::DlVertices(DlVertexMode mode,
97 int unchecked_vertex_count,
98 const SkPoint* vertices,
99 const SkPoint* texture_coordinates,
100 const DlColor* colors,
101 int unchecked_index_count,
102 const uint16_t* indices,
103 const SkRect* bounds)
104 : mode_(mode),
105 vertex_count_(std::max(unchecked_vertex_count, 0)),
106 index_count_(indices ? std::max(unchecked_index_count, 0) : 0) {
107 bounds_ = bounds ? *bounds : compute_bounds(vertices, vertex_count_);
108
109 char* pod = reinterpret_cast<char*>(this);
110 size_t offset = sizeof(DlVertices);
111
112 auto advance = [pod, &offset](auto* src, int count) {
113 if (src != nullptr && count > 0) {
114 size_t bytes = count * sizeof(*src);
115 memcpy(pod + offset, src, bytes);
116 size_t ret = offset;
117 offset += bytes;
118 return ret;
119 } else {
120 return static_cast<size_t>(0);
121 }
122 };
123
124 vertices_offset_ = advance(vertices, vertex_count_);
125 texture_coordinates_offset_ = advance(texture_coordinates, vertex_count_);
126 colors_offset_ = advance(colors, vertex_count_);
127 indices_offset_ = advance(indices, index_count_);
128 FML_DCHECK(offset == bytes_needed(vertex_count_,
129 {{!!texture_coordinates, !!colors}},
130 index_count_));
131}
132
133DlVertices::DlVertices(const DlVertices* other)
134 : DlVertices(other->mode_,
135 other->vertex_count_,
136 other->vertices(),
137 other->texture_coordinates(),
138 other->colors(),
139 other->index_count_,
140 other->indices(),
141 &other->bounds_) {}
142
143DlVertices::DlVertices(DlVertexMode mode,
144 int unchecked_vertex_count,
145 Flags flags,
146 int unchecked_index_count)
147 : mode_(mode),
148 vertex_count_(std::max(unchecked_vertex_count, 0)),
149 index_count_(std::max(unchecked_index_count, 0)) {
150 char* pod = reinterpret_cast<char*>(this);
151 size_t offset = sizeof(DlVertices);
152
153 auto advance = [pod, &offset](size_t size, int count) {
154 if (count > 0) {
155 size_t bytes = count * size;
156 memset(pod + offset, 0, bytes);
157 size_t ret = offset;
158 offset += bytes;
159 return ret;
160 } else {
161 return static_cast<size_t>(0);
162 }
163 };
164
165 vertices_offset_ = advance(sizeof(SkPoint), vertex_count_);
166 texture_coordinates_offset_ = advance(
167 sizeof(SkPoint), flags.has_texture_coordinates ? vertex_count_ : 0);
168 colors_offset_ =
169 advance(sizeof(DlColor), flags.has_colors ? vertex_count_ : 0);
170 indices_offset_ = advance(sizeof(uint16_t), index_count_);
171 FML_DCHECK(offset == bytes_needed(vertex_count_, flags, index_count_));
172 FML_DCHECK((vertex_count_ != 0) == (vertices() != nullptr));
173 FML_DCHECK((vertex_count_ != 0 && flags.has_texture_coordinates) ==
174 (texture_coordinates() != nullptr));
175 FML_DCHECK((vertex_count_ != 0 && flags.has_colors) == (colors() != nullptr));
176 FML_DCHECK((index_count_ != 0) == (indices() != nullptr));
177}
178
179bool DlVertices::operator==(DlVertices const& other) const {
180 auto lists_equal = [](auto* a, auto* b, int count) {
181 if (a == nullptr || b == nullptr) {
182 return a == b;
183 }
184 for (int i = 0; i < count; i++) {
185 if (a[i] != b[i]) {
186 return false;
187 }
188 }
189 return true;
190 };
191 return //
192 mode_ == other.mode_ && //
193 vertex_count_ == other.vertex_count_ && //
194 lists_equal(vertices(), other.vertices(), vertex_count_) && //
195 lists_equal(texture_coordinates(), other.texture_coordinates(), //
196 vertex_count_) && //
197 lists_equal(colors(), other.colors(), vertex_count_) && //
198 index_count_ == other.index_count_ && //
199 lists_equal(indices(), other.indices(), index_count_);
200}
201
203 int vertex_count,
204 Flags flags,
205 int index_count)
206 : needs_texture_coords_(flags.has_texture_coordinates),
207 needs_colors_(flags.has_colors),
208 needs_indices_(index_count > 0) {
211 void* storage =
212 ::operator new(bytes_needed(vertex_count, flags, index_count));
213 vertices_.reset(new (storage)
216}
217
218static void store_points(char* dst, int offset, const float* src, int count) {
219 SkPoint* points = reinterpret_cast<SkPoint*>(dst + offset);
220 for (int i = 0; i < count; i++) {
221 points[i] = SkPoint::Make(src[i * 2], src[i * 2 + 1]);
222 }
223}
224
227 FML_CHECK(needs_vertices_);
228 char* pod = reinterpret_cast<char*>(vertices_.get());
229 size_t bytes = vertices_->vertex_count_ * sizeof(vertices[0]);
230 memcpy(pod + vertices_->vertices_offset_, vertices, bytes);
231 needs_vertices_ = false;
232}
233
236 FML_CHECK(needs_vertices_);
237 char* pod = reinterpret_cast<char*>(vertices_.get());
238 store_points(pod, vertices_->vertices_offset_, vertices,
239 vertices_->vertex_count_);
240 needs_vertices_ = false;
241}
242
245 FML_CHECK(needs_texture_coords_);
246 char* pod = reinterpret_cast<char*>(vertices_.get());
247 size_t bytes = vertices_->vertex_count_ * sizeof(coords[0]);
248 memcpy(pod + vertices_->texture_coordinates_offset_, coords, bytes);
249 needs_texture_coords_ = false;
250}
251
254 FML_CHECK(needs_texture_coords_);
255 char* pod = reinterpret_cast<char*>(vertices_.get());
256 store_points(pod, vertices_->texture_coordinates_offset_, coords,
257 vertices_->vertex_count_);
258 needs_texture_coords_ = false;
259}
260
263 FML_CHECK(needs_colors_);
264 char* pod = reinterpret_cast<char*>(vertices_.get());
265 size_t bytes = vertices_->vertex_count_ * sizeof(colors[0]);
266 memcpy(pod + vertices_->colors_offset_, colors, bytes);
267 needs_colors_ = false;
268}
269
272 FML_CHECK(needs_indices_);
273 char* pod = reinterpret_cast<char*>(vertices_.get());
274 size_t bytes = vertices_->index_count_ * sizeof(indices[0]);
275 memcpy(pod + vertices_->indices_offset_, indices, bytes);
276 needs_indices_ = false;
277}
278
279std::shared_ptr<DlVertices> DlVertices::Builder::build() {
281 if (vertices_->vertex_count() <= 0) {
282 // We set this to true in the constructor to make sure that they
283 // call store_vertices() only once, but if there are no vertices
284 // then we will not object to them never having stored any vertices
285 needs_vertices_ = false;
286 }
287 FML_CHECK(!needs_vertices_);
288 FML_CHECK(!needs_texture_coords_);
289 FML_CHECK(!needs_colors_);
290 FML_CHECK(!needs_indices_);
291
292 vertices_->bounds_ =
293 compute_bounds(vertices_->vertices(), vertices_->vertex_count_);
294
295 return std::move(vertices_);
296}
297
298} // namespace flutter
int count
Definition: FontMgrTest.cpp:50
static const int points[]
static bool is_valid(SkISize dim)
void accumulate(SkScalar x, SkScalar y)
A utility class to build up a |DlVertices| object one set of data at a time.
Definition: dl_vertices.h:75
void store_texture_coordinates(const SkPoint points[])
Copies the indicated list of points as texture coordinates.
Definition: dl_vertices.cc:243
void store_vertices(const SkPoint points[])
Copies the indicated list of points as vertices.
Definition: dl_vertices.cc:225
void store_indices(const uint16_t indices[])
Copies the indicated list of 16-bit indices as vertex indices.
Definition: dl_vertices.cc:270
std::shared_ptr< DlVertices > build()
Finalizes and the constructed DlVertices object.
Definition: dl_vertices.cc:279
static constexpr Flags kHasColors
Definition: dl_vertices.h:98
void store_colors(const DlColor colors[])
Copies the indicated list of colors as vertex colors.
Definition: dl_vertices.cc:261
static constexpr Flags kHasTextureCoordinates
Definition: dl_vertices.h:97
Holds all of the data (both required and optional) for a DisplayList drawVertices call.
Definition: dl_vertices.h:71
static std::shared_ptr< DlVertices > Make(DlVertexMode mode, int vertex_count, const SkPoint vertices[], const SkPoint texture_coordinates[], const DlColor colors[], int index_count=0, const uint16_t indices[]=nullptr)
Constructs a DlVector with compact inline storage for all of its required and optional lists of data.
Definition: dl_vertices.cc:39
const DlColor * colors() const
Definition: dl_vertices.h:217
int vertex_count() const
Definition: dl_vertices.h:202
DlVertexMode mode() const
Definition: dl_vertices.h:198
int index_count() const
Definition: dl_vertices.h:223
const SkPoint * vertices() const
Returns a pointer to the vertex information. Should be non-null.
Definition: dl_vertices.h:205
size_t size() const
Returns the size of the object including all of the inlined data.
Definition: dl_vertices.cc:82
const uint16_t * indices() const
Definition: dl_vertices.h:227
const SkPoint * texture_coordinates() const
Definition: dl_vertices.h:211
static bool b
struct MyStruct a[10]
FlutterSemanticsFlag flags
#define FML_CHECK(condition)
Definition: logging.h:85
#define FML_DCHECK(condition)
Definition: logging.h:103
static float max(float r, float g, float b)
Definition: hsl.cpp:49
Optional< SkRect > bounds
Definition: SkRecords.h:189
PODArray< SkColor > colors
Definition: SkRecords.h:276
DlVertices::Builder Builder
static void DlVerticesDeleter(void *p)
Definition: dl_vertices.cc:14
DlVertices::Builder::Flags Flags
Definition: dl_vertices.cc:12
DlVertexMode
Defines the way in which the vertices of a DlVertices object are separated into triangles into which ...
Definition: dl_vertices.h:20
static void store_points(char *dst, int offset, const float *src, int count)
Definition: dl_vertices.cc:218
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
static SkRect compute_bounds(const SkPoint *points, int count)
Definition: dl_vertices.cc:88
static size_t bytes_needed(int vertex_count, Flags flags, int index_count)
Definition: dl_vertices.cc:23
bool operator==(C p1, const scoped_nsprotocol< C > &p2)
dst
Definition: cp.py:12
Definition: ref_ptr.h:256
flutter::DlColor DlColor
SeparatedVector2 offset
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
flags to indicate/promise which of the optional texture coordinates or colors will be supplied during...
Definition: dl_vertices.h:80