1199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon/*
2199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon * Copyright 2017 Google Inc.
3199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon *
4199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon * Use of this source code is governed by a BSD-style license that can be
5199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon * found in the LICENSE file.
6199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon */
7199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
8199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#ifndef SkVertices_DEFINED
9199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#define SkVertices_DEFINED
10199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
11199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#include "SkColor.h"
12bdce9c2d73e3661f8061f73e35b74ba35d98e5ffMike Reed#include "SkData.h"
13199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#include "SkPoint.h"
14199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#include "SkRect.h"
15199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#include "SkRefCnt.h"
16199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
17199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon/**
18aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed * An immutable set of vertex data that can be used with SkCanvas::drawVertices.
19199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon */
202fbf1bc8c96f749a4c098bcfc827053445c2e12dDerek Sollenbergerclass SK_API SkVertices : public SkNVRefCnt<SkVertices> {
21199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomonpublic:
22887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed    enum VertexMode {
23887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed        kTriangles_VertexMode,
24887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed        kTriangleStrip_VertexMode,
25887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed        kTriangleFan_VertexMode,
26165fa634b7619f5a9e04eb5735ab0ec2c0776c42Mike Reed
27165fa634b7619f5a9e04eb5735ab0ec2c0776c42Mike Reed        kLast_VertexMode = kTriangleFan_VertexMode,
28887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed    };
29887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed
3097eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    /**
3197eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed     *  Create a vertices by copying the specified arrays. texs and colors may be nullptr,
3297eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed     *  and indices is ignored if indexCount == 0.
3397eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed     */
34887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed    static sk_sp<SkVertices> MakeCopy(VertexMode mode, int vertexCount,
3597eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                      const SkPoint positions[],
3697eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                      const SkPoint texs[],
3797eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                      const SkColor colors[],
3897eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                      int indexCount,
3997eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                      const uint16_t indices[]);
40199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
41887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed    static sk_sp<SkVertices> MakeCopy(VertexMode mode, int vertexCount,
4297eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                      const SkPoint positions[],
4397eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                      const SkPoint texs[],
4497eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                      const SkColor colors[]) {
4597eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed        return MakeCopy(mode, vertexCount, positions, texs, colors, 0, nullptr);
46199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon    }
47199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
48aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    struct Sizes;
49aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
50aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    enum BuilderFlags {
51aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        kHasTexCoords_BuilderFlag   = 1 << 0,
52aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        kHasColors_BuilderFlag      = 1 << 1,
5397eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    };
5497eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    class Builder {
5597eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    public:
56887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed        Builder(VertexMode mode, int vertexCount, int indexCount, uint32_t flags);
57887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed
58aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        bool isValid() const { return fVertices != nullptr; }
5997eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed
60aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        // if the builder is invalid, these will return 0
61aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        int vertexCount() const;
62aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        int indexCount() const;
63aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        SkPoint* positions();
64aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        SkPoint* texCoords();   // returns null if there are no texCoords
65aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        SkColor* colors();      // returns null if there are no colors
66aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        uint16_t* indices();    // returns null if there are no indices
6797eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed
68aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        // Detach the built vertices object. After the first call, this will always return null.
6997eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed        sk_sp<SkVertices> detach();
7097eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed
7197eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    private:
72887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed        Builder(VertexMode mode, int vertexCount, int indexCount, const Sizes&);
73aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
74887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed        void init(VertexMode mode, int vertexCount, int indexCount, const Sizes&);
75aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
76aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        // holds a partially complete object. only completed in detach()
77aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        sk_sp<SkVertices> fVertices;
78aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
79aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed        friend class SkVertices;
8097eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    };
81199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
82aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    uint32_t uniqueID() const { return fUniqueID; }
83887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed    VertexMode mode() const { return fMode; }
84aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    const SkRect& bounds() const { return fBounds; }
85aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
86aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    bool hasColors() const { return SkToBool(this->colors()); }
87aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    bool hasTexCoords() const { return SkToBool(this->texCoords()); }
88aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    bool hasIndices() const { return SkToBool(this->indices()); }
89199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
90199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon    int vertexCount() const { return fVertexCnt; }
9197eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    const SkPoint* positions() const { return fPositions; }
9297eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    const SkPoint* texCoords() const { return fTexs; }
9397eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    const SkColor* colors() const { return fColors; }
94199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
95199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon    int indexCount() const { return fIndexCnt; }
9697eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    const uint16_t* indices() const { return fIndices; }
97199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
98aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    // returns approximate byte size of the vertices object
99aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    size_t approximateSize() const;
100199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
101aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    /**
102aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed     *  Recreate a vertices from a buffer previously created by calling encode().
103aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed     *  Returns null if the data is corrupt or the length is incorrect for the contents.
104aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed     */
105aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    static sk_sp<SkVertices> Decode(const void* buffer, size_t length);
106199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
107aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    /**
108aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed     *  Pack the vertices object into a byte buffer. This can be used to recreate the vertices
109aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed     *  by calling Decode() with the buffer.
110aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed     */
111bdce9c2d73e3661f8061f73e35b74ba35d98e5ffMike Reed    sk_sp<SkData> encode() const;
112bdce9c2d73e3661f8061f73e35b74ba35d98e5ffMike Reed
113199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomonprivate:
11497eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed    SkVertices() {}
115199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
116aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    // these are needed since we've manually sized our allocation (see Builder::init)
117aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    friend class SkNVRefCnt<SkVertices>;
118aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    void operator delete(void* p) { ::operator delete(p); }
119aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
120aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    static sk_sp<SkVertices> Alloc(int vCount, int iCount, uint32_t builderFlags,
121aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed                                   size_t* arraySize);
122aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
123aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    // we store this first, to pair with the refcnt in our base-class, so we don't have an
124aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    // unnecessary pad between it and the (possibly 8-byte aligned) ptrs.
1259a8065d34dd090837c2a05bc60533fcc6268e6bbMike Reed    uint32_t fUniqueID;
126aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
127aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    // these point inside our allocation, so none of these can be "freed"
128aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    SkPoint*    fPositions;
129aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    SkPoint*    fTexs;
130aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    SkColor*    fColors;
131aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    uint16_t*   fIndices;
132aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
133aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    SkRect  fBounds;    // computed to be the union of the fPositions[]
134aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    int     fVertexCnt;
135aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    int     fIndexCnt;
136aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed
137887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed    VertexMode fMode;
138aa9e3326f71c74e6250ae783cc3257d835624dd0Mike Reed    // below here is where the actual array data is stored.
139199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon};
140199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon
141199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#endif
142