Home | History | Annotate | Download | only in core
      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 
     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 
     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 
     80     uint32_t uniqueID() const { return fUniqueID; }
     81     VertexMode mode() const { return fMode; }
     82     const SkRect& bounds() const { return fBounds; }
     83 
     84     bool hasColors() const { return SkToBool(this->colors()); }
     85     bool hasTexCoords() const { return SkToBool(this->texCoords()); }
     86     bool hasIndices() const { return SkToBool(this->indices()); }
     87 
     88     int vertexCount() const { return fVertexCnt; }
     89     const SkPoint* positions() const { return fPositions; }
     90     const SkPoint* texCoords() const { return fTexs; }
     91     const SkColor* colors() const { return fColors; }
     92 
     93     int indexCount() const { return fIndexCnt; }
     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:
    112     SkVertices() {}
    113 
    114     // these are needed since we've manually sized our allocation (see Builder::init)
    115     friend class SkNVRefCnt<SkVertices>;
    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