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