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