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