aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/batches/GrDrawPathBatch.h
blob: 71ef9d42b482de9dc5f5002c986162011fb894ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrDrawPathBatch_DEFINED
#define GrDrawPathBatch_DEFINED

#include "GrBatchFlushState.h"
#include "GrDrawBatch.h"
#include "GrGpu.h"
#include "GrPath.h"
#include "GrPathRendering.h"
#include "GrPathProcessor.h"

#include "SkTLList.h"

class GrDrawPathBatchBase : public GrDrawBatch {
public:
    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
        out->setKnownFourComponents(fColor);
    }

    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
        out->setKnownSingleComponent(0xff);
    }

    void setStencilSettings(const GrStencilSettings& stencil) { fStencilSettings = stencil; }

protected:
    GrDrawPathBatchBase(const SkMatrix& viewMatrix, GrColor initialColor)
        : fViewMatrix(viewMatrix)
        , fColor(initialColor) {}

    const GrStencilSettings& stencilSettings() const { return fStencilSettings; }
    const GrPipelineOptimizations& opts() const { return fOpts; }
    const SkMatrix& viewMatrix() const { return fViewMatrix; }
    GrColor color() const { return fColor; }

private:
    void initBatchTracker(const GrPipelineOptimizations& opts) override {
        opts.getOverrideColorIfSet(&fColor);
        fOpts = opts;
    }

    SkMatrix                                                fViewMatrix;
    GrColor                                                 fColor;
    GrStencilSettings                                       fStencilSettings;
    GrPipelineOptimizations                                 fOpts;

    typedef GrDrawBatch INHERITED;
};

class GrDrawPathBatch final : public GrDrawPathBatchBase {
public:
    // This can't return a more abstract type because we install the stencil settings late :(
    static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, GrColor color,
                                       const GrPath* path) {
        return new GrDrawPathBatch(viewMatrix, color, path);
    }

    const char* name() const override { return "DrawPath"; }

    SkString dumpInfo() const override;

private:
    GrDrawPathBatch(const SkMatrix& viewMatrix, GrColor color, const GrPath* path)
        : INHERITED(viewMatrix, color)
        , fPath(path) {
        fBounds = path->getBounds();
        viewMatrix.mapRect(&fBounds);
        this->initClassID<GrDrawPathBatch>();
    }

    bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { return false; }

    void onPrepare(GrBatchFlushState*) override {}

    void onDraw(GrBatchFlushState* state) override;

    GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;

    typedef GrDrawPathBatchBase INHERITED;
};

/**
 * This could be nested inside the batch class, but for now it must be declarable in a public
 * header (GrDrawContext)
 */
class GrPathRangeDraw : public GrNonAtomicRef {
public:
    typedef GrPathRendering::PathTransformType TransformType;

    static GrPathRangeDraw* Create(GrPathRange* range, TransformType transformType,
        int reserveCnt) {
        return SkNEW_ARGS(GrPathRangeDraw, (range, transformType, reserveCnt));
    }

    void append(uint16_t index, float transform[]) {
        fTransforms.push_back_n(GrPathRendering::PathTransformSize(fTransformType), transform);
        fIndices.push_back(index);
    }

    int count() const { return fIndices.count(); }

    TransformType transformType() const { return fTransformType; }

    const float* transforms() const { return fTransforms.begin(); }

    const uint16_t* indices() const { return fIndices.begin(); }

    const GrPathRange* range() const { return fPathRange.get(); }

    static bool CanMerge(const GrPathRangeDraw& a, const GrPathRangeDraw& b) {
        return a.transformType() == b.transformType() && a.range() == b.range();
    }

private:
    GrPathRangeDraw(GrPathRange* range, TransformType transformType, int reserveCnt)
        : fPathRange(range)
        , fTransformType(transformType)
        , fIndices(reserveCnt)
        , fTransforms(reserveCnt * GrPathRendering::PathTransformSize(transformType)) {
        SkDEBUGCODE(fUsedInBatch = false;)
    }

    // Reserve space for 64 paths where indices are 16 bit and transforms are translations.
    static const int kIndexReserveCnt = 64;
    static const int kTransformBufferReserveCnt = 2 * 64;

    GrPendingIOResource<const GrPathRange, kRead_GrIOType> fPathRange;
    GrPathRendering::PathTransformType                     fTransformType;
    SkSTArray<kIndexReserveCnt, uint16_t, true>            fIndices;
    SkSTArray<kTransformBufferReserveCnt, float, true>     fTransforms;

    // To ensure we don't reuse these across batches.
#ifdef SK_DEBUG
    bool fUsedInBatch;
    friend class GrDrawPathRangeBatch;
#endif

    typedef GrNonAtomicRef INHERITED;
};

// Template this if we decide to support index types other than 16bit
class GrDrawPathRangeBatch final : public GrDrawPathBatchBase {
public:
    // This can't return a more abstracet type because we install the stencil settings late :(
    static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, const SkMatrix& localMatrix,
                                       GrColor color, GrPathRangeDraw* pathRangeDraw) {
        return SkNEW_ARGS(GrDrawPathRangeBatch, (viewMatrix, localMatrix, color, pathRangeDraw));
    }

    ~GrDrawPathRangeBatch() override;

    const char* name() const override { return "DrawPathRange"; }

    SkString dumpInfo() const override;

private:
    inline bool isWinding() const;

    GrDrawPathRangeBatch(const SkMatrix& viewMatrix, const SkMatrix& localMatrix, GrColor color,
                         GrPathRangeDraw* pathRangeDraw);

    bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override;

    void onPrepare(GrBatchFlushState*) override {}

    void onDraw(GrBatchFlushState* state) override;

    typedef SkTLList<GrPathRangeDraw*> DrawList;
    DrawList    fDraws;
    int         fTotalPathCount;
    SkMatrix    fLocalMatrix;

    typedef GrDrawPathBatchBase INHERITED;
};

#endif