From 1e63279156d61b5a2faca9502895a9ee540490a7 Mon Sep 17 00:00:00 2001 From: Michael Ludwig Date: Thu, 21 May 2020 12:45:31 -0400 Subject: [PATCH] Only use scissor state for native clears This is the first of many CLs that progressively refine the clipping, scissoring, and clearing APIs. The series of changes focus on simplifying the clear APIs, consolidating clip intersection logic, and moving towards a more explicitly sized render target context (where confusion between approx-fit and exact-fit is handled externally, although I don't take it that far). Next step will be to propagate the simpler calls up to GrRTC. Bug:skia:10205 Change-Id: Idb0c58a63b7a3950a92604dd4c03536d668be7c4 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/290123 Commit-Queue: Michael Ludwig Reviewed-by: Chris Dalton --- src/gpu/GrOpsRenderPass.cpp | 14 +++++---- src/gpu/GrOpsRenderPass.h | 18 +++++++---- src/gpu/GrRenderTargetContext.cpp | 19 ++++++----- src/gpu/d3d/GrD3DCommandList.cpp | 6 ++-- src/gpu/d3d/GrD3DCommandList.h | 4 +-- src/gpu/d3d/GrD3DGpu.cpp | 4 +-- src/gpu/d3d/GrD3DGpu.h | 2 +- src/gpu/d3d/GrD3DOpsRenderPass.cpp | 7 ++--- src/gpu/d3d/GrD3DOpsRenderPass.h | 4 +-- src/gpu/dawn/GrDawnOpsRenderPass.cpp | 7 +++-- src/gpu/dawn/GrDawnOpsRenderPass.h | 4 +-- src/gpu/gl/GrGLGpu.cpp | 47 +++++++--------------------- src/gpu/gl/GrGLGpu.h | 8 ++--- src/gpu/gl/GrGLOpsRenderPass.cpp | 10 +++--- src/gpu/gl/GrGLOpsRenderPass.h | 5 ++- src/gpu/mock/GrMockOpsRenderPass.h | 6 ++-- src/gpu/mtl/GrMtlOpsRenderPass.h | 5 ++- src/gpu/mtl/GrMtlOpsRenderPass.mm | 10 ++++-- src/gpu/ops/GrClearOp.cpp | 24 +++++++------- src/gpu/ops/GrClearOp.h | 28 +++++++---------- src/gpu/ops/GrClearStencilClipOp.cpp | 6 ++-- src/gpu/ops/GrClearStencilClipOp.h | 18 +++++------ src/gpu/vk/GrVkOpsRenderPass.cpp | 30 +++++++----------- src/gpu/vk/GrVkOpsRenderPass.h | 4 +-- 24 files changed, 135 insertions(+), 155 deletions(-) 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);