diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 898256d7b0..263a33099c 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -1837,7 +1837,8 @@ void GrGLGpu::disableWindowRectangles() { #endif } -bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, const GrProgramInfo& programInfo) { +bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, bool useMultisampleFBO, + const GrProgramInfo& programInfo) { this->handleDirtyContext(); sk_sp program = fProgramCache->findOrCreateProgram(this->getContext(), @@ -1877,7 +1878,7 @@ bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, const GrProgramInfo& pr // This must come after textures are flushed because a texture may need // to be msaa-resolved (which will modify bound FBO state). - this->flushRenderTarget(glRT, glRT->numSamples() > 1); + this->flushRenderTarget(glRT, useMultisampleFBO); return true; } @@ -1939,6 +1940,7 @@ GrGLenum GrGLGpu::bindBuffer(GrGpuBufferType type, const GrBuffer* buffer) { void GrGLGpu::clear(const GrScissorState& scissor, std::array color, GrRenderTarget* target, + bool useMultisampleFBO, GrSurfaceOrigin origin) { // parent class should never let us get here with no RT SkASSERT(target); @@ -1950,9 +1952,9 @@ void GrGLGpu::clear(const GrScissorState& scissor, GrGLRenderTarget* glRT = static_cast(target); if (scissor.enabled()) { - this->flushRenderTarget(glRT, glRT->numSamples() > 1, origin, scissor.rect()); + this->flushRenderTarget(glRT, useMultisampleFBO, origin, scissor.rect()); } else { - this->flushRenderTarget(glRT, glRT->numSamples() > 1); + this->flushRenderTarget(glRT, useMultisampleFBO); } this->flushScissor(scissor, glRT->height(), origin); this->disableWindowRectangles(); @@ -1969,7 +1971,8 @@ static bool use_tiled_rendering(const GrGLCaps& glCaps, GrStoreOp::kDiscard == stencilLoadStore.fStoreOp; } -void GrGLGpu::beginCommandBuffer(GrRenderTarget* rt, const SkIRect& bounds, GrSurfaceOrigin origin, +void GrGLGpu::beginCommandBuffer(GrRenderTarget* rt, bool useMultisampleFBO, const SkIRect& bounds, + GrSurfaceOrigin origin, const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore) { SkASSERT(!fIsExecutingCommandBuffer_DebugOnly); @@ -1977,7 +1980,7 @@ void GrGLGpu::beginCommandBuffer(GrRenderTarget* rt, const SkIRect& bounds, GrSu this->handleDirtyContext(); auto glRT = static_cast(rt); - this->flushRenderTarget(glRT, glRT->numSamples() > 1); + this->flushRenderTarget(glRT, useMultisampleFBO); SkDEBUGCODE(fIsExecutingCommandBuffer_DebugOnly = true); if (use_tiled_rendering(this->glCaps(), stencilLoadStore)) { @@ -2009,7 +2012,7 @@ void GrGLGpu::beginCommandBuffer(GrRenderTarget* rt, const SkIRect& bounds, GrSu } } -void GrGLGpu::endCommandBuffer(GrRenderTarget* rt, +void GrGLGpu::endCommandBuffer(GrRenderTarget* rt, bool useMultisampleFBO, const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore) { SkASSERT(fIsExecutingCommandBuffer_DebugOnly); @@ -2027,13 +2030,13 @@ void GrGLGpu::endCommandBuffer(GrRenderTarget* rt, SkSTArray<2, GrGLenum> discardAttachments; if (GrStoreOp::kDiscard == colorLoadStore.fStoreOp) { - GrGLuint renderFBOID = (glRT->numSamples() > 1) ? glRT->multisampleFBOID() - : glRT->singleSampleFBOID(); + GrGLuint renderFBOID = (useMultisampleFBO) ? glRT->multisampleFBOID() + : glRT->singleSampleFBOID(); discardAttachments.push_back((!renderFBOID) ? GR_GL_COLOR : GR_GL_COLOR_ATTACHMENT0); } if (GrStoreOp::kDiscard == stencilLoadStore.fStoreOp) { - GrGLuint renderFBOID = (glRT->numSamples() > 1) ? glRT->multisampleFBOID() - : glRT->singleSampleFBOID(); + GrGLuint renderFBOID = (useMultisampleFBO) ? glRT->multisampleFBOID() + : glRT->singleSampleFBOID(); discardAttachments.push_back((!renderFBOID) ? GR_GL_STENCIL : GR_GL_STENCIL_ATTACHMENT); } @@ -2094,7 +2097,7 @@ void GrGLGpu::clearStencilClip(const GrScissorState& scissor, bool insideStencil value = 0; } GrGLRenderTarget* glRT = static_cast(target); - this->flushRenderTargetNoColorWrites(glRT, glRT->numSamples() > 1); + this->flushRenderTargetNoColorWrites(glRT, glRT->stencilIsOnMultisampleFBO()); this->flushScissor(scissor, glRT->height(), origin); this->disableWindowRectangles(); diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 0b7a3fc48b..534d4c5206 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -71,7 +71,7 @@ public: GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer*); // Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set. - bool flushGLState(GrRenderTarget*, const GrProgramInfo&); + bool flushGLState(GrRenderTarget*, bool useMultisampleFBO, const GrProgramInfo&); void flushScissorRect(const SkIRect& scissor, int rtHeight, GrSurfaceOrigin); // The flushRenderTarget methods will all set the initial viewport to the full extent of the @@ -106,7 +106,8 @@ public: // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu. // Thus this is the implementation of the clear call for the corresponding passthrough function // on GrGLOpsRenderPass. - void clear(const GrScissorState&, std::array color, GrRenderTarget*, GrSurfaceOrigin); + void clear(const GrScissorState&, std::array color, GrRenderTarget*, + bool useMultisampleFBO, GrSurfaceOrigin); // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu. // Thus this is the implementation of the clearStencil call for the corresponding passthrough @@ -114,11 +115,13 @@ public: void clearStencilClip(const GrScissorState&, bool insideStencilMask, GrRenderTarget*, GrSurfaceOrigin); - void beginCommandBuffer(GrRenderTarget*, const SkIRect& bounds, GrSurfaceOrigin, + void beginCommandBuffer(GrRenderTarget*, bool useMultisampleFBO, + const SkIRect& bounds, GrSurfaceOrigin, const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore); - void endCommandBuffer(GrRenderTarget*, const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, + void endCommandBuffer(GrRenderTarget*, bool useMultisampleFBO, + const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore); void invalidateBoundRenderTarget() { diff --git a/src/gpu/gl/GrGLOpsRenderPass.cpp b/src/gpu/gl/GrGLOpsRenderPass.cpp index 57384b8445..4e58159e9c 100644 --- a/src/gpu/gl/GrGLOpsRenderPass.cpp +++ b/src/gpu/gl/GrGLOpsRenderPass.cpp @@ -25,24 +25,26 @@ void GrGLOpsRenderPass::set(GrRenderTarget* rt, const SkIRect& contentBounds, SkASSERT(fGpu == rt->getContext()->priv().getGpu()); this->INHERITED::set(rt, origin); + fUseMultisampleFBO = rt->numSamples() > 1; fContentBounds = contentBounds; fColorLoadAndStoreInfo = colorInfo; fStencilLoadAndStoreInfo = stencilInfo; } void GrGLOpsRenderPass::onBegin() { - fGpu->beginCommandBuffer(fRenderTarget, fContentBounds, fOrigin, fColorLoadAndStoreInfo, - fStencilLoadAndStoreInfo); + fGpu->beginCommandBuffer(fRenderTarget, fUseMultisampleFBO, fContentBounds, fOrigin, + fColorLoadAndStoreInfo, fStencilLoadAndStoreInfo); } void GrGLOpsRenderPass::onEnd() { - fGpu->endCommandBuffer(fRenderTarget, fColorLoadAndStoreInfo, fStencilLoadAndStoreInfo); + fGpu->endCommandBuffer(fRenderTarget, fUseMultisampleFBO, fColorLoadAndStoreInfo, + fStencilLoadAndStoreInfo); } bool GrGLOpsRenderPass::onBindPipeline(const GrProgramInfo& programInfo, const SkRect& drawBounds) { fPrimitiveType = programInfo.primitiveType(); - return fGpu->flushGLState(fRenderTarget, programInfo); + return fGpu->flushGLState(fRenderTarget, fUseMultisampleFBO, programInfo); } void GrGLOpsRenderPass::onSetScissorRect(const SkIRect& scissor) { @@ -384,7 +386,7 @@ void GrGLOpsRenderPass::multiDrawElementsANGLEOrWebGL(const GrBuffer* drawIndire } void GrGLOpsRenderPass::onClear(const GrScissorState& scissor, std::array color) { - fGpu->clear(scissor, color, fRenderTarget, fOrigin); + fGpu->clear(scissor, color, fRenderTarget, fUseMultisampleFBO, fOrigin); } void GrGLOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) { diff --git a/src/gpu/gl/GrGLOpsRenderPass.h b/src/gpu/gl/GrGLOpsRenderPass.h index 1e62b875f8..586bfed92d 100644 --- a/src/gpu/gl/GrGLOpsRenderPass.h +++ b/src/gpu/gl/GrGLOpsRenderPass.h @@ -77,7 +77,9 @@ private: void onClear(const GrScissorState& scissor, std::array color) override; void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override; - GrGLGpu* fGpu; + GrGLGpu* const fGpu; + + bool fUseMultisampleFBO; SkIRect fContentBounds; LoadAndStoreInfo fColorLoadAndStoreInfo; StencilLoadAndStoreInfo fStencilLoadAndStoreInfo; diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index 1842d2cac2..fd3bc1e12f 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp @@ -45,8 +45,7 @@ GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, } inline void GrGLRenderTarget::setFlags(const GrGLCaps& glCaps, const IDs& idDesc) { - GrGLuint renderFBOID = (this->numSamples() > 1) ? fMultisampleFBOID : fSingleSampleFBOID; - if (renderFBOID == 0) { + if ((fMultisampleFBOID | fSingleSampleFBOID) == 0) { this->setGLRTFBOIDIs0(); } } @@ -129,7 +128,8 @@ bool GrGLRenderTarget::completeStencilAttachment() { const GrGLInterface* interface = gpu->glInterface(); GrAttachment* stencil = this->getStencilAttachment(); - GrGLuint stencilFBOID = (this->numSamples() > 1) ? fMultisampleFBOID : fSingleSampleFBOID; + GrGLuint stencilFBOID = (this->stencilIsOnMultisampleFBO()) ? fMultisampleFBOID + : fSingleSampleFBOID; gpu->invalidateBoundRenderTarget(); gpu->bindFramebuffer(GR_GL_FRAMEBUFFER, stencilFBOID); diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h index 93f859d801..7ad6cacdb9 100644 --- a/src/gpu/gl/GrGLRenderTarget.h +++ b/src/gpu/gl/GrGLRenderTarget.h @@ -44,6 +44,12 @@ public: GrGLuint singleSampleFBOID() const { return fSingleSampleFBOID; } GrGLuint multisampleFBOID() const { return fMultisampleFBOID; } + // If we have a multisample FBO, that is always where the stencil goes. With dynamic MSAA there + // will be a multisample FBO even if numSamples is 1. + bool stencilIsOnMultisampleFBO() const { + return this->numSamples() > 1 || fMultisampleFBOID != 0; + } + GrBackendRenderTarget getBackendRenderTarget() const override; GrBackendFormat backendFormat() const override;