Line data Source code
1 : /*
2 : * Copyright 2017 Google Inc.
3 : *
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #ifndef SkVertices_DEFINED
9 : #define SkVertices_DEFINED
10 :
11 : #include "SkColor.h"
12 : #include "SkData.h"
13 : #include "SkPoint.h"
14 : #include "SkRect.h"
15 : #include "SkRefCnt.h"
16 :
17 : /**
18 : * An immutable set of vertex data that can be used with SkCanvas::drawVertices.
19 : */
20 0 : class SkVertices : public SkNVRefCnt<SkVertices> {
21 : public:
22 : enum VertexMode {
23 : kTriangles_VertexMode,
24 : kTriangleStrip_VertexMode,
25 : kTriangleFan_VertexMode,
26 : };
27 :
28 : /**
29 : * Create a vertices by copying the specified arrays. texs and colors may be nullptr,
30 : * and indices is ignored if indexCount == 0.
31 : */
32 : static sk_sp<SkVertices> MakeCopy(VertexMode mode, int vertexCount,
33 : const SkPoint positions[],
34 : const SkPoint texs[],
35 : const SkColor colors[],
36 : int indexCount,
37 : const uint16_t indices[]);
38 :
39 : static sk_sp<SkVertices> MakeCopy(VertexMode mode, int vertexCount,
40 : const SkPoint positions[],
41 : const SkPoint texs[],
42 : const SkColor colors[]) {
43 : return MakeCopy(mode, vertexCount, positions, texs, colors, 0, nullptr);
44 : }
45 :
46 : struct Sizes;
47 :
48 : enum BuilderFlags {
49 : kHasTexCoords_BuilderFlag = 1 << 0,
50 : kHasColors_BuilderFlag = 1 << 1,
51 : };
52 0 : class Builder {
53 : public:
54 : Builder(VertexMode mode, int vertexCount, int indexCount, uint32_t flags);
55 :
56 0 : bool isValid() const { return fVertices != nullptr; }
57 :
58 : // if the builder is invalid, these will return 0
59 : int vertexCount() const;
60 : int indexCount() const;
61 : SkPoint* positions();
62 : SkPoint* texCoords(); // returns null if there are no texCoords
63 : SkColor* colors(); // returns null if there are no colors
64 : uint16_t* indices(); // returns null if there are no indices
65 :
66 : // Detach the built vertices object. After the first call, this will always return null.
67 : sk_sp<SkVertices> detach();
68 :
69 : private:
70 : Builder(VertexMode mode, int vertexCount, int indexCount, const Sizes&);
71 :
72 : void init(VertexMode mode, int vertexCount, int indexCount, const Sizes&);
73 :
74 : // holds a partially complete object. only completed in detach()
75 : sk_sp<SkVertices> fVertices;
76 :
77 : friend class SkVertices;
78 : };
79 :
80 0 : uint32_t uniqueID() const { return fUniqueID; }
81 0 : VertexMode mode() const { return fMode; }
82 0 : const SkRect& bounds() const { return fBounds; }
83 :
84 0 : bool hasColors() const { return SkToBool(this->colors()); }
85 0 : bool hasTexCoords() const { return SkToBool(this->texCoords()); }
86 0 : bool hasIndices() const { return SkToBool(this->indices()); }
87 :
88 0 : int vertexCount() const { return fVertexCnt; }
89 0 : const SkPoint* positions() const { return fPositions; }
90 0 : const SkPoint* texCoords() const { return fTexs; }
91 0 : const SkColor* colors() const { return fColors; }
92 :
93 0 : int indexCount() const { return fIndexCnt; }
94 0 : const uint16_t* indices() const { return fIndices; }
95 :
96 : // returns approximate byte size of the vertices object
97 : size_t approximateSize() const;
98 :
99 : /**
100 : * Recreate a vertices from a buffer previously created by calling encode().
101 : * Returns null if the data is corrupt or the length is incorrect for the contents.
102 : */
103 : static sk_sp<SkVertices> Decode(const void* buffer, size_t length);
104 :
105 : /**
106 : * Pack the vertices object into a byte buffer. This can be used to recreate the vertices
107 : * by calling Decode() with the buffer.
108 : */
109 : sk_sp<SkData> encode() const;
110 :
111 : private:
112 0 : SkVertices() {}
113 :
114 : // these are needed since we've manually sized our allocation (see Builder::init)
115 : friend class SkNVRefCnt<SkVertices>;
116 0 : void operator delete(void* p) { ::operator delete(p); }
117 :
118 : static sk_sp<SkVertices> Alloc(int vCount, int iCount, uint32_t builderFlags,
119 : size_t* arraySize);
120 :
121 : // we store this first, to pair with the refcnt in our base-class, so we don't have an
122 : // unnecessary pad between it and the (possibly 8-byte aligned) ptrs.
123 : uint32_t fUniqueID;
124 :
125 : // these point inside our allocation, so none of these can be "freed"
126 : SkPoint* fPositions;
127 : SkPoint* fTexs;
128 : SkColor* fColors;
129 : uint16_t* fIndices;
130 :
131 : SkRect fBounds; // computed to be the union of the fPositions[]
132 : int fVertexCnt;
133 : int fIndexCnt;
134 :
135 : VertexMode fMode;
136 : // below here is where the actual array data is stored.
137 : };
138 :
139 : #endif
|