• 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/SkBlurTypes.h"
12 #include "include/core/SkDrawable.h"
13 #include "src/gpu/GrDeferredUpload.h"
14 #include "src/gpu/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     void drawBlurImage(const GrSurfaceProxyView& proxyView, SkBlurArg& blurArg);
143 
144 protected:
GrOpsRenderPass()145     GrOpsRenderPass() : fOrigin(kTopLeft_GrSurfaceOrigin), fRenderTarget(nullptr) {}
146 
GrOpsRenderPass(GrRenderTarget * rt,GrSurfaceOrigin origin)147     GrOpsRenderPass(GrRenderTarget* rt, GrSurfaceOrigin origin)
148             : fOrigin(origin)
149             , fRenderTarget(rt) {
150     }
151 
set(GrRenderTarget * rt,GrSurfaceOrigin origin)152     void set(GrRenderTarget* rt, GrSurfaceOrigin origin) {
153         SkASSERT(!fRenderTarget);
154 
155         fRenderTarget = rt;
156         fOrigin = origin;
157     }
158 
159     GrSurfaceOrigin fOrigin;
160     GrRenderTarget* fRenderTarget;
161 
162     // Backends may defer binding of certain buffers if their draw API requires a buffer, or if
163     // their bind methods don't support base values.
164     sk_sp<const GrBuffer> fActiveIndexBuffer;
165     sk_sp<const GrBuffer> fActiveVertexBuffer;
166     sk_sp<const GrBuffer> fActiveInstanceBuffer;
167 
168 private:
169     virtual GrGpu* gpu() = 0;
170 
resetActiveBuffers()171     void resetActiveBuffers() {
172         fActiveIndexBuffer.reset();
173         fActiveInstanceBuffer.reset();
174         fActiveVertexBuffer.reset();
175     }
176 
177     bool prepareToDraw();
178 
179     // overridden by backend-specific derived class to perform the rendering command.
onBegin()180     virtual void onBegin() {}
onEnd()181     virtual void onEnd() {}
182     virtual bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) = 0;
183     virtual void onSetScissorRect(const SkIRect&) = 0;
184     virtual bool onBindTextures(const GrGeometryProcessor&,
185                                 const GrSurfaceProxy* const geomProcTextures[],
186                                 const GrPipeline&) = 0;
187     virtual void onBindBuffers(sk_sp<const GrBuffer> indexBuffer, sk_sp<const GrBuffer> instanceBuffer,
188                                sk_sp<const GrBuffer> vertexBuffer, GrPrimitiveRestart) = 0;
189     virtual void onDraw(int vertexCount, int baseVertex) = 0;
190     virtual void onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
191                                uint16_t maxIndexValue, int baseVertex) = 0;
192     virtual void onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
193                                  int baseVertex) = 0;
194     virtual void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount,
195                                         int baseInstance, int baseVertex) = 0;
onDrawIndirect(const GrBuffer *,size_t offset,int drawCount)196     virtual void onDrawIndirect(const GrBuffer*, size_t offset, int drawCount) {
197         SK_ABORT("Not implemented.");  // Only called if caps.nativeDrawIndirectSupport().
198     }
onDrawIndexedIndirect(const GrBuffer *,size_t offset,int drawCount)199     virtual void onDrawIndexedIndirect(const GrBuffer*, size_t offset, int drawCount) {
200         SK_ABORT("Not implemented.");  // Only called if caps.nativeDrawIndirectSupport().
201     }
202     virtual void onClear(const GrScissorState&, std::array<float, 4> color) = 0;
203     virtual void onClearStencilClip(const GrScissorState&, bool insideStencilMask) = 0;
onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>)204     virtual void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) {}
onDrawBlurImage(const GrSurfaceProxyView & proxyView,const SkBlurArg & blurArg)205     virtual void onDrawBlurImage(const GrSurfaceProxyView& proxyView, const SkBlurArg& blurArg) {};
206 
207     enum class DrawPipelineStatus {
208         kOk = 0,
209         kNotConfigured,
210         kFailedToBind
211     };
212 
213     DrawPipelineStatus fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
214     GrXferBarrierType fXferBarrierType;
215 
216 #ifdef SK_DEBUG
217     enum class DynamicStateStatus {
218         kDisabled,
219         kUninitialized,
220         kConfigured
221     };
222 
223     DynamicStateStatus fScissorStatus;
224     DynamicStateStatus fTextureBindingStatus;
225     bool fHasIndexBuffer;
226     DynamicStateStatus fInstanceBufferStatus;
227     DynamicStateStatus fVertexBufferStatus;
228 #endif
229 
230     using INHERITED = GrOpsRenderPass;
231 };
232 
233 #endif
234