aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrRenderTargetOpList.h
blob: 216a3303cd49a0d3e63bfc7719eae895770e47f1 (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
183
184
185
186
/*
 * Copyright 2010 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrRenderTargetOpList_DEFINED
#define GrRenderTargetOpList_DEFINED

#include "GrClip.h"
#include "GrContext.h"
#include "GrOpList.h"
#include "GrPathProcessor.h"
#include "GrPrimitiveProcessor.h"
#include "GrPathRendering.h"
#include "GrXferProcessor.h"

#include "ops/GrDrawOp.h"

#include "SkClipStack.h"
#include "SkMatrix.h"
#include "SkPath.h"
#include "SkStringUtils.h"
#include "SkStrokeRec.h"
#include "SkTArray.h"
#include "SkTLazy.h"
#include "SkTypes.h"

class GrAuditTrail;
class GrClearOp;
class GrClip;
class GrCaps;
class GrPath;
class GrDrawPathOpBase;
class GrOp;
class GrPipelineBuilder;
class GrRenderTargetProxy;

class GrRenderTargetOpList final : public GrOpList {
public:
    /** Options for GrRenderTargetOpList behavior. */
    struct Options {
        bool fClipDrawOpsToBounds = false;
        int fMaxOpCombineLookback = -1;
        int fMaxOpCombineLookahead = -1;
    };

    GrRenderTargetOpList(GrRenderTargetProxy*, GrGpu*, GrResourceProvider*,
                         GrAuditTrail*, const Options&);

    ~GrRenderTargetOpList() override;

    void makeClosed() override {
        INHERITED::makeClosed();

        fLastFullClearOp = nullptr;
        this->forwardCombine();
    }

    /**
     * Empties the draw buffer of any queued up draws.
     */
    void reset() override;

    void abandonGpuResources() override;
    void freeGpuResources() override;

    /**
     * Together these two functions flush all queued up draws to GrCommandBuffer. The return value
     * of executeOps() indicates whether any commands were actually issued to the GPU.
     */
    void prepareOps(GrOpFlushState* flushState) override;
    bool executeOps(GrOpFlushState* flushState) override;

    /**
     * Gets the capabilities of the draw target.
     */
    const GrCaps* caps() const { return fGpu->caps(); }

    void addDrawOp(const GrPipelineBuilder&, GrRenderTargetContext*, const GrClip&,
                   std::unique_ptr<GrDrawOp>);

    void addOp(std::unique_ptr<GrOp> op, GrRenderTargetContext* renderTargetContext) {
        this->recordOp(std::move(op), renderTargetContext);
    }

    /**
     * Draws the path into user stencil bits. Upon return, all user stencil values
     * inside the path will be nonzero. The path's fill must be either even/odd or
     * winding (notnverse or hairline).It will respect the HW antialias boolean (if
     * possible in the 3D API).  Note, we will never have an inverse fill with
     * stencil path.
     */
    void stencilPath(GrRenderTargetContext*,
                     const GrClip&,
                     GrAAType aa,
                     const SkMatrix& viewMatrix,
                     const GrPath*);

    /** Clears the entire render target */
    void fullClear(GrRenderTargetContext*, GrColor color);

    /** Discards the contents render target. */
    void discard(GrRenderTargetContext*);

    /**
     * Copies a pixel rectangle from one surface to another. This call may finalize
     * reserved vertex/index data (as though a draw call was made). The src pixels
     * copied are specified by srcRect. They are copied to a rect of the same
     * size in dst with top left at dstPoint. If the src rect is clipped by the
     * src bounds then  pixel values in the dst rect corresponding to area clipped
     * by the src rect are not overwritten. This method is not guaranteed to succeed
     * depending on the type of surface, configs, etc, and the backend-specific
     * limitations.
     */
    bool copySurface(GrSurface* dst,
                     GrSurface* src,
                     const SkIRect& srcRect,
                     const SkIPoint& dstPoint);

    gr_instanced::InstancedRendering* instancedRendering() const {
        SkASSERT(fInstancedRendering);
        return fInstancedRendering.get();
    }

    GrRenderTargetOpList* asRenderTargetOpList() override { return this; }

    SkDEBUGCODE(void dump() const override;)

private:
    friend class GrRenderTargetContextPriv; // for clearStencilClip and stencil clip state.

    // If the input op is combined with an earlier op, this returns the combined op. Otherwise, it
    // returns the input op.
    GrOp* recordOp(std::unique_ptr<GrOp> op, GrRenderTargetContext* renderTargetContext) {
        SkRect bounds = op->bounds();
        return this->recordOp(std::move(op), renderTargetContext, bounds);
    }

    // Variant that allows an explicit bounds (computed from the Op's bounds and a clip).
    GrOp* recordOp(std::unique_ptr<GrOp>, GrRenderTargetContext*, const SkRect& clippedBounds);

    void forwardCombine();

    // Makes a copy of the dst if it is necessary for the draw and returns the texture that should
    // be used by GrXferProcessor to access the destination color. If the texture is nullptr then
    // a texture copy could not be made.
    void setupDstTexture(GrRenderTarget*,
                         const GrClip&,
                         const SkRect& opBounds,
                         GrXferProcessor::DstTexture*);

    // Used only via GrRenderTargetContextPriv.
    void clearStencilClip(const GrFixedClip&, bool insideStencilMask, GrRenderTargetContext*);

    struct RecordedOp {
        std::unique_ptr<GrOp> fOp;
        SkRect fClippedBounds;
        // TODO: Use proxy ID instead of instantiated render target ID.
        GrGpuResource::UniqueID fRenderTargetID;
    };
    SkSTArray<256, RecordedOp, true> fRecordedOps;

    GrClearOp* fLastFullClearOp = nullptr;
    GrGpuResource::UniqueID fLastFullClearRenderTargetID = GrGpuResource::UniqueID::InvalidID();

    // The context is only in service of the GrClip, remove once it doesn't need this.
    GrContext* fContext;
    GrGpu* fGpu;
    GrResourceProvider* fResourceProvider;

    bool fClipOpToBounds;
    int fMaxOpLookback;
    int fMaxOpLookahead;

    std::unique_ptr<gr_instanced::InstancedRendering> fInstancedRendering;

    int32_t fLastClipStackGenID;
    SkIRect fLastClipStackRect;
    SkIPoint fLastClipOrigin;

    typedef GrOpList INHERITED;
};

#endif