• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright 2016 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 GrOpsRenderPass_DEFINED
9 #define GrOpsRenderPass_DEFINED
10 
11 #include "include/core/SkDrawable.h"
12 #include "src/gpu/GrPipeline.h"
13 #include "src/gpu/ops/GrDrawOp.h"
14 
15 class GrOpFlushState;
16 class GrGpu;
17 class GrPipeline;
18 class GrGeometryProcessor;
19 class GrProgramInfo;
20 class GrRenderTarget;
21 class GrScissorState;
22 class GrSemaphore;
23 struct SkIRect;
24 struct SkRect;
25 
26 /**
27  * The GrOpsRenderPass is a series of commands (draws, clears, and discards), which all target the
28  * same render target. It is possible that these commands execute immediately (GL), or get buffered
29  * up for later execution (Vulkan). GrOps execute into a GrOpsRenderPass.
30  */
31 class GrOpsRenderPass {
32 public:
~GrOpsRenderPass()33     virtual ~GrOpsRenderPass() {}
34 
35     struct LoadAndStoreInfo {
36         GrLoadOp             fLoadOp;
37         GrStoreOp            fStoreOp;
38         std::array<float, 4> fClearColor;
39     };
40 
41     // Load-time clears of the stencil buffer are always to 0 so we don't store
42     // an 'fStencilClearValue'
43     struct StencilLoadAndStoreInfo {
44         GrLoadOp  fLoadOp;
45         GrStoreOp fStoreOp;
46     };
47 
48     void begin();
49     // Signals the end of recording to the GrOpsRenderPass and that it can now be submitted.
50     void end();
51 
52     // Updates the internal pipeline state for drawing with the provided GrProgramInfo. Enters an
53     // internal "bad" state if the pipeline could not be set.
54     void bindPipeline(const GrProgramInfo&, const SkRect& drawBounds);
55 
56     // The scissor rect is always dynamic state and therefore not stored on GrPipeline. If scissor
57     // test is enabled on the current pipeline, then the client must call setScissorRect() before
58     // drawing. The scissor rect may also be updated between draws without having to bind a new
59     // pipeline.
60     void setScissorRect(const SkIRect&);
61 
62     // Binds textures for the primitive processor and any FP on the GrPipeline. Texture bindings are
63     // dynamic state and therefore not set during bindPipeline(). If the current program uses
64     // textures, then the client must call bindTextures() before drawing. The primitive processor
65     // textures may also be updated between draws by calling bindTextures() again with a different
66     // array for primProcTextures. (On subsequent calls, if the backend is capable of updating the
67     // primitive processor textures independently, then it will automatically skip re-binding
68     // FP textures from GrPipeline.)
69     //
70     // If the current program does not use textures, this is a no-op.
71     void bindTextures(const GrGeometryProcessor&,
72                       const GrSurfaceProxy* const geomProcTextures[],
73                       const GrPipeline&);
74 
75     void bindBuffers(sk_sp<const GrBuffer> indexBuffer, sk_sp<const GrBuffer> instanceBuffer,
76                      sk_sp<const GrBuffer> vertexBuffer, GrPrimitiveRestart = GrPrimitiveRestart::kNo);
77 
78     // The next several draw*() methods issue draws using the current pipeline state. Before
79     // drawing, the caller must configure the pipeline and dynamic state:
80     //
81     //   - Call bindPipeline()
82     //   - If the scissor test is enabled, call setScissorRect()
83     //   - If the current program uses textures, call bindTextures()
84     //   - Call bindBuffers() (even if all buffers are null)
85     void draw(int vertexCount, int baseVertex);
86     void drawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue,
87                      int baseVertex);
88 
89     // Requires caps.drawInstancedSupport().
90     void drawInstanced(int instanceCount, int baseInstance, int vertexCount, int baseVertex);
91 
92     // Requires caps.drawInstancedSupport().
93     void drawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance,
94                               int baseVertex);
95 
96     // Executes multiple draws from an array of GrDrawIndirectCommand in the provided buffer.
97     //
98     // Requires caps.drawInstancedSupport().
99     //
100     // If caps.nativeDrawIndirectSupport() is unavailable, then 'drawIndirectBuffer' must be a
101     // GrCpuBuffer in order to polyfill. Performance may suffer in this scenario.
102     void drawIndirect(const GrBuffer* drawIndirectBuffer, size_t bufferOffset, int drawCount);
103 
104     // Executes multiple draws from an array of GrDrawIndexedIndirectCommand in the provided buffer.
105     //
106     // Requires caps.drawInstancedSupport().
107     //
108     // If caps.nativeDrawIndirectSupport() is unavailable, then 'drawIndirectBuffer' must be a
109     // GrCpuBuffer in order to polyfill. Performance may suffer in this scenario.
110     void drawIndexedIndirect(const GrBuffer* drawIndirectBuffer, size_t bufferOffset,
111                              int drawCount);
112 
113     // This is a helper method for drawing a repeating pattern of vertices. The bound index buffer
114     // is understood to contain 'maxPatternRepetitionsInIndexBuffer' repetitions of the pattern.
115     // If more repetitions are required, then we loop.
116     void drawIndexPattern(int patternIndexCount, int patternRepeatCount,
117                           int maxPatternRepetitionsInIndexBuffer, int patternVertexCount,
118                           int baseVertex);
119 
120     // Performs an upload of vertex data in the middle of a set of a set of draws
121     virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0;
122 
123     /**
124      * Clear the owned render target. Clears the full target if 'scissor' is disabled, otherwise it
125      * is restricted to 'scissor'. Must check caps.performPartialClearsAsDraws() before using an
126      * enabled scissor test; must check caps.performColorClearsAsDraws() before using this at all.
127      */
128     void clear(const GrScissorState& scissor, std::array<float, 4> color);
129 
130     /**
131      * Same as clear() but modifies the stencil; check caps.performStencilClearsAsDraws() and
132      * caps.performPartialClearsAsDraws().
133      */
134     void clearStencilClip(const GrScissorState& scissor, bool insideStencilMask);
135 
136     /**
137      * Executes the SkDrawable object for the underlying backend.
138      */
139     void executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>);
140 
141 protected:
GrOpsRenderPass()142     GrOpsRenderPass() : fOrigin(kTopLeft_GrSurfaceOrigin), fRenderTarget(nullptr) {}
143 
GrOpsRenderPass(GrRenderTarget * rt,GrSurfaceOrigin origin)144     GrOpsRenderPass(GrRenderTarget* rt, GrSurfaceOrigin origin)
145             : fOrigin(origin)
146             , fRenderTarget(rt) {
147     }
148 
set(GrRenderTarget * rt,GrSurfaceOrigin origin)149     void set(GrRenderTarget* rt, GrSurfaceOrigin origin) {
150         SkASSERT(!fRenderTarget);
151 
152         fRenderTarget = rt;
153         fOrigin = origin;
154     }
155 
156     GrSurfaceOrigin fOrigin;
157     GrRenderTarget* fRenderTarget;
158 
159     // Backends may defer binding of certain buffers if their draw API requires a buffer, or if
160     // their bind methods don't support base values.
161     sk_sp<const GrBuffer> fActiveIndexBuffer;
162     sk_sp<const GrBuffer> fActiveVertexBuffer;
163     sk_sp<const GrBuffer> fActiveInstanceBuffer;
164 
165 private:
166     virtual GrGpu* gpu() = 0;
167 
resetActiveBuffers()168     void resetActiveBuffers() {
169         fActiveIndexBuffer.reset();
170         fActiveInstanceBuffer.reset();
171         fActiveVertexBuffer.reset();
172     }
173 
174     bool prepareToDraw();
175 
176     // overridden by backend-specific derived class to perform the rendering command.
onBegin()177     virtual void onBegin() {}
onEnd()178     virtual void onEnd() {}
179     virtual bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) = 0;
180     virtual void onSetScissorRect(const SkIRect&) = 0;
181     virtual bool onBindTextures(const GrGeometryProcessor&,
182                                 const GrSurfaceProxy* const geomProcTextures[],
183                                 const GrPipeline&) = 0;
184     virtual void onBindBuffers(sk_sp<const GrBuffer> indexBuffer, sk_sp<const GrBuffer> instanceBuffer,
185                                sk_sp<const GrBuffer> vertexBuffer, GrPrimitiveRestart) = 0;
186     virtual void onDraw(int vertexCount, int baseVertex) = 0;
187     virtual void onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
188                                uint16_t maxIndexValue, int baseVertex) = 0;
189     virtual void onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
190                                  int baseVertex) = 0;
191     virtual void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount,
192                                         int baseInstance, int baseVertex) = 0;
onDrawIndirect(const GrBuffer *,size_t offset,int drawCount)193     virtual void onDrawIndirect(const GrBuffer*, size_t offset, int drawCount) {
194         SK_ABORT("Not implemented.");  // Only called if caps.nativeDrawIndirectSupport().
195     }
onDrawIndexedIndirect(const GrBuffer *,size_t offset,int drawCount)196     virtual void onDrawIndexedIndirect(const GrBuffer*, size_t offset, int drawCount) {
197         SK_ABORT("Not implemented.");  // Only called if caps.nativeDrawIndirectSupport().
198     }
199     virtual void onClear(const GrScissorState&, std::array<float, 4> color) = 0;
200     virtual void onClearStencilClip(const GrScissorState&, bool insideStencilMask) = 0;
onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>)201     virtual void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) {}
202 
203     enum class DrawPipelineStatus {
204         kOk = 0,
205         kNotConfigured,
206         kFailedToBind
207     };
208 
209     DrawPipelineStatus fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
210     GrXferBarrierType fXferBarrierType;
211 
212 #ifdef SK_DEBUG
213     enum class DynamicStateStatus {
214         kDisabled,
215         kUninitialized,
216         kConfigured
217     };
218 
219     DynamicStateStatus fScissorStatus;
220     DynamicStateStatus fTextureBindingStatus;
221     bool fHasIndexBuffer;
222     DynamicStateStatus fInstanceBufferStatus;
223     DynamicStateStatus fVertexBufferStatus;
224 #endif
225 
226     using INHERITED = GrOpsRenderPass;
227 };
228 
229 #endif
230