forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dl_vertices.h
287 lines (242 loc) · 10.8 KB
/
dl_vertices.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_DISPLAY_LIST_DL_VERTICES_H_
#define FLUTTER_DISPLAY_LIST_DL_VERTICES_H_
#include <memory>
#include "flutter/display_list/dl_color.h"
#include "third_party/skia/include/core/SkRect.h"
namespace flutter {
//------------------------------------------------------------------------------
/// @brief Defines the way in which the vertices of a DlVertices object
/// are separated into triangles into which to render.
///
enum class DlVertexMode {
/// The vertices are taken 3 at a time to form a triangle.
kTriangles,
/// The vertices are taken in overlapping triplets to form triangles, with
/// each triplet sharing 2 of its vertices with the preceding and following
/// triplets.
/// vertices [ABCDE] yield 3 triangles ABC,BCD,CDE
kTriangleStrip,
/// The vertices are taken in overlapping pairs and combined with the first
/// vertex to form triangles that radiate outward from the initial point.
/// vertices [ABCDE] yield 3 triangles ABC,ACD,ADE
kTriangleFan,
};
//------------------------------------------------------------------------------
/// @brief Holds all of the data (both required and optional) for a
/// DisplayList drawVertices call.
///
/// There are 4 main pices of data:
/// - vertices():
/// the points on the rendering surface that define the pixels
/// being rendered to in a series of triangles. These points
/// can map to triangles in various ways depending on the
/// supplied |DlVertexMode|.
/// - texture_coordinates():
/// the points in the DlColorSource to map to the coordinates
/// of the triangles in the vertices(). If missing, the
/// vertex coordinates themselves will be used to map the
/// source colors to the vertices.
/// - colors():
/// colors to map to each triangle vertex. Note that each
/// vertex is mapped to exactly 1 color even if the DlVertex
/// - indices():
/// An indirection based on indices into the array of vertices
/// (and by extension, their associated texture_coordinates and
/// colors). Note that the DLVertexMode will still apply to the
/// indices in the same way (and instead of the way) that it
/// would normally be applied to the vertices themselves. The
/// indices are useful, for example, to fill the vertices with
/// a grid of points and then use the indices to define a
/// triangular mesh that covers that grid without having to
/// repeat the vertex (and texture coordinate and color)
/// information for the times when a given grid coordinate
/// gets reused in up to 4 mesh triangles.
///
/// Note that each vertex is mapped to exactly 1 texture_coordinate and
/// color even if the DlVertexMode or indices specify that it contributes
/// to more than one output triangle.
///
class DlVertices {
public:
/// @brief A utility class to build up a |DlVertices| object
/// one set of data at a time.
class Builder {
public:
/// @brief flags to indicate/promise which of the optional
/// texture coordinates or colors will be supplied
/// during the build phase.
union Flags {
struct {
unsigned has_texture_coordinates : 1;
unsigned has_colors : 1;
};
uint32_t mask = 0;
inline Flags operator|(const Flags& rhs) const {
return {.mask = (mask | rhs.mask)};
}
inline Flags& operator|=(const Flags& rhs) {
mask = mask | rhs.mask;
return *this;
}
};
static constexpr Flags kNone = {{false, false}};
static constexpr Flags kHasTextureCoordinates = {{true, false}};
static constexpr Flags kHasColors = {{false, true}};
//--------------------------------------------------------------------------
/// @brief Constructs a Builder and prepares room for the
/// required and optional data.
///
/// Vertices are always required. Optional texture coordinates
/// and optional colors are reserved depending on the |Flags|.
/// Optional indices will be reserved if the index_count is
/// positive (>0).
///
/// The caller must provide all data that is promised by the
/// supplied |flags| and |index_count| parameters before
/// calling the |build()| method.
Builder(DlVertexMode mode, int vertex_count, Flags flags, int index_count);
/// Returns true iff the underlying object was successfully allocated.
bool is_valid() { return vertices_ != nullptr; }
/// @brief Copies the indicated list of points as vertices.
///
/// fails if vertices have already been supplied.
void store_vertices(const SkPoint points[]);
/// @brief Copies the indicated list of float pairs as vertices.
///
/// fails if vertices have already been supplied.
void store_vertices(const float coordinates[]);
/// @brief Copies the indicated list of points as texture coordinates.
///
/// fails if texture coordinates have already been supplied or if they
/// were not promised by the flags.has_texture_coordinates.
void store_texture_coordinates(const SkPoint points[]);
/// @brief Copies the indicated list of float pairs as texture coordinates.
///
/// fails if texture coordinates have already been supplied or if they
/// were not promised by the flags.has_texture_coordinates.
void store_texture_coordinates(const float coordinates[]);
/// @brief Copies the indicated list of colors as vertex colors.
///
/// fails if colors have already been supplied or if they were not
/// promised by the flags.has_colors.
void store_colors(const DlColor colors[]);
/// @brief Copies the indicated list of unsigned ints as vertex colors
/// in the 32-bit RGBA format.
///
/// fails if colors have already been supplied or if they were not
/// promised by the flags.has_colors.
void store_colors(const uint32_t colors[]) {
store_colors(reinterpret_cast<const DlColor*>(colors));
}
/// @brief Copies the indicated list of 16-bit indices as vertex indices.
///
/// fails if indices have already been supplied or if they were not
/// promised by (index_count > 0).
void store_indices(const uint16_t indices[]);
/// @brief Finalizes and the constructed DlVertices object.
///
/// fails if any of the optional data promised in the constructor is
/// missing.
std::shared_ptr<DlVertices> build();
private:
std::shared_ptr<DlVertices> vertices_;
bool needs_vertices_ = true;
bool needs_texture_coords_;
bool needs_colors_;
bool needs_indices_;
};
//--------------------------------------------------------------------------
/// @brief Constructs a DlVector with compact inline storage for all
/// of its required and optional lists of data.
///
/// Vertices are always required. Optional texture coordinates
/// and optional colors are stored if the arguments are non-null.
/// Optional indices will be stored iff the array argument is
/// non-null and the index_count is positive (>0).
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);
/// Returns the size of the object including all of the inlined data.
size_t size() const;
/// Returns the bounds of the vertices.
SkRect bounds() const { return bounds_; }
/// Returns the vertex mode that defines how the vertices (or the indices)
/// are turned into triangles.
DlVertexMode mode() const { return mode_; }
/// Returns the number of vertices, which also applies to the number of
/// texture coordinate and colors if they are provided.
int vertex_count() const { return vertex_count_; }
/// Returns a pointer to the vertex information. Should be non-null.
const SkPoint* vertices() const {
return static_cast<const SkPoint*>(pod(vertices_offset_));
}
/// Returns a pointer to the vertex texture coordinate
/// or null if none were provided.
const SkPoint* texture_coordinates() const {
return static_cast<const SkPoint*>(pod(texture_coordinates_offset_));
}
/// Returns a pointer to the vertex colors
/// or null if none were provided.
const DlColor* colors() const {
return static_cast<const DlColor*>(pod(colors_offset_));
}
/// Returns a pointer to the count of vertex indices
/// or 0 if none were provided.
int index_count() const { return index_count_; }
/// Returns a pointer to the vertex indices
/// or null if none were provided.
const uint16_t* indices() const {
return static_cast<const uint16_t*>(pod(indices_offset_));
}
bool operator==(DlVertices const& other) const;
bool operator!=(DlVertices const& other) const { return !(*this == other); }
private:
// Constructors are designed to encapsulate arrays sequentially in memory
// which means they can only be called by intantiations that use the
// new (ptr) paradigm which precomputes and preallocates the memory for
// the class body and all of its arrays, such as in Builder.
DlVertices(DlVertexMode mode,
int vertex_count,
const SkPoint vertices[],
const SkPoint texture_coordinates[],
const DlColor colors[],
int index_count,
const uint16_t indices[],
const SkRect* bounds = nullptr);
// This constructor is specifically used by the DlVertices::Builder to
// establish the object before the copying of data is requested.
DlVertices(DlVertexMode mode,
int vertex_count,
Builder::Flags flags,
int index_count);
// The copy constructor has the same memory pre-allocation requirements
// as this other constructors. This particular version is used by the
// DisplaylistBuilder to copy the instance into pre-allocated pod memory
// in the display list buffer.
explicit DlVertices(const DlVertices* other);
DlVertexMode mode_;
int vertex_count_;
size_t vertices_offset_;
size_t texture_coordinates_offset_;
size_t colors_offset_;
int index_count_;
size_t indices_offset_;
SkRect bounds_;
const void* pod(int offset) const {
if (offset <= 0) {
return nullptr;
}
const void* base = static_cast<const void*>(this);
return static_cast<const char*>(base) + offset;
}
friend class DisplayListBuilder;
};
} // namespace flutter
#endif // FLUTTER_DISPLAY_LIST_DL_VERTICES_H_