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