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