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 "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 
     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 
     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 
     75     uint32_t uniqueID() const { return fUniqueID; }
     76     SkCanvas::VertexMode mode() const { return fMode; }
     77     const SkRect& bounds() const { return fBounds; }
     78 
     79     bool hasColors() const { return SkToBool(this->colors()); }
     80     bool hasTexCoords() const { return SkToBool(this->texCoords()); }
     81     bool hasIndices() const { return SkToBool(this->indices()); }
     82 
     83     int vertexCount() const { return fVertexCnt; }
     84     const SkPoint* positions() const { return fPositions; }
     85     const SkPoint* texCoords() const { return fTexs; }
     86     const SkColor* colors() const { return fColors; }
     87 
     88     int indexCount() const { return fIndexCnt; }
     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:
    107     SkVertices() {}
    108 
    109     // these are needed since we've manually sized our allocation (see Builder::init)
    110     friend class SkNVRefCnt<SkVertices>;
    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