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