From a219419c9d76432dca74494b611ff1f59086d139 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Mon, 2 Jul 2018 09:00:27 -0400 Subject: [PATCH] Some scissor state cleanup. Separate flushing the enablement of scissor from the rect in GrGLGpu. Move GrPipeline::ScissorState to a global enum and use more broadly. Rename to GrScissorTest to avoid name conflict with existing GrScissorState. Change-Id: Ib32160b3300bc12de2d2e1761d152fd1bba8b683 Reviewed-on: https://skia-review.googlesource.com/137395 Commit-Queue: Brian Salomon Reviewed-by: Chris Dalton --- include/private/GrTypesPriv.h | 5 + samplecode/SampleCCPRGeometry.cpp | 3 +- src/gpu/GrAppliedClip.h | 5 +- src/gpu/GrFixedClip.cpp | 9 +- src/gpu/GrFixedClip.h | 11 +- src/gpu/GrGpuCommandBuffer.cpp | 2 +- src/gpu/GrPipeline.cpp | 6 +- src/gpu/GrPipeline.h | 11 +- src/gpu/GrRenderTargetContext.cpp | 2 +- src/gpu/GrScissorState.h | 21 ++-- src/gpu/ccpr/GrCCPathParser.cpp | 4 +- src/gpu/ccpr/GrCCPerFlushResources.cpp | 3 +- src/gpu/gl/GrGLGpu.cpp | 110 +++++++++--------- src/gpu/gl/GrGLGpu.h | 11 +- src/gpu/gl/GrGLPathRendering.cpp | 2 +- src/gpu/ops/GrClearOp.cpp | 11 +- src/gpu/ops/GrClearOp.h | 10 +- src/gpu/ops/GrClearStencilClipOp.h | 8 +- src/gpu/ops/GrStencilAndCoverPathRenderer.cpp | 2 +- src/gpu/vk/GrVkGpuCommandBuffer.cpp | 16 +-- tests/GLProgramsTest.cpp | 3 - tests/GrMeshTest.cpp | 2 +- tests/GrPipelineDynamicStateTest.cpp | 24 ++-- 23 files changed, 138 insertions(+), 143 deletions(-) diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h index 16f3c4a53e..a5ee50878a 100644 --- a/include/private/GrTypesPriv.h +++ b/include/private/GrTypesPriv.h @@ -73,6 +73,11 @@ static const GrPixelConfig kSkia8888_GrPixelConfig = kRGBA_8888_GrPixelConfig; #error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format." #endif +enum class GrScissorTest : bool { + kDisabled = false, + kEnabled = true +}; + /** * Geometric primitives used for drawing. */ diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp index 13cc0a0690..1da048eda3 100644 --- a/samplecode/SampleCCPRGeometry.cpp +++ b/samplecode/SampleCCPRGeometry.cpp @@ -348,8 +348,7 @@ void CCPRGeometryView::DrawCoverageCountOp::onExecute(GrOpFlushState* state) { } } - GrPipeline pipeline(state->drawOpArgs().fProxy, GrPipeline::ScissorState::kDisabled, - SkBlendMode::kPlus); + GrPipeline pipeline(state->drawOpArgs().fProxy, GrScissorTest::kDisabled, SkBlendMode::kPlus); if (glGpu) { glGpu->handleDirtyContext(); diff --git a/src/gpu/GrAppliedClip.h b/src/gpu/GrAppliedClip.h index bfe3383e16..90068669db 100644 --- a/src/gpu/GrAppliedClip.h +++ b/src/gpu/GrAppliedClip.h @@ -11,10 +11,8 @@ #include "GrFragmentProcessor.h" #include "GrScissorState.h" #include "GrWindowRectsState.h" - #include "SkClipStack.h" - /** * Produced by GrHardClip. It provides a set of modifications to the hardware drawing state that * implement the clip. @@ -55,7 +53,8 @@ public: } bool doesClip() const { - return fScissorState.enabled() || this->hasStencilClip() || fWindowRectsState.enabled(); + return fScissorState.scissorTest() == GrScissorTest::kEnabled || this->hasStencilClip() || + fWindowRectsState.enabled(); } bool operator==(const GrAppliedHardClip& that) const { diff --git a/src/gpu/GrFixedClip.cpp b/src/gpu/GrFixedClip.cpp index 94a89fd034..7eee3941f2 100644 --- a/src/gpu/GrFixedClip.cpp +++ b/src/gpu/GrFixedClip.cpp @@ -14,12 +14,13 @@ bool GrFixedClip::quickContains(const SkRect& rect) const { if (fWindowRectsState.enabled()) { return false; } - return !fScissorState.enabled() || GrClip::IsInsideClip(fScissorState.rect(), rect); + return fScissorState.scissorTest() == GrScissorTest::kDisabled || + GrClip::IsInsideClip(fScissorState.rect(), rect); } void GrFixedClip::getConservativeBounds(int w, int h, SkIRect* devResult, bool* iior) const { devResult->setXYWH(0, 0, w, h); - if (fScissorState.enabled()) { + if (fScissorState.scissorTest() == GrScissorTest::kEnabled) { if (!devResult->intersect(fScissorState.rect())) { devResult->setEmpty(); } @@ -33,7 +34,7 @@ bool GrFixedClip::isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA* aa) const { if (fWindowRectsState.enabled()) { return false; } - if (fScissorState.enabled()) { + if (fScissorState.scissorTest() == GrScissorTest::kEnabled) { SkRect rect = SkRect::Make(fScissorState.rect()); if (!rect.intersects(rtBounds)) { return false; @@ -46,7 +47,7 @@ bool GrFixedClip::isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA* aa) const { }; bool GrFixedClip::apply(int rtWidth, int rtHeight, GrAppliedHardClip* out, SkRect* bounds) const { - if (fScissorState.enabled()) { + if (fScissorState.scissorTest() == GrScissorTest::kEnabled) { SkIRect tightScissor = SkIRect::MakeWH(rtWidth, rtHeight); if (!tightScissor.intersect(fScissorState.rect())) { return false; diff --git a/src/gpu/GrFixedClip.h b/src/gpu/GrFixedClip.h index d44c1e84e4..2e466aff67 100644 --- a/src/gpu/GrFixedClip.h +++ b/src/gpu/GrFixedClip.h @@ -21,14 +21,15 @@ public: explicit GrFixedClip(const SkIRect& scissorRect) : fScissorState(scissorRect) {} const GrScissorState& scissorState() const { return fScissorState; } - bool scissorEnabled() const { return fScissorState.enabled(); } - const SkIRect& scissorRect() const { SkASSERT(scissorEnabled()); return fScissorState.rect(); } + GrScissorTest scissorTest() const { return fScissorState.scissorTest(); } + const SkIRect& scissorRect() const { + SkASSERT(this->scissorTest() == GrScissorTest::kEnabled); + return fScissorState.rect(); + } void disableScissor() { fScissorState.setDisabled(); } - void setScissor(const SkIRect& irect) { - fScissorState.set(irect); - } + void setScissor(const SkIRect& irect) { fScissorState = GrScissorState(irect); } bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& irect) { return fScissorState.intersect(irect); } diff --git a/src/gpu/GrGpuCommandBuffer.cpp b/src/gpu/GrGpuCommandBuffer.cpp index 42e00f355f..1cedd0cdb8 100644 --- a/src/gpu/GrGpuCommandBuffer.cpp +++ b/src/gpu/GrGpuCommandBuffer.cpp @@ -39,7 +39,7 @@ bool GrGpuRTCommandBuffer::draw(const GrPrimitiveProcessor& primProc, const GrPi SkASSERT(primProc.hasInstanceAttributes() == meshes[i].isInstanced()); } #endif - SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState || + SkASSERT(pipeline.scissorTest() == GrScissorTest::kDisabled || fixedDynamicState || (dynamicStateArrays && dynamicStateArrays->fScissorRects)); auto resourceProvider = this->gpu()->getContext()->contextPriv().resourceProvider(); diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp index 6608d7c7d2..3f68fe088c 100644 --- a/src/gpu/GrPipeline.cpp +++ b/src/gpu/GrPipeline.cpp @@ -28,7 +28,7 @@ GrPipeline::GrPipeline(const InitArgs& args, if (appliedClip.hasStencilClip()) { fFlags |= kHasStencilClip_Flag; } - if (appliedClip.scissorState().enabled()) { + if (appliedClip.scissorState().scissorTest() == GrScissorTest::kEnabled) { fFlags |= kScissorEnabled_Flag; } @@ -99,7 +99,7 @@ GrXferBarrierType GrPipeline::xferBarrierType(const GrCaps& caps) const { return this->getXferProcessor().xferBarrierType(caps); } -GrPipeline::GrPipeline(GrRenderTargetProxy* proxy, ScissorState scissorState, SkBlendMode blendmode) +GrPipeline::GrPipeline(GrRenderTargetProxy* proxy, GrScissorTest scissorTest, SkBlendMode blendmode) : fProxy(proxy) , fWindowRectsState() , fUserStencilSettings(&GrUserStencilSettings::kUnused) @@ -108,7 +108,7 @@ GrPipeline::GrPipeline(GrRenderTargetProxy* proxy, ScissorState scissorState, Sk , fFragmentProcessors() , fNumColorProcessors(0) { SkASSERT(proxy); - if (scissorState) { + if (scissorTest == GrScissorTest::kEnabled) { fFlags |= kScissorEnabled_Flag; } } diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h index f60a6d410b..23255287ae 100644 --- a/src/gpu/GrPipeline.h +++ b/src/gpu/GrPipeline.h @@ -64,11 +64,6 @@ public: return flags; } - enum ScissorState : bool { - kEnabled = true, - kDisabled = false - }; - struct InitArgs { uint32_t fFlags = 0; const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused; @@ -103,7 +98,7 @@ public: * must be "Porter Duff" (<= kLastCoeffMode). If using ScissorState::kEnabled, the caller must * specify a scissor rectangle through the DynamicState struct. **/ - GrPipeline(GrRenderTargetProxy*, ScissorState, SkBlendMode); + GrPipeline(GrRenderTargetProxy*, GrScissorTest, SkBlendMode); GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&); @@ -179,8 +174,8 @@ public: const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; } - ScissorState isScissorEnabled() const { - return ScissorState(SkToBool(fFlags & kScissorEnabled_Flag)); + GrScissorTest scissorTest() const { + return GrScissorTest(SkToBool(fFlags & kScissorEnabled_Flag)); } const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; } diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 1dbde17575..9e52558768 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -329,7 +329,7 @@ void GrRenderTargetContext::internalClear(const GrFixedClip& clip, CanClearFullscreen canClearFullscreen) { bool isFull = false; if (!clip.hasWindowRectangles()) { - isFull = !clip.scissorEnabled() || + isFull = clip.scissorTest() == GrScissorTest::kDisabled || (CanClearFullscreen::kYes == canClearFullscreen && this->caps()->preferFullscreenClears()) || clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height())); diff --git a/src/gpu/GrScissorState.h b/src/gpu/GrScissorState.h index 59ea088078..a395aef7ac 100644 --- a/src/gpu/GrScissorState.h +++ b/src/gpu/GrScissorState.h @@ -8,32 +8,29 @@ #ifndef GrScissorState_DEFINED #define GrScissorState_DEFINED -#include "SkRect.h" - class GrScissorState { public: - GrScissorState() : fEnabled(false) {} - GrScissorState(const SkIRect& rect) : fEnabled(true), fRect(rect) {} - void setDisabled() { fEnabled = false; } - void set(const SkIRect& rect) { fRect = rect; fEnabled = true; } + GrScissorState() = default; + GrScissorState(const SkIRect& rect) : fScissorTest(GrScissorTest::kEnabled), fRect(rect) {} + void setDisabled() { fScissorTest = GrScissorTest::kDisabled; } bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& rect) { - if (!fEnabled) { - this->set(rect); + if (fScissorTest == GrScissorTest::kDisabled) { + *this = GrScissorState(rect); return true; } return fRect.intersect(rect); } bool operator==(const GrScissorState& other) const { - return fEnabled == other.fEnabled && - (false == fEnabled || fRect == other.fRect); + return fScissorTest == other.fScissorTest && + (fScissorTest == GrScissorTest::kDisabled || fRect == other.fRect); } bool operator!=(const GrScissorState& other) const { return !(*this == other); } - bool enabled() const { return fEnabled; } + GrScissorTest scissorTest() const { return fScissorTest; } const SkIRect& rect() const { return fRect; } private: - bool fEnabled; + GrScissorTest fScissorTest = GrScissorTest::kDisabled; SkIRect fRect; }; diff --git a/src/gpu/ccpr/GrCCPathParser.cpp b/src/gpu/ccpr/GrCCPathParser.cpp index 1935385eeb..d013b5766e 100644 --- a/src/gpu/ccpr/GrCCPathParser.cpp +++ b/src/gpu/ccpr/GrCCPathParser.cpp @@ -530,7 +530,7 @@ void GrCCPathParser::drawCoverageCount(GrOpFlushState* flushState, CoverageCount const PrimitiveTallies& batchTotalCounts = fCoverageCountBatches[batchID].fTotalPrimitiveCounts; - GrPipeline pipeline(flushState->drawOpArgs().fProxy, GrPipeline::ScissorState::kEnabled, + GrPipeline pipeline(flushState->drawOpArgs().fProxy, GrScissorTest::kEnabled, SkBlendMode::kPlus); if (batchTotalCounts.fTriangles) { @@ -564,7 +564,7 @@ void GrCCPathParser::drawPrimitives(GrOpFlushState* flushState, const GrPipeline GrCCCoverageProcessor::PrimitiveType primitiveType, int PrimitiveTallies::*instanceType, const SkIRect& drawBounds) const { - SkASSERT(pipeline.isScissorEnabled()); + SkASSERT(pipeline.scissorTest() == GrScissorTest::kEnabled); // Don't call reset(), as that also resets the reserve count. fMeshesScratchBuffer.pop_back_n(fMeshesScratchBuffer.count()); diff --git a/src/gpu/ccpr/GrCCPerFlushResources.cpp b/src/gpu/ccpr/GrCCPerFlushResources.cpp index dd0bf1b473..c4e2861b47 100644 --- a/src/gpu/ccpr/GrCCPerFlushResources.cpp +++ b/src/gpu/ccpr/GrCCPerFlushResources.cpp @@ -64,8 +64,7 @@ public: void onExecute(GrOpFlushState* flushState) override { SkASSERT(fStashedAtlasProxy); - GrPipeline pipeline(flushState->proxy(), GrPipeline::ScissorState::kDisabled, - SkBlendMode::kSrc); + GrPipeline pipeline(flushState->proxy(), GrScissorTest::kDisabled, SkBlendMode::kSrc); GrCCPathProcessor pathProc(flushState->resourceProvider(), std::move(fStashedAtlasProxy)); pathProc.drawPaths(flushState, pipeline, nullptr, *fResources, fBaseInstance, fEndInstance, this->bounds()); diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 40915a3dcb..02f2f37c6c 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -1358,7 +1358,7 @@ sk_sp GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, GrGLIRect viewport; this->bindSurfaceFBOForPixelOps(tex.get(), GR_GL_FRAMEBUFFER, &viewport, kDst_TempFBOTarget); - this->disableScissor(); + this->flushScissorTest(GrScissorTest::kDisabled); this->disableWindowRectangles(); GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); fHWWriteToColor = kYes_TriState; @@ -1605,29 +1605,45 @@ GrBuffer* GrGLGpu::onCreateBuffer(size_t size, GrBufferType intendedType, return GrGLBuffer::Create(this, size, intendedType, accessPattern, data); } -void GrGLGpu::flushScissor(const GrScissorState& scissorState, - const GrGLIRect& rtViewport, - GrSurfaceOrigin rtOrigin) { - if (scissorState.enabled()) { - GrGLIRect scissor; - scissor.setRelativeTo(rtViewport, scissorState.rect(), rtOrigin); - // if the scissor fully contains the viewport then we fall through and - // disable the scissor test. - if (!scissor.contains(rtViewport)) { - if (fHWScissorSettings.fRect != scissor) { - scissor.pushToGLScissor(this->glInterface()); - fHWScissorSettings.fRect = scissor; - } - if (kYes_TriState != fHWScissorSettings.fEnabled) { - GL_CALL(Enable(GR_GL_SCISSOR_TEST)); - fHWScissorSettings.fEnabled = kYes_TriState; +void GrGLGpu::flushScissorTest(GrScissorTest test) { + if (test == GrScissorTest::kEnabled) { + if (kYes_TriState != fHWScissorSettings.fEnabled) { + GL_CALL(Enable(GR_GL_SCISSOR_TEST)); + fHWScissorSettings.fEnabled = kYes_TriState; + } + } else { + if (kNo_TriState != fHWScissorSettings.fEnabled) { + GL_CALL(Disable(GR_GL_SCISSOR_TEST)); + fHWScissorSettings.fEnabled = kNo_TriState; + } + } +} + +void GrGLGpu::flushScissorRect(const SkIRect& scissorRect, const GrGLIRect& viewport, + GrSurfaceOrigin origin) { + GrGLIRect scissor; + scissor.setRelativeTo(viewport, scissorRect, origin); + if (fHWScissorSettings.fRect != scissor) { + scissor.pushToGLScissor(this->glInterface()); + fHWScissorSettings.fRect = scissor; + } +} + +void GrGLGpu::flushScissorState(const GrScissorState& clipScissor, const GrGLIRect& viewport, + GrSurfaceOrigin origin) { + if (clipScissor.scissorTest() == GrScissorTest::kEnabled) { + GrGLIRect scissorRect; + scissorRect.setRelativeTo(viewport, clipScissor.rect(), origin); + if (!scissorRect.contains(viewport)) { + this->flushScissorTest(GrScissorTest::kEnabled); + if (fHWScissorSettings.fRect != scissorRect) { + scissorRect.pushToGLScissor(this->glInterface()); + fHWScissorSettings.fRect = scissorRect; } return; } } - - // See fall through note above - this->disableScissor(); + this->flushScissorTest(GrScissorTest::kDisabled); } void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState, @@ -1721,12 +1737,10 @@ bool GrGLGpu::flushGLState(const GrPrimitiveProcessor& primProc, glRT->renderTargetPriv().numStencilBits()); } this->flushStencil(stencil); - if (pipeline.isScissorEnabled()) { - static constexpr SkIRect kBogusScissor{0, 0, 1, 1}; - GrScissorState state(fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor); - this->flushScissor(state, glRT->getViewport(), pipeline.proxy()->origin()); - } else { - this->disableScissor(); + this->flushScissorTest(pipeline.scissorTest()); + if (pipeline.scissorTest() == GrScissorTest::kEnabled && fixedDynamicState) { + this->flushScissorRect(fixedDynamicState->fScissorRect, glRT->getViewport(), + pipeline.proxy()->origin()); } this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT, pipeline.proxy()->origin()); this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !stencil.isDisabled()); @@ -1860,14 +1874,6 @@ void GrGLGpu::notifyBufferReleased(const GrGLBuffer* buffer) { } } -void GrGLGpu::disableScissor() { - if (kNo_TriState != fHWScissorSettings.fEnabled) { - GL_CALL(Disable(GR_GL_SCISSOR_TEST)); - fHWScissorSettings.fEnabled = kNo_TriState; - return; - } -} - void GrGLGpu::clear(const GrFixedClip& clip, GrColor color, GrRenderTarget* target, GrSurfaceOrigin origin) { // parent class should never let us get here with no RT @@ -1890,12 +1896,12 @@ void GrGLGpu::clear(const GrFixedClip& clip, GrColor color, GrGLRenderTarget* glRT = static_cast(target); - if (clip.scissorEnabled()) { + if (clip.scissorTest() == GrScissorTest::kEnabled) { this->flushRenderTarget(glRT, origin, clip.scissorRect()); } else { this->flushRenderTarget(glRT); } - this->flushScissor(clip.scissorState(), glRT->getViewport(), origin); + this->flushScissorState(clip.scissorState(), glRT->getViewport(), origin); this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); @@ -1924,7 +1930,7 @@ void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) { GrGLRenderTarget* glRT = static_cast(target); this->flushRenderTargetNoColorWrites(glRT); - this->disableScissor(); + this->flushScissorTest(GrScissorTest::kDisabled); this->disableWindowRectangles(); GL_CALL(StencilMask(0xffffffff)); @@ -1972,7 +1978,7 @@ void GrGLGpu::clearStencilClip(const GrFixedClip& clip, GrGLRenderTarget* glRT = static_cast(target); this->flushRenderTargetNoColorWrites(glRT); - this->flushScissor(clip.scissorState(), glRT->getViewport(), origin); + this->flushScissorState(clip.scissorState(), glRT->getViewport(), origin); this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); GL_CALL(StencilMask((uint32_t) clipStencilMask)); @@ -2254,8 +2260,8 @@ void GrGLGpu::draw(const GrPrimitiveProcessor& primProc, return; } - bool dynamicScissor = - pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects; + bool dynamicScissor = pipeline.scissorTest() == GrScissorTest::kEnabled && dynamicStateArrays && + dynamicStateArrays->fScissorRects; for (int i = 0; i < meshCount; ++i) { if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) { this->xferBarrier(pipeline.renderTarget(), barrierType); @@ -2263,8 +2269,8 @@ void GrGLGpu::draw(const GrPrimitiveProcessor& primProc, if (dynamicScissor) { GrGLRenderTarget* glRT = static_cast(pipeline.renderTarget()); - this->flushScissor(GrScissorState(dynamicStateArrays->fScissorRects[i]), - glRT->getViewport(), pipeline.proxy()->origin()); + this->flushScissorRect(dynamicStateArrays->fScissorRects[i], glRT->getViewport(), + pipeline.proxy()->origin()); } if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() && GrIsPrimTypeLines(meshes[i].primitiveType()) && @@ -2408,9 +2414,7 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { static constexpr auto kDirtyRectOrigin = kTopLeft_GrSurfaceOrigin; if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { // Apple's extension uses the scissor as the blit bounds. - GrScissorState scissorState; - scissorState.set(dirtyRect); - this->flushScissor(scissorState, vp, kDirtyRectOrigin); + this->flushScissorState(GrScissorState(dirtyRect), vp, kDirtyRectOrigin); this->disableWindowRectangles(); GL_CALL(ResolveMultisampleFramebuffer()); } else { @@ -2431,7 +2435,7 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { } // BlitFrameBuffer respects the scissor, so disable it. - this->disableScissor(); + this->flushScissorTest(GrScissorTest::kDisabled); this->disableWindowRectangles(); GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t, GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); @@ -3455,7 +3459,7 @@ void GrGLGpu::clearStencilClipAsDraw(const GrFixedClip& clip, bool insideStencil this->flushBlend(blendInfo, GrSwizzle::RGBA()); this->flushColorWrite(false); this->flushHWAAState(glRT, false, false); - this->flushScissor(clip.scissorState(), glRT->getViewport(), origin); + this->flushScissorState(clip.scissorState(), glRT->getViewport(), origin); this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); GrStencilAttachment* sb = rt->renderTargetPriv().getStencilAttachment(); // This should only be called internally when we know we have a stencil buffer. @@ -3563,7 +3567,7 @@ void GrGLGpu::clearColorAsDraw(const GrFixedClip& clip, GrGLfloat r, GrGLfloat g 2 * sizeof(GrGLfloat), 0); GrGLRenderTarget* glrt = static_cast(dst); - this->flushScissor(clip.scissorState(), glrt->getViewport(), origin); + this->flushScissorState(clip.scissorState(), glrt->getViewport(), origin); this->flushWindowRectangles(clip.windowRectsState(), glrt, origin); GL_CALL(Uniform4f(fClearColorProgram.fColorUniform, r, g, b, a)); @@ -3580,7 +3584,9 @@ void GrGLGpu::clearColorAsDraw(const GrFixedClip& clip, GrGLfloat r, GrGLfloat g GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst); - this->didWriteToSurface(dst, origin, clip.scissorEnabled() ? &clip.scissorRect() : nullptr); + const auto* rect = + clip.scissorTest() == GrScissorTest::kEnabled ? &clip.scissorRect() : nullptr; + this->didWriteToSurface(dst, origin, rect); } bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin, @@ -3660,7 +3666,7 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin, this->flushBlend(blendInfo, GrSwizzle::RGBA()); this->flushColorWrite(true); this->flushHWAAState(nullptr, false, false); - this->disableScissor(); + this->flushScissorTest(GrScissorTest::kDisabled); this->disableWindowRectangles(); this->disableStencil(); if (this->glCaps().srgbWriteControl()) { @@ -3732,7 +3738,7 @@ bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOr dstGLRect.setRelativeTo(dstVP, dstRect, dstOrigin); // BlitFrameBuffer respects the scissor, so disable it. - this->disableScissor(); + this->flushScissorTest(GrScissorTest::kDisabled); this->disableWindowRectangles(); GrGLint srcY0; @@ -3827,7 +3833,7 @@ bool GrGLGpu::onRegenerateMipMapLevels(GrTexture* texture) { this->flushBlend(blendInfo, GrSwizzle::RGBA()); this->flushColorWrite(true); this->flushHWAAState(nullptr, false, false); - this->disableScissor(); + this->flushScissorTest(GrScissorTest::kDisabled); this->disableWindowRectangles(); this->disableStencil(); diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 765d5f67ee..0448f11a45 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -328,14 +328,9 @@ private: void flushColorWrite(bool writeColor); - // flushes the scissor. see the note on flushBoundTextureAndParams about - // flushing the scissor after that function is called. - void flushScissor(const GrScissorState&, - const GrGLIRect& rtViewport, - GrSurfaceOrigin rtOrigin); - - // disables the scissor - void disableScissor(); + void flushScissorTest(GrScissorTest); + void flushScissorRect(const SkIRect& scissorRect, const GrGLIRect& viewport, GrSurfaceOrigin); + void flushScissorState(const GrScissorState&, const GrGLIRect& viewport, GrSurfaceOrigin); void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin); void disableWindowRectangles(); diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp index 85c129f8b0..dbadd5801e 100644 --- a/src/gpu/gl/GrGLPathRendering.cpp +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -90,7 +90,7 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath* GrGLRenderTarget* rt = static_cast(args.fProxy->priv().peekRenderTarget()); SkISize size = SkISize::Make(rt->width(), rt->height()); this->setProjectionMatrix(*args.fViewMatrix, size, args.fProxy->origin()); - gpu->flushScissor(*args.fScissor, rt->getViewport(), args.fProxy->origin()); + gpu->flushScissorState(*args.fScissor, rt->getViewport(), args.fProxy->origin()); gpu->flushHWAAState(rt, args.fUseHWAA, true); gpu->flushRenderTarget(rt); diff --git a/src/gpu/ops/GrClearOp.cpp b/src/gpu/ops/GrClearOp.cpp index 612ff2085d..52360dbe93 100644 --- a/src/gpu/ops/GrClearOp.cpp +++ b/src/gpu/ops/GrClearOp.cpp @@ -17,7 +17,8 @@ std::unique_ptr GrClearOp::Make(GrContext* context, GrColor color, GrSurfaceProxy* dstProxy) { const SkIRect rect = SkIRect::MakeWH(dstProxy->width(), dstProxy->height()); - if (clip.scissorEnabled() && !SkIRect::Intersects(clip.scissorRect(), rect)) { + if (clip.scissorTest() == GrScissorTest::kEnabled && + !SkIRect::Intersects(clip.scissorRect(), rect)) { return nullptr; } @@ -42,7 +43,7 @@ GrClearOp::GrClearOp(const GrFixedClip& clip, GrColor color, GrSurfaceProxy* pro , fClip(clip) , fColor(color) { const SkIRect rtRect = SkIRect::MakeWH(proxy->width(), proxy->height()); - if (fClip.scissorEnabled()) { + if (fClip.scissorTest() == GrScissorTest::kEnabled) { // Don't let scissors extend outside the RT. This may improve op combining. if (!fClip.intersect(rtRect)) { SkASSERT(0); // should be caught upstream @@ -53,8 +54,10 @@ GrClearOp::GrClearOp(const GrFixedClip& clip, GrColor color, GrSurfaceProxy* pro fClip.disableScissor(); } } - this->setBounds(SkRect::Make(fClip.scissorEnabled() ? fClip.scissorRect() : rtRect), - HasAABloat::kNo, IsZeroArea::kNo); + this->setBounds( + SkRect::Make(fClip.scissorTest() == GrScissorTest::kEnabled ? fClip.scissorRect() + : rtRect), + HasAABloat::kNo, IsZeroArea::kNo); } void GrClearOp::onExecute(GrOpFlushState* state) { diff --git a/src/gpu/ops/GrClearOp.h b/src/gpu/ops/GrClearOp.h index 6e76191dff..59929b269a 100644 --- a/src/gpu/ops/GrClearOp.h +++ b/src/gpu/ops/GrClearOp.h @@ -33,7 +33,7 @@ public: SkString string; string.append(INHERITED::dumpInfo()); string.appendf("Scissor [ "); - if (fClip.scissorEnabled()) { + if (fClip.scissorTest() == GrScissorTest::kEnabled) { const SkIRect& r = fClip.scissorRect(); string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom); } else { @@ -83,9 +83,11 @@ 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())); + if (fClip.scissorTest() == GrScissorTest::kDisabled) { + return true; + } + return that->fClip.scissorTest() == GrScissorTest::kEnabled && + fClip.scissorRect().contains(that->fClip.scissorRect()); } void onPrepare(GrOpFlushState*) override {} diff --git a/src/gpu/ops/GrClearStencilClipOp.h b/src/gpu/ops/GrClearStencilClipOp.h index 3e7ad5070f..09c05e1ceb 100644 --- a/src/gpu/ops/GrClearStencilClipOp.h +++ b/src/gpu/ops/GrClearStencilClipOp.h @@ -27,7 +27,7 @@ public: SkString dumpInfo() const override { SkString string("Scissor ["); - if (fClip.scissorEnabled()) { + if (fClip.scissorTest() == GrScissorTest::kEnabled) { const SkIRect& r = fClip.scissorRect(); string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom); } else { @@ -46,9 +46,9 @@ private: : INHERITED(ClassID()) , fClip(clip) , fInsideStencilMask(insideStencilMask) { - const SkRect& bounds = fClip.scissorEnabled() - ? SkRect::Make(fClip.scissorRect()) - : SkRect::MakeIWH(proxy->width(), proxy->height()); + const SkRect& bounds = fClip.scissorTest() == GrScissorTest::kEnabled + ? SkRect::Make(fClip.scissorRect()) + : SkRect::MakeIWH(proxy->width(), proxy->height()); this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); } diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp index f395927b63..6b56183752 100644 --- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp @@ -109,7 +109,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { return true; } GrStencilClip stencilClip(appliedClip.stencilStackID()); - if (appliedClip.scissorState().enabled()) { + if (appliedClip.scissorState().scissorTest() == GrScissorTest::kEnabled) { stencilClip.fixedClip().setScissor(appliedClip.scissorState().rect()); } if (appliedClip.windowRectsState().enabled()) { diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp index 91adb5a778..63ebba0f25 100644 --- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp +++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp @@ -305,7 +305,7 @@ void GrVkGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool in VkClearRect clearRect; // Flip rect if necessary SkIRect vkRect; - if (!clip.scissorEnabled()) { + if (clip.scissorTest() == GrScissorTest::kDisabled) { vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height()); } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) { vkRect = clip.scissorRect(); @@ -333,7 +333,7 @@ void GrVkGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool in cbInfo.fIsEmpty = false; // Update command buffer bounds - if (!clip.scissorEnabled()) { + if (clip.scissorTest() == GrScissorTest::kDisabled) { cbInfo.fBounds.join(fRenderTarget->getBoundsRect()); } else { cbInfo.fBounds.join(SkRect::Make(clip.scissorRect())); @@ -351,7 +351,7 @@ void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, GrColor color) { VkClearColorValue vkColor; GrColorToRGBAFloat(color, vkColor.float32); - if (cbInfo.fIsEmpty && !clip.scissorEnabled()) { + if (cbInfo.fIsEmpty && clip.scissorTest() == GrScissorTest::kDisabled) { // Change the render pass to do a clear load GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE); @@ -390,7 +390,7 @@ void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, GrColor color) { VkClearRect clearRect; // Flip rect if necessary SkIRect vkRect; - if (!clip.scissorEnabled()) { + if (clip.scissorTest() == GrScissorTest::kDisabled) { vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height()); } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) { vkRect = clip.scissorRect(); @@ -416,7 +416,7 @@ void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, GrColor color) { cbInfo.fIsEmpty = false; // Update command buffer bounds - if (!clip.scissorEnabled()) { + if (clip.scissorTest() == GrScissorTest::kDisabled) { cbInfo.fBounds.join(fRenderTarget->getBoundsRect()); } else { cbInfo.fBounds.join(SkRect::Make(clip.scissorRect())); @@ -591,7 +591,7 @@ GrVkPipelineState* GrVkGpuRTCommandBuffer::prepareDrawState( GrRenderTarget* rt = pipeline.renderTarget(); - if (!pipeline.isScissorEnabled()) { + if (pipeline.scissorTest() == GrScissorTest::kDisabled) { GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), rt, pipeline.proxy()->origin(), SkIRect::MakeWH(rt->width(), rt->height())); @@ -663,8 +663,8 @@ void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc, return; } - bool dynamicScissor = - pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects; + bool dynamicScissor = (pipeline.scissorTest() == GrScissorTest::kEnabled) && + dynamicStateArrays && dynamicStateArrays->fScissorRects; for (int i = 0; i < meshCount; ++i) { const GrMesh& mesh = meshes[i]; diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp index 359527fce5..06b8f71080 100644 --- a/tests/GLProgramsTest.cpp +++ b/tests/GLProgramsTest.cpp @@ -292,9 +292,6 @@ bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages, int ma return false; } - // dummy scissor state - GrScissorState scissor; - SkRandom random; static const int NUM_TESTS = 1024; for (int t = 0; t < NUM_TESTS; t++) { diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp index aa951c0364..e8c124d950 100644 --- a/tests/GrMeshTest.cpp +++ b/tests/GrMeshTest.cpp @@ -392,7 +392,7 @@ sk_sp DrawMeshHelper::getIndexBuffer() { void DrawMeshHelper::drawMesh(const GrMesh& mesh) { GrRenderTargetProxy* proxy = fState->drawOpArgs().fProxy; - GrPipeline pipeline(proxy, GrPipeline::ScissorState::kDisabled, SkBlendMode::kSrc); + GrPipeline pipeline(proxy, GrScissorTest::kDisabled, SkBlendMode::kSrc); GrMeshTestProcessor mtp(mesh.isInstanced(), mesh.hasVertexData()); fState->rtCommandBuffer()->draw(mtp, pipeline, nullptr, nullptr, &mesh, 1, SkRect::MakeIWH(kImageWidth, kImageHeight)); diff --git a/tests/GrPipelineDynamicStateTest.cpp b/tests/GrPipelineDynamicStateTest.cpp index b2aaecc48b..ad631899b9 100644 --- a/tests/GrPipelineDynamicStateTest.cpp +++ b/tests/GrPipelineDynamicStateTest.cpp @@ -28,8 +28,6 @@ * scissor rectangles then reads back the result to verify a successful test. */ -using ScissorState = GrPipeline::ScissorState; - static constexpr int kScreenSize = 6; static constexpr int kNumMeshes = 4; static constexpr int kScreenSplitX = kScreenSize/2; @@ -113,20 +111,18 @@ public: DEFINE_OP_CLASS_ID static std::unique_ptr Make(GrContext* context, - ScissorState scissorState, + GrScissorTest scissorTest, sk_sp vbuff) { GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); - return pool->allocate(scissorState, std::move(vbuff)); + return pool->allocate(scissorTest, std::move(vbuff)); } private: friend class GrOpMemoryPool; - GrPipelineDynamicStateTestOp(ScissorState scissorState, sk_sp vbuff) - : INHERITED(ClassID()) - , fScissorState(scissorState) - , fVertexBuffer(std::move(vbuff)) { + GrPipelineDynamicStateTestOp(GrScissorTest scissorTest, sk_sp vbuff) + : INHERITED(ClassID()), fScissorTest(scissorTest), fVertexBuffer(std::move(vbuff)) { this->setBounds(SkRect::MakeIWH(kScreenSize, kScreenSize), HasAABloat::kNo, IsZeroArea::kNo); } @@ -141,7 +137,7 @@ private: void onPrepare(GrOpFlushState*) override {} void onExecute(GrOpFlushState* state) override { GrRenderTargetProxy* proxy = state->drawOpArgs().fProxy; - GrPipeline pipeline(proxy, fScissorState, SkBlendMode::kSrc); + GrPipeline pipeline(proxy, fScissorTest, SkBlendMode::kSrc); SkSTArray meshes; for (int i = 0; i < kNumMeshes; ++i) { GrMesh& mesh = meshes.emplace_back(GrPrimitiveType::kTriangleStrip); @@ -155,7 +151,7 @@ private: SkRect::MakeIWH(kScreenSize, kScreenSize)); } - ScissorState fScissorState; + GrScissorTest fScissorTest; const sk_sp fVertexBuffer; typedef GrDrawOp INHERITED; @@ -208,17 +204,17 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrPipelineDynamicStateTest, reporter, ctxInfo uint32_t resultPx[kScreenSize * kScreenSize]; - for (ScissorState scissorState : {ScissorState::kEnabled, ScissorState::kDisabled}) { + for (GrScissorTest scissorTest : {GrScissorTest::kEnabled, GrScissorTest::kDisabled}) { rtc->clear(nullptr, 0xbaaaaaad, GrRenderTargetContext::CanClearFullscreen::kYes); rtc->priv().testingOnly_addDrawOp( - GrPipelineDynamicStateTestOp::Make(context, scissorState, vbuff)); + GrPipelineDynamicStateTestOp::Make(context, scissorTest, vbuff)); rtc->readPixels(SkImageInfo::Make(kScreenSize, kScreenSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType), resultPx, 4 * kScreenSize, 0, 0, 0); for (int y = 0; y < kScreenSize; ++y) { for (int x = 0; x < kScreenSize; ++x) { int expectedColorIdx; - if (ScissorState::kEnabled == scissorState) { + if (scissorTest == GrScissorTest::kEnabled) { expectedColorIdx = (x < kScreenSplitX ? 0 : 2) + (y < kScreenSplitY ? 0 : 1); } else { expectedColorIdx = kNumMeshes - 1; @@ -227,7 +223,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrPipelineDynamicStateTest, reporter, ctxInfo uint32_t actual = resultPx[y * kScreenSize + x]; if (expected != actual) { ERRORF(reporter, "[scissor=%s] pixel (%i,%i): got 0x%x expected 0x%x", - ScissorState::kEnabled == scissorState ? "enabled" : "disabled", x, y, + scissorTest == GrScissorTest::kEnabled ? "enabled" : "disabled", x, y, actual, expected); return; }