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