1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef GrAppliedClip_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define GrAppliedClip_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkClipStack.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrFragmentProcessor.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrScissorState.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrWindowRectsState.h" 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 20*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 21*c8dee2aaSAndroid Build Coastguard Worker #include <utility> 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker class GrWindowRectangles; 24*c8dee2aaSAndroid Build Coastguard Worker struct SkISize; 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker /** 27*c8dee2aaSAndroid Build Coastguard Worker * Produced by GrHardClip. It provides a set of modifications to the hardware drawing state that 28*c8dee2aaSAndroid Build Coastguard Worker * implement the clip. 29*c8dee2aaSAndroid Build Coastguard Worker */ 30*c8dee2aaSAndroid Build Coastguard Worker class GrAppliedHardClip { 31*c8dee2aaSAndroid Build Coastguard Worker public: Disabled()32*c8dee2aaSAndroid Build Coastguard Worker static const GrAppliedHardClip& Disabled() { 33*c8dee2aaSAndroid Build Coastguard Worker // The size doesn't really matter here since it's returned as const& so an actual scissor 34*c8dee2aaSAndroid Build Coastguard Worker // will never be set on it, and applied clips are not used to query or bounds test like 35*c8dee2aaSAndroid Build Coastguard Worker // the GrClip is. 36*c8dee2aaSAndroid Build Coastguard Worker static const GrAppliedHardClip kDisabled({1 << 29, 1 << 29}); 37*c8dee2aaSAndroid Build Coastguard Worker return kDisabled; 38*c8dee2aaSAndroid Build Coastguard Worker } 39*c8dee2aaSAndroid Build Coastguard Worker GrAppliedHardClip(const SkISize & rtDims)40*c8dee2aaSAndroid Build Coastguard Worker GrAppliedHardClip(const SkISize& rtDims) : fScissorState(rtDims) {} GrAppliedHardClip(const SkISize & logicalRTDims,const SkISize & backingStoreDims)41*c8dee2aaSAndroid Build Coastguard Worker GrAppliedHardClip(const SkISize& logicalRTDims, const SkISize& backingStoreDims) 42*c8dee2aaSAndroid Build Coastguard Worker : fScissorState(backingStoreDims) { 43*c8dee2aaSAndroid Build Coastguard Worker fScissorState.set(SkIRect::MakeSize(logicalRTDims)); 44*c8dee2aaSAndroid Build Coastguard Worker } 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard Worker GrAppliedHardClip(GrAppliedHardClip&& that) = default; 47*c8dee2aaSAndroid Build Coastguard Worker explicit GrAppliedHardClip(const GrAppliedHardClip&) = default; 48*c8dee2aaSAndroid Build Coastguard Worker scissorState()49*c8dee2aaSAndroid Build Coastguard Worker const GrScissorState& scissorState() const { return fScissorState; } windowRectsState()50*c8dee2aaSAndroid Build Coastguard Worker const GrWindowRectsState& windowRectsState() const { return fWindowRectsState; } stencilStackID()51*c8dee2aaSAndroid Build Coastguard Worker uint32_t stencilStackID() const { return fStencilStackID; } hasStencilClip()52*c8dee2aaSAndroid Build Coastguard Worker bool hasStencilClip() const { return SkClipStack::kInvalidGenID != fStencilStackID; } 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker /** 55*c8dee2aaSAndroid Build Coastguard Worker * Intersects the applied clip with the provided rect. Returns false if the draw became empty. 56*c8dee2aaSAndroid Build Coastguard Worker * 'clippedDrawBounds' will be intersected with 'irect'. This returns false if the clip becomes 57*c8dee2aaSAndroid Build Coastguard Worker * empty or the draw no longer intersects the clip. In either case the draw can be skipped. 58*c8dee2aaSAndroid Build Coastguard Worker */ addScissor(const SkIRect & irect,SkRect * clippedDrawBounds)59*c8dee2aaSAndroid Build Coastguard Worker bool addScissor(const SkIRect& irect, SkRect* clippedDrawBounds) { 60*c8dee2aaSAndroid Build Coastguard Worker return fScissorState.intersect(irect) && clippedDrawBounds->intersect(SkRect::Make(irect)); 61*c8dee2aaSAndroid Build Coastguard Worker } 62*c8dee2aaSAndroid Build Coastguard Worker setScissor(const SkIRect & irect)63*c8dee2aaSAndroid Build Coastguard Worker void setScissor(const SkIRect& irect) { 64*c8dee2aaSAndroid Build Coastguard Worker fScissorState.set(irect); 65*c8dee2aaSAndroid Build Coastguard Worker } 66*c8dee2aaSAndroid Build Coastguard Worker addWindowRectangles(const GrWindowRectsState & windowState)67*c8dee2aaSAndroid Build Coastguard Worker void addWindowRectangles(const GrWindowRectsState& windowState) { 68*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!fWindowRectsState.enabled()); 69*c8dee2aaSAndroid Build Coastguard Worker fWindowRectsState = windowState; 70*c8dee2aaSAndroid Build Coastguard Worker } 71*c8dee2aaSAndroid Build Coastguard Worker addWindowRectangles(const GrWindowRectangles & windows,GrWindowRectsState::Mode mode)72*c8dee2aaSAndroid Build Coastguard Worker void addWindowRectangles(const GrWindowRectangles& windows, GrWindowRectsState::Mode mode) { 73*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!fWindowRectsState.enabled()); 74*c8dee2aaSAndroid Build Coastguard Worker fWindowRectsState.set(windows, mode); 75*c8dee2aaSAndroid Build Coastguard Worker } 76*c8dee2aaSAndroid Build Coastguard Worker addStencilClip(uint32_t stencilStackID)77*c8dee2aaSAndroid Build Coastguard Worker void addStencilClip(uint32_t stencilStackID) { 78*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(SkClipStack::kInvalidGenID == fStencilStackID); 79*c8dee2aaSAndroid Build Coastguard Worker fStencilStackID = stencilStackID; 80*c8dee2aaSAndroid Build Coastguard Worker } 81*c8dee2aaSAndroid Build Coastguard Worker doesClip()82*c8dee2aaSAndroid Build Coastguard Worker bool doesClip() const { 83*c8dee2aaSAndroid Build Coastguard Worker return fScissorState.enabled() || this->hasStencilClip() || fWindowRectsState.enabled(); 84*c8dee2aaSAndroid Build Coastguard Worker } 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const GrAppliedHardClip& that) const { 87*c8dee2aaSAndroid Build Coastguard Worker return fScissorState == that.fScissorState && 88*c8dee2aaSAndroid Build Coastguard Worker fWindowRectsState == that.fWindowRectsState && 89*c8dee2aaSAndroid Build Coastguard Worker fStencilStackID == that.fStencilStackID; 90*c8dee2aaSAndroid Build Coastguard Worker } 91*c8dee2aaSAndroid Build Coastguard Worker bool operator!=(const GrAppliedHardClip& that) const { return !(*this == that); } 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker private: 94*c8dee2aaSAndroid Build Coastguard Worker GrScissorState fScissorState; 95*c8dee2aaSAndroid Build Coastguard Worker GrWindowRectsState fWindowRectsState; 96*c8dee2aaSAndroid Build Coastguard Worker uint32_t fStencilStackID = SkClipStack::kInvalidGenID; 97*c8dee2aaSAndroid Build Coastguard Worker }; 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker /** 100*c8dee2aaSAndroid Build Coastguard Worker * Produced by GrClip. It provides a set of modifications to GrPipeline that implement the clip. 101*c8dee2aaSAndroid Build Coastguard Worker */ 102*c8dee2aaSAndroid Build Coastguard Worker class GrAppliedClip { 103*c8dee2aaSAndroid Build Coastguard Worker public: Disabled()104*c8dee2aaSAndroid Build Coastguard Worker static GrAppliedClip Disabled() { 105*c8dee2aaSAndroid Build Coastguard Worker return GrAppliedClip({1 << 29, 1 << 29}); 106*c8dee2aaSAndroid Build Coastguard Worker } 107*c8dee2aaSAndroid Build Coastguard Worker GrAppliedClip(const SkISize & rtDims)108*c8dee2aaSAndroid Build Coastguard Worker GrAppliedClip(const SkISize& rtDims) : fHardClip(rtDims) {} GrAppliedClip(const SkISize & logicalRTDims,const SkISize & backingStoreDims)109*c8dee2aaSAndroid Build Coastguard Worker GrAppliedClip(const SkISize& logicalRTDims, const SkISize& backingStoreDims) 110*c8dee2aaSAndroid Build Coastguard Worker : fHardClip(logicalRTDims, backingStoreDims) {} 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker GrAppliedClip(GrAppliedClip&& that) = default; 113*c8dee2aaSAndroid Build Coastguard Worker GrAppliedClip(const GrAppliedClip&) = delete; 114*c8dee2aaSAndroid Build Coastguard Worker scissorState()115*c8dee2aaSAndroid Build Coastguard Worker const GrScissorState& scissorState() const { return fHardClip.scissorState(); } windowRectsState()116*c8dee2aaSAndroid Build Coastguard Worker const GrWindowRectsState& windowRectsState() const { return fHardClip.windowRectsState(); } stencilStackID()117*c8dee2aaSAndroid Build Coastguard Worker uint32_t stencilStackID() const { return fHardClip.stencilStackID(); } hasStencilClip()118*c8dee2aaSAndroid Build Coastguard Worker bool hasStencilClip() const { return fHardClip.hasStencilClip(); } hasCoverageFragmentProcessor()119*c8dee2aaSAndroid Build Coastguard Worker int hasCoverageFragmentProcessor() const { return fCoverageFP != nullptr; } coverageFragmentProcessor()120*c8dee2aaSAndroid Build Coastguard Worker const GrFragmentProcessor* coverageFragmentProcessor() const { 121*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fCoverageFP != nullptr); 122*c8dee2aaSAndroid Build Coastguard Worker return fCoverageFP.get(); 123*c8dee2aaSAndroid Build Coastguard Worker } detachCoverageFragmentProcessor()124*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> detachCoverageFragmentProcessor() { 125*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fCoverageFP != nullptr); 126*c8dee2aaSAndroid Build Coastguard Worker return std::move(fCoverageFP); 127*c8dee2aaSAndroid Build Coastguard Worker } 128*c8dee2aaSAndroid Build Coastguard Worker hardClip()129*c8dee2aaSAndroid Build Coastguard Worker const GrAppliedHardClip& hardClip() const { return fHardClip; } hardClip()130*c8dee2aaSAndroid Build Coastguard Worker GrAppliedHardClip& hardClip() { return fHardClip; } 131*c8dee2aaSAndroid Build Coastguard Worker addCoverageFP(std::unique_ptr<GrFragmentProcessor> fp)132*c8dee2aaSAndroid Build Coastguard Worker void addCoverageFP(std::unique_ptr<GrFragmentProcessor> fp) { 133*c8dee2aaSAndroid Build Coastguard Worker if (fCoverageFP == nullptr) { 134*c8dee2aaSAndroid Build Coastguard Worker fCoverageFP = std::move(fp); 135*c8dee2aaSAndroid Build Coastguard Worker } else { 136*c8dee2aaSAndroid Build Coastguard Worker // Compose this coverage FP with the previously-added coverage. 137*c8dee2aaSAndroid Build Coastguard Worker fCoverageFP = GrFragmentProcessor::Compose(std::move(fp), std::move(fCoverageFP)); 138*c8dee2aaSAndroid Build Coastguard Worker } 139*c8dee2aaSAndroid Build Coastguard Worker } 140*c8dee2aaSAndroid Build Coastguard Worker doesClip()141*c8dee2aaSAndroid Build Coastguard Worker bool doesClip() const { 142*c8dee2aaSAndroid Build Coastguard Worker return fHardClip.doesClip() || fCoverageFP != nullptr; 143*c8dee2aaSAndroid Build Coastguard Worker } 144*c8dee2aaSAndroid Build Coastguard Worker 145*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const GrAppliedClip& that) const { 146*c8dee2aaSAndroid Build Coastguard Worker if (fHardClip != that.fHardClip || 147*c8dee2aaSAndroid Build Coastguard Worker this->hasCoverageFragmentProcessor() != that.hasCoverageFragmentProcessor()) { 148*c8dee2aaSAndroid Build Coastguard Worker return false; 149*c8dee2aaSAndroid Build Coastguard Worker } 150*c8dee2aaSAndroid Build Coastguard Worker if (fCoverageFP != nullptr && !fCoverageFP->isEqual(*that.fCoverageFP)) { 151*c8dee2aaSAndroid Build Coastguard Worker return false; 152*c8dee2aaSAndroid Build Coastguard Worker } 153*c8dee2aaSAndroid Build Coastguard Worker return true; 154*c8dee2aaSAndroid Build Coastguard Worker } 155*c8dee2aaSAndroid Build Coastguard Worker bool operator!=(const GrAppliedClip& that) const { return !(*this == that); } 156*c8dee2aaSAndroid Build Coastguard Worker visitProxies(const GrVisitProxyFunc & func)157*c8dee2aaSAndroid Build Coastguard Worker void visitProxies(const GrVisitProxyFunc& func) const { 158*c8dee2aaSAndroid Build Coastguard Worker if (fCoverageFP != nullptr) { 159*c8dee2aaSAndroid Build Coastguard Worker fCoverageFP->visitProxies(func); 160*c8dee2aaSAndroid Build Coastguard Worker } 161*c8dee2aaSAndroid Build Coastguard Worker } 162*c8dee2aaSAndroid Build Coastguard Worker 163*c8dee2aaSAndroid Build Coastguard Worker private: 164*c8dee2aaSAndroid Build Coastguard Worker GrAppliedHardClip fHardClip; 165*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> fCoverageFP; 166*c8dee2aaSAndroid Build Coastguard Worker }; 167*c8dee2aaSAndroid Build Coastguard Worker 168*c8dee2aaSAndroid Build Coastguard Worker #endif 169