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 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 MakeCopy(VertexMode mode,int vertexCount,const SkPoint positions[],const SkPoint texs[],const SkColor colors[])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 class Builder { 53 public: 54 Builder(VertexMode mode, int vertexCount, int indexCount, uint32_t flags); 55 isValid()56 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 uniqueID()80 uint32_t uniqueID() const { return fUniqueID; } mode()81 VertexMode mode() const { return fMode; } bounds()82 const SkRect& bounds() const { return fBounds; } 83 hasColors()84 bool hasColors() const { return SkToBool(this->colors()); } hasTexCoords()85 bool hasTexCoords() const { return SkToBool(this->texCoords()); } hasIndices()86 bool hasIndices() const { return SkToBool(this->indices()); } 87 vertexCount()88 int vertexCount() const { return fVertexCnt; } positions()89 const SkPoint* positions() const { return fPositions; } texCoords()90 const SkPoint* texCoords() const { return fTexs; } colors()91 const SkColor* colors() const { return fColors; } 92 indexCount()93 int indexCount() const { return fIndexCnt; } indices()94 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: SkVertices()112 SkVertices() {} 113 114 // these are needed since we've manually sized our allocation (see Builder::init) 115 friend class SkNVRefCnt<SkVertices>; delete(void * p)116 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 140