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