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