diff --git a/src/gpu/GrOpsRenderPass.cpp b/src/gpu/GrOpsRenderPass.cpp index 66e346b82f..07b4eeebe3 100644 --- a/src/gpu/GrOpsRenderPass.cpp +++ b/src/gpu/GrOpsRenderPass.cpp @@ -11,12 +11,13 @@ #include "include/gpu/GrContext.h" #include "src/gpu/GrCaps.h" #include "src/gpu/GrContextPriv.h" -#include "src/gpu/GrFixedClip.h" +#include "src/gpu/GrCpuBuffer.h" #include "src/gpu/GrGpu.h" #include "src/gpu/GrPrimitiveProcessor.h" #include "src/gpu/GrProgramInfo.h" #include "src/gpu/GrRenderTarget.h" #include "src/gpu/GrRenderTargetPriv.h" +#include "src/gpu/GrScissorState.h" #include "src/gpu/GrSimpleMesh.h" #include "src/gpu/GrTexturePriv.h" @@ -37,21 +38,22 @@ void GrOpsRenderPass::end() { this->resetActiveBuffers(); } -void GrOpsRenderPass::clear(const GrFixedClip& clip, const SkPMColor4f& color) { +void GrOpsRenderPass::clear(const GrScissorState& scissor, const SkPMColor4f& color) { SkASSERT(fRenderTarget); // A clear at this level will always be a true clear, so make sure clears were not supposed to // be redirected to draws instead SkASSERT(!this->gpu()->caps()->performColorClearsAsDraws()); - SkASSERT(!clip.scissorEnabled() || !this->gpu()->caps()->performPartialClearsAsDraws()); + SkASSERT(!scissor.enabled() || !this->gpu()->caps()->performPartialClearsAsDraws()); fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured; - this->onClear(clip, color); + this->onClear(scissor, color); } -void GrOpsRenderPass::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) { +void GrOpsRenderPass::clearStencilClip(const GrScissorState& scissor, bool insideStencilMask) { // As above, make sure the stencil clear wasn't supposed to be a draw rect with stencil settings SkASSERT(!this->gpu()->caps()->performStencilClearsAsDraws()); + SkASSERT(!scissor.enabled() || !this->gpu()->caps()->performPartialClearsAsDraws()); fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured; - this->onClearStencilClip(clip, insideStencilMask); + this->onClearStencilClip(scissor, insideStencilMask); } void GrOpsRenderPass::executeDrawable(std::unique_ptr drawable) { diff --git a/src/gpu/GrOpsRenderPass.h b/src/gpu/GrOpsRenderPass.h index 959d1a222f..ec7960f366 100644 --- a/src/gpu/GrOpsRenderPass.h +++ b/src/gpu/GrOpsRenderPass.h @@ -13,12 +13,12 @@ #include "src/gpu/ops/GrDrawOp.h" class GrOpFlushState; -class GrFixedClip; class GrGpu; class GrPipeline; class GrPrimitiveProcessor; class GrProgramInfo; class GrRenderTarget; +class GrScissorState; class GrSemaphore; struct SkIRect; struct SkRect; @@ -120,11 +120,17 @@ public: virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0; /** - * Clear the owned render target. Ignores the draw state and clip. + * Clear the owned render target. Clears the full target if 'scissor' is disabled, otherwise it + * is restricted to 'scissor'. Must check caps.performPartialClearsAsDraws() before using an + * enabled scissor test; must check caps.performColorClearsAsDraws() before using this at all. */ - void clear(const GrFixedClip&, const SkPMColor4f&); + void clear(const GrScissorState& scissor, const SkPMColor4f&); - void clearStencilClip(const GrFixedClip&, bool insideStencilMask); + /** + * Same as clear() but modifies the stencil; check caps.performStencilClearsAsDraws() and + * caps.performPartialClearsAsDraws(). + */ + void clearStencilClip(const GrScissorState& scissor, bool insideStencilMask); /** * Executes the SkDrawable object for the underlying backend. @@ -189,8 +195,8 @@ private: virtual void onDrawIndexedIndirect(const GrBuffer*, size_t offset, int drawCount) { SK_ABORT("Not implemented."); // Only called if caps.nativeDrawIndirectSupport(). } - virtual void onClear(const GrFixedClip&, const SkPMColor4f&) = 0; - virtual void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) = 0; + virtual void onClear(const GrScissorState&, const SkPMColor4f&) = 0; + virtual void onClearStencilClip(const GrScissorState&, bool insideStencilMask) = 0; virtual void onExecuteDrawable(std::unique_ptr) {} enum class DrawPipelineStatus { diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 0990e76167..be418f609e 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -558,7 +558,7 @@ void GrRenderTargetContext::internalClear(const GrFixedClip& clip, fContext, SkIRect::MakeEmpty(), color, /* fullscreen */ true)); } } else { - if (this->caps()->performPartialClearsAsDraws()) { + if (this->caps()->performPartialClearsAsDraws() || clip.hasWindowRectangles()) { // performPartialClearsAsDraws() also returns true if any clear has to be a draw. GrPaint paint; clear_to_grpaint(color, &paint); @@ -567,7 +567,7 @@ void GrRenderTargetContext::internalClear(const GrFixedClip& clip, GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(), SkRect::Make(clip.scissorRect()))); } else { - std::unique_ptr op(GrClearOp::Make(fContext, clip, color, + std::unique_ptr op(GrClearOp::Make(fContext, clip.scissorState(), color, this->asSurfaceProxy())); // This version of the clear op factory can return null if the clip doesn't intersect // with the surface proxy's boundary @@ -979,18 +979,23 @@ void GrRenderTargetContextPriv::clearStencilClip(const GrFixedClip& clip, bool i void GrRenderTargetContext::internalStencilClear(const GrFixedClip& clip, bool insideStencilMask) { this->setNeedsStencil(/* useMixedSamplesIfNotMSAA = */ false); - if (this->caps()->performStencilClearsAsDraws()) { + bool clearWithDraw = this->caps()->performStencilClearsAsDraws() || + (clip.scissorEnabled() && this->caps()->performPartialClearsAsDraws()); + // TODO(michaelludwig): internalStencilClear will eventually just take a GrScissorState so + // we won't need to check window rectangles here. + if (clearWithDraw || clip.hasWindowRectangles()) { const GrUserStencilSettings* ss = GrStencilSettings::SetClipBitSettings(insideStencilMask); - SkRect rtRect = SkRect::MakeWH(this->width(), this->height()); + SkRect rect = clip.scissorEnabled() ? SkRect::Make(clip.scissorRect()) + : SkRect::MakeWH(this->width(), this->height()); // Configure the paint to have no impact on the color buffer GrPaint paint; paint.setXPFactory(GrDisableColorXPFactory::Get()); this->addDrawOp(clip, GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(), - rtRect, ss)); + rect, ss)); } else { - std::unique_ptr op(GrClearStencilClipOp::Make(fContext, clip, insideStencilMask, - this->asRenderTargetProxy())); + std::unique_ptr op(GrClearStencilClipOp::Make( + fContext, clip.scissorState(), insideStencilMask, this->asRenderTargetProxy())); if (!op) { return; } diff --git a/src/gpu/d3d/GrD3DCommandList.cpp b/src/gpu/d3d/GrD3DCommandList.cpp index aa9825cebf..fd06a980b5 100644 --- a/src/gpu/d3d/GrD3DCommandList.cpp +++ b/src/gpu/d3d/GrD3DCommandList.cpp @@ -7,6 +7,7 @@ #include "src/gpu/d3d/GrD3DCommandList.h" +#include "src/gpu/GrScissorState.h" #include "src/gpu/d3d/GrD3DBuffer.h" #include "src/gpu/d3d/GrD3DGpu.h" #include "src/gpu/d3d/GrD3DPipelineState.h" @@ -296,12 +297,13 @@ void GrD3DDirectCommandList::drawIndexedInstanced(unsigned int indexCount, void GrD3DDirectCommandList::clearRenderTargetView(GrD3DRenderTarget* renderTarget, const SkPMColor4f& color, - const GrFixedClip& clip) { + const GrScissorState& scissor) { + SkASSERT(!scissor.enabled()); // no cliprects for now this->addingWork(); this->addResource(renderTarget->resource()); fCommandList->ClearRenderTargetView(renderTarget->colorRenderTargetView(), color.vec(), - 0, NULL); // no cliprects for now + 0, NULL); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/d3d/GrD3DCommandList.h b/src/gpu/d3d/GrD3DCommandList.h index ee06b49cf6..6a00ded6ee 100644 --- a/src/gpu/d3d/GrD3DCommandList.h +++ b/src/gpu/d3d/GrD3DCommandList.h @@ -22,7 +22,7 @@ class GrD3DRenderTarget; class GrD3DRootSignature; class GrD3DTextureResource; -class GrFixedClip; +class GrScissorState; class GrD3DCommandList { public: @@ -134,7 +134,7 @@ public: unsigned int startInstance); void clearRenderTargetView(GrD3DRenderTarget* renderTarget, const SkPMColor4f& color, - const GrFixedClip& clip); + const GrScissorState& scissor); private: GrD3DDirectCommandList(gr_cp allocator, gr_cp commandList); diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp index e722b37095..c41ae081e0 100644 --- a/src/gpu/d3d/GrD3DGpu.cpp +++ b/src/gpu/d3d/GrD3DGpu.cpp @@ -563,12 +563,12 @@ bool GrD3DGpu::uploadToTexture(GrD3DTexture* tex, int left, int top, int width, return true; } -void GrD3DGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color, GrRenderTarget* rt) { +void GrD3DGpu::clear(const GrScissorState& scissor, const SkPMColor4f& color, GrRenderTarget* rt) { GrD3DRenderTarget* d3dRT = static_cast(rt); d3dRT->setResourceState(this, D3D12_RESOURCE_STATE_RENDER_TARGET); - fCurrentDirectCommandList->clearRenderTargetView(d3dRT, color, clip); + fCurrentDirectCommandList->clearRenderTargetView(d3dRT, color, scissor); } static bool check_resource_info(const GrD3DTextureResourceInfo& info) { diff --git a/src/gpu/d3d/GrD3DGpu.h b/src/gpu/d3d/GrD3DGpu.h index be8fbc587f..4100893a52 100644 --- a/src/gpu/d3d/GrD3DGpu.h +++ b/src/gpu/d3d/GrD3DGpu.h @@ -99,7 +99,7 @@ public: return nullptr; } - void clear(const GrFixedClip& clip, const SkPMColor4f& color, GrRenderTarget*); + void clear(const GrScissorState& scissor, const SkPMColor4f& color, GrRenderTarget*); void submit(GrOpsRenderPass* renderPass) override; diff --git a/src/gpu/d3d/GrD3DOpsRenderPass.cpp b/src/gpu/d3d/GrD3DOpsRenderPass.cpp index e6a8344dbc..18309da05b 100644 --- a/src/gpu/d3d/GrD3DOpsRenderPass.cpp +++ b/src/gpu/d3d/GrD3DOpsRenderPass.cpp @@ -46,8 +46,7 @@ GrGpu* GrD3DOpsRenderPass::gpu() { return fGpu; } void GrD3DOpsRenderPass::onBegin() { if (GrLoadOp::kClear == fColorLoadOp) { - GrFixedClip clip; - fGpu->clear(clip, fClearColor, fRenderTarget); + fGpu->clear(GrScissorState(), fClearColor, fRenderTarget); } } @@ -234,6 +233,6 @@ void GrD3DOpsRenderPass::onDrawIndexedInstanced(int indexCount, int baseIndex, i fGpu->stats()->incNumDraws(); } -void GrD3DOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) { - fGpu->clear(clip, color, fRenderTarget); +void GrD3DOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) { + fGpu->clear(scissor, color, fRenderTarget); } diff --git a/src/gpu/d3d/GrD3DOpsRenderPass.h b/src/gpu/d3d/GrD3DOpsRenderPass.h index 7ec418169c..51a385e75f 100644 --- a/src/gpu/d3d/GrD3DOpsRenderPass.h +++ b/src/gpu/d3d/GrD3DOpsRenderPass.h @@ -56,9 +56,9 @@ private: void onDrawIndirect(const GrBuffer*, size_t offset, int drawCount) override {} void onDrawIndexedIndirect(const GrBuffer*, size_t offset, int drawCount) override {} - void onClear(const GrFixedClip&, const SkPMColor4f& color) override; + void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override; - void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {} + void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override {} GrD3DGpu* fGpu; diff --git a/src/gpu/dawn/GrDawnOpsRenderPass.cpp b/src/gpu/dawn/GrDawnOpsRenderPass.cpp index 5857ac6dd2..1b0db7ade6 100644 --- a/src/gpu/dawn/GrDawnOpsRenderPass.cpp +++ b/src/gpu/dawn/GrDawnOpsRenderPass.cpp @@ -94,12 +94,15 @@ void GrDawnOpsRenderPass::submit() { fGpu->appendCommandBuffer(fEncoder.Finish()); } -void GrDawnOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) { +void GrDawnOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, + bool insideStencilMask) { + SkASSERT(!scissor.enabled()); fPassEncoder.EndPass(); fPassEncoder = beginRenderPass(wgpu::LoadOp::Load, wgpu::LoadOp::Clear); } -void GrDawnOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) { +void GrDawnOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) { + SkASSERT(!scissor.enabled()); fPassEncoder.EndPass(); fPassEncoder = beginRenderPass(wgpu::LoadOp::Clear, wgpu::LoadOp::Load); } diff --git a/src/gpu/dawn/GrDawnOpsRenderPass.h b/src/gpu/dawn/GrDawnOpsRenderPass.h index 8ab0c77144..1f7b70f25e 100644 --- a/src/gpu/dawn/GrDawnOpsRenderPass.h +++ b/src/gpu/dawn/GrDawnOpsRenderPass.h @@ -51,9 +51,9 @@ private: void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance, int baseVertex) override; - void onClear(const GrFixedClip&, const SkPMColor4f& color) override; + void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override; - void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override; + void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override; struct InlineUploadInfo { InlineUploadInfo(GrOpFlushState* state, const GrDeferredTextureUploadFn& upload) diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index ef000ad9c5..7813e401ae 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -1869,51 +1869,29 @@ GrGLenum GrGLGpu::bindBuffer(GrGpuBufferType type, const GrBuffer* buffer) { return bufferState->fGLTarget; } -void GrGLGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color, +void GrGLGpu::clear(const GrScissorState& scissor, const SkPMColor4f& color, GrRenderTarget* target, GrSurfaceOrigin origin) { // parent class should never let us get here with no RT SkASSERT(target); SkASSERT(!this->caps()->performColorClearsAsDraws()); - SkASSERT(!clip.scissorEnabled() || !this->caps()->performPartialClearsAsDraws()); + SkASSERT(!scissor.enabled() || !this->caps()->performPartialClearsAsDraws()); this->handleDirtyContext(); GrGLRenderTarget* glRT = static_cast(target); - if (clip.scissorEnabled()) { - this->flushRenderTarget(glRT, origin, clip.scissorRect()); + if (scissor.enabled()) { + this->flushRenderTarget(glRT, origin, scissor.rect()); } else { this->flushRenderTarget(glRT); } - this->flushScissor(clip.scissorState(), glRT->width(), glRT->height(), origin); - this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); + this->flushScissor(scissor, glRT->width(), glRT->height(), origin); + this->disableWindowRectangles(); this->flushColorWrite(true); this->flushClearColor(color); GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); } -void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) { - SkASSERT(!this->caps()->performStencilClearsAsDraws()); - - if (!target) { - return; - } - - // This should only be called internally when we know we have a stencil buffer. - SkASSERT(target->renderTargetPriv().getStencilAttachment()); - - GrGLRenderTarget* glRT = static_cast(target); - this->flushRenderTargetNoColorWrites(glRT); - - this->flushScissorTest(GrScissorTest::kDisabled); - this->disableWindowRectangles(); - - GL_CALL(StencilMask(0xffffffff)); - GL_CALL(ClearStencil(clearValue)); - GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); - fHWStencilSettings.invalidate(); -} - static bool use_tiled_rendering(const GrGLCaps& glCaps, const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore) { // Only use the tiled rendering extension if we can explicitly clear and discard the stencil. @@ -2011,11 +1989,11 @@ void GrGLGpu::endCommandBuffer(GrRenderTarget* rt, SkDEBUGCODE(fIsExecutingCommandBuffer_DebugOnly = false); } -void GrGLGpu::clearStencilClip(const GrFixedClip& clip, - bool insideStencilMask, +void GrGLGpu::clearStencilClip(const GrScissorState& scissor, bool insideStencilMask, GrRenderTarget* target, GrSurfaceOrigin origin) { SkASSERT(target); SkASSERT(!this->caps()->performStencilClearsAsDraws()); + SkASSERT(!scissor.enabled() || !this->caps()->performPartialClearsAsDraws()); this->handleDirtyContext(); GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment(); @@ -2046,8 +2024,8 @@ void GrGLGpu::clearStencilClip(const GrFixedClip& clip, GrGLRenderTarget* glRT = static_cast(target); this->flushRenderTargetNoColorWrites(glRT); - this->flushScissor(clip.scissorState(), glRT->width(), glRT->height(), origin); - this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); + this->flushScissor(scissor, glRT->width(), glRT->height(), origin); + this->disableWindowRectangles(); GL_CALL(StencilMask((uint32_t) clipStencilMask)); GL_CALL(ClearStencil(value)); @@ -2281,11 +2259,10 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resol fHWBoundRenderTargetUniqueID.makeInvalid(); if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { // Apple's extension uses the scissor as the blit bounds. - GrScissorState scissorState; - scissorState.set(resolveRect); // Passing in kTopLeft_GrSurfaceOrigin will make sure no transformation of the rect // happens inside flushScissor since resolveRect is already in native device coordinates. - this->flushScissor(scissorState, rt->width(), rt->height(), kTopLeft_GrSurfaceOrigin); + this->flushScissor(GrScissorState(resolveRect), rt->width(), rt->height(), + kTopLeft_GrSurfaceOrigin); this->disableWindowRectangles(); GL_CALL(ResolveMultisampleFramebuffer()); } else { diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 3f223091b1..ba0cadf79e 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -104,18 +104,14 @@ 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 GrFixedClip&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin); + void clear(const GrScissorState&, const SkPMColor4f&, GrRenderTarget*, 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 // function on GrGLOpsrenderPass. - void clearStencilClip(const GrFixedClip&, bool insideStencilMask, + void clearStencilClip(const GrScissorState&, bool insideStencilMask, GrRenderTarget*, GrSurfaceOrigin); - // FIXME (michaelludwig): Can this go away and just use clearStencilClip() + marking the - // stencil buffer as not dirty? - void clearStencil(GrRenderTarget*, int clearValue); - void beginCommandBuffer(GrRenderTarget*, const SkIRect& bounds, GrSurfaceOrigin, const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore); diff --git a/src/gpu/gl/GrGLOpsRenderPass.cpp b/src/gpu/gl/GrGLOpsRenderPass.cpp index 865d8075fe..737d69b8ca 100644 --- a/src/gpu/gl/GrGLOpsRenderPass.cpp +++ b/src/gpu/gl/GrGLOpsRenderPass.cpp @@ -259,12 +259,10 @@ void GrGLOpsRenderPass::onDrawIndexedIndirect(const GrBuffer* drawIndirectBuffer } } -void GrGLOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) { - fGpu->clear(clip, color, fRenderTarget, fOrigin); +void GrGLOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) { + fGpu->clear(scissor, color, fRenderTarget, fOrigin); } -void GrGLOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, - bool insideStencilMask) { - fGpu->clearStencilClip(clip, insideStencilMask, fRenderTarget, fOrigin); +void GrGLOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) { + fGpu->clearStencilClip(scissor, insideStencilMask, fRenderTarget, fOrigin); } - diff --git a/src/gpu/gl/GrGLOpsRenderPass.h b/src/gpu/gl/GrGLOpsRenderPass.h index b16dda1a95..038e5586f3 100644 --- a/src/gpu/gl/GrGLOpsRenderPass.h +++ b/src/gpu/gl/GrGLOpsRenderPass.h @@ -69,8 +69,8 @@ private: void onDrawIndirect(const GrBuffer* drawIndirectBuffer, size_t offset, int drawCount) override; void onDrawIndexedIndirect(const GrBuffer* drawIndirectBuffer, size_t offset, int drawCount) override; - void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override; - void onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) override; + void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override; + void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override; GrGLGpu* fGpu; SkIRect fContentBounds; @@ -89,4 +89,3 @@ private: }; #endif - diff --git a/src/gpu/mock/GrMockOpsRenderPass.h b/src/gpu/mock/GrMockOpsRenderPass.h index 5a45a3e971..703eac2133 100644 --- a/src/gpu/mock/GrMockOpsRenderPass.h +++ b/src/gpu/mock/GrMockOpsRenderPass.h @@ -45,8 +45,10 @@ private: void onDrawIndexedInstanced(int, int, int, int, int) override { this->dummyDraw(); } void onDrawIndirect(const GrBuffer*, size_t, int) override { this->dummyDraw(); } void onDrawIndexedIndirect(const GrBuffer*, size_t, int) override { this->dummyDraw(); } - void onClear(const GrFixedClip&, const SkPMColor4f&) override { this->markRenderTargetDirty(); } - void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {} + void onClear(const GrScissorState& scissor, const SkPMColor4f&) override { + this->markRenderTargetDirty(); + } + void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override {} void dummyDraw() { this->markRenderTargetDirty(); ++fNumDraws; diff --git a/src/gpu/mtl/GrMtlOpsRenderPass.h b/src/gpu/mtl/GrMtlOpsRenderPass.h index 77229ce848..c4cf385ef0 100644 --- a/src/gpu/mtl/GrMtlOpsRenderPass.h +++ b/src/gpu/mtl/GrMtlOpsRenderPass.h @@ -49,9 +49,9 @@ private: void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance, int baseVertex) override; - void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override; + void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override; - void onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) override; + void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override; void setupRenderPass(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo, const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo); @@ -80,4 +80,3 @@ private: }; #endif - diff --git a/src/gpu/mtl/GrMtlOpsRenderPass.mm b/src/gpu/mtl/GrMtlOpsRenderPass.mm index 576a1349c3..aaa394f9d6 100644 --- a/src/gpu/mtl/GrMtlOpsRenderPass.mm +++ b/src/gpu/mtl/GrMtlOpsRenderPass.mm @@ -123,7 +123,10 @@ bool GrMtlOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc, return true; } -void GrMtlOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) { +void GrMtlOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) { + // Partial clears are not supported + SkASSERT(!scissor.enabled()); + // Ideally we should never end up here since all clears should either be done as draws or // load ops in metal. However, if a client inserts a wait op we need to handle it. fRenderPassDesc.colorAttachments[0].clearColor = @@ -135,8 +138,9 @@ void GrMtlOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& col fGpu->commandBuffer()->getRenderCommandEncoder(fRenderPassDesc, nullptr, this); } -void GrMtlOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) { - SkASSERT(!clip.hasWindowRectangles()); +void GrMtlOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) { + // Partial clears are not supported + SkASSERT(!scissor.enabled()); GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment(); // this should only be called internally when we know we have a diff --git a/src/gpu/ops/GrClearOp.cpp b/src/gpu/ops/GrClearOp.cpp index 28529f47a0..dc1b93987a 100644 --- a/src/gpu/ops/GrClearOp.cpp +++ b/src/gpu/ops/GrClearOp.cpp @@ -15,17 +15,17 @@ #include "src/gpu/GrRecordingContextPriv.h" std::unique_ptr GrClearOp::Make(GrRecordingContext* context, - const GrFixedClip& clip, + const GrScissorState& scissor, const SkPMColor4f& color, GrSurfaceProxy* dstProxy) { const SkIRect rect = SkIRect::MakeSize(dstProxy->dimensions()); - if (clip.scissorEnabled() && !SkIRect::Intersects(clip.scissorRect(), rect)) { + if (scissor.enabled() && !SkIRect::Intersects(scissor.rect(), rect)) { return nullptr; } GrOpMemoryPool* pool = context->priv().opMemoryPool(); - return pool->allocate(clip, color, dstProxy); + return pool->allocate(scissor, color, dstProxy); } std::unique_ptr GrClearOp::Make(GrRecordingContext* context, @@ -39,27 +39,27 @@ std::unique_ptr GrClearOp::Make(GrRecordingContext* context, return pool->allocate(rect, color, fullScreen); } -GrClearOp::GrClearOp(const GrFixedClip& clip, const SkPMColor4f& color, GrSurfaceProxy* proxy) +GrClearOp::GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color, GrSurfaceProxy* proxy) : INHERITED(ClassID()) - , fClip(clip) + , fScissor(scissor) , fColor(color) { const SkIRect rtRect = SkIRect::MakeSize(proxy->dimensions()); - if (fClip.scissorEnabled()) { + if (fScissor.enabled()) { // Don't let scissors extend outside the RT. This may improve op combining. - if (!fClip.intersect(rtRect)) { + if (!fScissor.intersect(rtRect)) { SkASSERT(0); // should be caught upstream - fClip = GrFixedClip(SkIRect::MakeEmpty()); + fScissor.set(SkIRect::MakeEmpty()); } - if (proxy->isFunctionallyExact() && fClip.scissorRect() == rtRect) { - fClip.disableScissor(); + if (proxy->isFunctionallyExact() && fScissor.rect() == rtRect) { + fScissor.setDisabled(); } } - this->setBounds(SkRect::Make(fClip.scissorEnabled() ? fClip.scissorRect() : rtRect), + this->setBounds(SkRect::Make(fScissor.enabled() ? fScissor.rect() : rtRect), HasAABloat::kNo, IsHairline::kNo); } void GrClearOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) { SkASSERT(state->opsRenderPass()); - state->opsRenderPass()->clear(fClip, fColor); + state->opsRenderPass()->clear(fScissor, fColor); } diff --git a/src/gpu/ops/GrClearOp.h b/src/gpu/ops/GrClearOp.h index fbac02f9a7..0857064555 100644 --- a/src/gpu/ops/GrClearOp.h +++ b/src/gpu/ops/GrClearOp.h @@ -8,7 +8,7 @@ #ifndef GrClearOp_DEFINED #define GrClearOp_DEFINED -#include "src/gpu/GrFixedClip.h" +#include "src/gpu/GrScissorState.h" #include "src/gpu/ops/GrOp.h" class GrOpFlushState; @@ -19,7 +19,7 @@ public: DEFINE_OP_CLASS_ID static std::unique_ptr Make(GrRecordingContext* context, - const GrFixedClip& clip, + const GrScissorState& scissor, const SkPMColor4f& color, GrSurfaceProxy* dstProxy); @@ -35,8 +35,8 @@ public: SkString string; string.append(INHERITED::dumpInfo()); string.appendf("Scissor [ "); - if (fClip.scissorEnabled()) { - const SkIRect& r = fClip.scissorRect(); + if (fScissor.enabled()) { + const SkIRect& r = fScissor.rect(); string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom); } else { string.append("disabled"); @@ -52,15 +52,15 @@ public: private: friend class GrOpMemoryPool; // for ctors - GrClearOp(const GrFixedClip& clip, const SkPMColor4f& color, GrSurfaceProxy* proxy); + GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color, GrSurfaceProxy* proxy); GrClearOp(const SkIRect& rect, const SkPMColor4f& color, bool fullScreen) : INHERITED(ClassID()) - , fClip(GrFixedClip(rect)) + , fScissor(rect) , fColor(color) { if (fullScreen) { - fClip.disableScissor(); + fScissor.setDisabled(); } this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsHairline::kNo); } @@ -71,11 +71,8 @@ private: // contains the old clear, or when the new clear is a subset of the old clear and is the // same color. GrClearOp* cb = t->cast(); - if (fClip.windowRectsState() != cb->fClip.windowRectsState()) { - return CombineResult::kCannotCombine; - } if (cb->contains(this)) { - fClip = cb->fClip; + fScissor = cb->fScissor; fColor = cb->fColor; return CombineResult::kMerged; } else if (cb->fColor == fColor && this->contains(cb)) { @@ -86,9 +83,8 @@ private: bool contains(const GrClearOp* that) const { // The constructor ensures that scissor gets disabled on any clip that fills the entire RT. - return !fClip.scissorEnabled() || - (that->fClip.scissorEnabled() && - fClip.scissorRect().contains(that->fClip.scissorRect())); + return !fScissor.enabled() || + (that->fScissor.enabled() && fScissor.rect().contains(that->fScissor.rect())); } void onPrePrepare(GrRecordingContext*, @@ -100,8 +96,8 @@ private: void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override; - GrFixedClip fClip; - SkPMColor4f fColor; + GrScissorState fScissor; + SkPMColor4f fColor; typedef GrOp INHERITED; }; diff --git a/src/gpu/ops/GrClearStencilClipOp.cpp b/src/gpu/ops/GrClearStencilClipOp.cpp index 7ca4063b96..dc26471f1f 100644 --- a/src/gpu/ops/GrClearStencilClipOp.cpp +++ b/src/gpu/ops/GrClearStencilClipOp.cpp @@ -14,15 +14,15 @@ #include "src/gpu/GrRecordingContextPriv.h" std::unique_ptr GrClearStencilClipOp::Make(GrRecordingContext* context, - const GrFixedClip& clip, + const GrScissorState& scissor, bool insideStencilMask, GrRenderTargetProxy* proxy) { GrOpMemoryPool* pool = context->priv().opMemoryPool(); - return pool->allocate(clip, insideStencilMask, proxy); + return pool->allocate(scissor, insideStencilMask, proxy); } void GrClearStencilClipOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) { SkASSERT(state->opsRenderPass()); - state->opsRenderPass()->clearStencilClip(fClip, fInsideStencilMask); + state->opsRenderPass()->clearStencilClip(fScissor, fInsideStencilMask); } diff --git a/src/gpu/ops/GrClearStencilClipOp.h b/src/gpu/ops/GrClearStencilClipOp.h index 68f825a7e4..f185cdec69 100644 --- a/src/gpu/ops/GrClearStencilClipOp.h +++ b/src/gpu/ops/GrClearStencilClipOp.h @@ -8,8 +8,8 @@ #ifndef GrClearStencilClipOp_DEFINED #define GrClearStencilClipOp_DEFINED -#include "src/gpu/GrFixedClip.h" #include "src/gpu/GrRenderTargetProxy.h" +#include "src/gpu/GrScissorState.h" #include "src/gpu/ops/GrOp.h" class GrOpFlushState; @@ -20,7 +20,7 @@ public: DEFINE_OP_CLASS_ID static std::unique_ptr Make(GrRecordingContext* context, - const GrFixedClip& clip, + const GrScissorState& scissor, bool insideStencilMask, GrRenderTargetProxy* proxy); @@ -29,8 +29,8 @@ public: #ifdef SK_DEBUG SkString dumpInfo() const override { SkString string("Scissor ["); - if (fClip.scissorEnabled()) { - const SkIRect& r = fClip.scissorRect(); + if (fScissor.enabled()) { + const SkIRect& r = fScissor.rect(); string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom); } else { string.append("disabled"); @@ -44,13 +44,13 @@ public: private: friend class GrOpMemoryPool; // for ctor - GrClearStencilClipOp(const GrFixedClip& clip, bool insideStencilMask, + GrClearStencilClipOp(const GrScissorState& scissor, bool insideStencilMask, GrRenderTargetProxy* proxy) : INHERITED(ClassID()) - , fClip(clip) + , fScissor(scissor) , fInsideStencilMask(insideStencilMask) { const SkRect& bounds = - fClip.scissorEnabled() ? SkRect::Make(fClip.scissorRect()) : proxy->getBoundsRect(); + fScissor.enabled() ? SkRect::Make(fScissor.rect()) : proxy->getBoundsRect(); this->setBounds(bounds, HasAABloat::kNo, IsHairline::kNo); } @@ -63,8 +63,8 @@ private: void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; - const GrFixedClip fClip; - const bool fInsideStencilMask; + const GrScissorState fScissor; + const bool fInsideStencilMask; typedef GrOp INHERITED; }; diff --git a/src/gpu/vk/GrVkOpsRenderPass.cpp b/src/gpu/vk/GrVkOpsRenderPass.cpp index 5eef9cc72a..5828af8a41 100644 --- a/src/gpu/vk/GrVkOpsRenderPass.cpp +++ b/src/gpu/vk/GrVkOpsRenderPass.cpp @@ -265,14 +265,12 @@ bool GrVkOpsRenderPass::wrapsSecondaryCommandBuffer() const { //////////////////////////////////////////////////////////////////////////////// -void GrVkOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) { +void GrVkOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) { if (!fCurrentRenderPass) { SkASSERT(fGpu->isDeviceLost()); return; } - SkASSERT(!clip.hasWindowRectangles()); - GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment(); // this should only be called internally when we know we have a // stencil buffer. @@ -293,14 +291,13 @@ void GrVkOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideS VkClearRect clearRect; // Flip rect if necessary SkIRect vkRect; - if (!clip.scissorEnabled()) { + if (!scissor.enabled()) { vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height()); } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) { - vkRect = clip.scissorRect(); + vkRect = scissor.rect(); } else { - const SkIRect& scissor = clip.scissorRect(); - vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom, - scissor.fRight, fRenderTarget->height() - scissor.fTop); + vkRect.setLTRB(scissor.rect().fLeft, fRenderTarget->height() - scissor.rect().fBottom, + scissor.rect().fRight, fRenderTarget->height() - scissor.rect().fTop); } clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; @@ -321,15 +318,12 @@ void GrVkOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideS fCurrentCBIsEmpty = false; } -void GrVkOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) { +void GrVkOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) { if (!fCurrentRenderPass) { SkASSERT(fGpu->isDeviceLost()); return; } - // parent class should never let us get here with no RT - SkASSERT(!clip.hasWindowRectangles()); - VkClearColorValue vkColor = {{color.fR, color.fG, color.fB, color.fA}}; // If we end up in a situation where we are calling clear without a scissior then in general it @@ -338,20 +332,19 @@ void GrVkOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& colo // load op (e.g. if we needed to execute a wait op). Thus we also have the empty check here. // TODO: Make the waitOp a RenderTask instead so we can clear out the GrOpsTask for a clear. We // can then reenable this assert assuming we can't get messed up by a waitOp. - //SkASSERT(!fCurrentCBIsEmpty || clip.scissorEnabled()); + //SkASSERT(!fCurrentCBIsEmpty || scissor); // We always do a sub rect clear with clearAttachments since we are inside a render pass VkClearRect clearRect; // Flip rect if necessary SkIRect vkRect; - if (!clip.scissorEnabled()) { + if (!scissor.enabled()) { vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height()); } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) { - vkRect = clip.scissorRect(); + vkRect = scissor.rect(); } else { - const SkIRect& scissor = clip.scissorRect(); - vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom, - scissor.fRight, fRenderTarget->height() - scissor.fTop); + vkRect.setLTRB(scissor.rect().fLeft, fRenderTarget->height() - scissor.rect().fBottom, + scissor.rect().fRight, fRenderTarget->height() - scissor.rect().fTop); } clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; @@ -682,4 +675,3 @@ void GrVkOpsRenderPass::onExecuteDrawable(std::unique_ptrdraw(info); fGpu->addDrawable(std::move(drawable)); } - diff --git a/src/gpu/vk/GrVkOpsRenderPass.h b/src/gpu/vk/GrVkOpsRenderPass.h index 53bb07ed03..ef666ec334 100644 --- a/src/gpu/vk/GrVkOpsRenderPass.h +++ b/src/gpu/vk/GrVkOpsRenderPass.h @@ -84,9 +84,9 @@ private: void onDrawIndexedIndirect(const GrBuffer* drawIndirectBuffer, size_t offset, int drawCount) override; - void onClear(const GrFixedClip&, const SkPMColor4f& color) override; + void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override; - void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override; + void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override; void addAdditionalRenderPass(bool mustUseSecondaryCommandBuffer);