• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrFragmentProcessor.h"
12 #include "GrScissorState.h"
13 #include "GrWindowRectsState.h"
14 
15 #include "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  */
22 class GrAppliedHardClip {
23 public:
24     GrAppliedHardClip() = default;
25     GrAppliedHardClip(GrAppliedHardClip&& that) = default;
26     GrAppliedHardClip(const GrAppliedHardClip&) = delete;
27 
scissorState()28     const GrScissorState& scissorState() const { return fScissorState; }
windowRectsState()29     const GrWindowRectsState& windowRectsState() const { return fWindowRectsState; }
stencilStackID()30     uint32_t stencilStackID() const { return fStencilStackID; }
hasStencilClip()31     bool hasStencilClip() const { return SkClipStack::kInvalidGenID != fStencilStackID; }
32 
33     /**
34      * Intersects the applied clip with the provided rect. Returns false if the draw became empty.
35      * 'clippedDrawBounds' will be intersected with 'irect'. This returns false if the clip becomes
36      * empty or the draw no longer intersects the clip. In either case the draw can be skipped.
37      */
addScissor(const SkIRect & irect,SkRect * clippedDrawBounds)38     bool addScissor(const SkIRect& irect, SkRect* clippedDrawBounds) {
39         return fScissorState.intersect(irect) && clippedDrawBounds->intersect(SkRect::Make(irect));
40     }
41 
addWindowRectangles(const GrWindowRectsState & windowState)42     void addWindowRectangles(const GrWindowRectsState& windowState) {
43         SkASSERT(!fWindowRectsState.enabled());
44         fWindowRectsState = windowState;
45     }
46 
addWindowRectangles(const GrWindowRectangles & windows,GrWindowRectsState::Mode mode)47     void addWindowRectangles(const GrWindowRectangles& windows, GrWindowRectsState::Mode mode) {
48         SkASSERT(!fWindowRectsState.enabled());
49         fWindowRectsState.set(windows, mode);
50     }
51 
addStencilClip(uint32_t stencilStackID)52     void addStencilClip(uint32_t stencilStackID) {
53         SkASSERT(SkClipStack::kInvalidGenID == fStencilStackID);
54         fStencilStackID = stencilStackID;
55     }
56 
doesClip()57     bool doesClip() const {
58         return fScissorState.enabled() || this->hasStencilClip() || fWindowRectsState.enabled();
59     }
60 
61     bool operator==(const GrAppliedHardClip& that) const {
62         return fScissorState == that.fScissorState &&
63                fWindowRectsState == that.fWindowRectsState &&
64                fStencilStackID == that.fStencilStackID;
65     }
66     bool operator!=(const GrAppliedHardClip& that) const { return !(*this == that); }
67 
68 private:
69     GrScissorState             fScissorState;
70     GrWindowRectsState         fWindowRectsState;
71     uint32_t                   fStencilStackID = SkClipStack::kInvalidGenID;
72 };
73 
74 /**
75  * Produced by GrClip. It provides a set of modifications to GrPipeline that implement the clip.
76  */
77 class GrAppliedClip {
78 public:
79     GrAppliedClip() = default;
80     GrAppliedClip(GrAppliedClip&& that) = default;
81     GrAppliedClip(const GrAppliedClip&) = delete;
82 
scissorState()83     const GrScissorState& scissorState() const { return fHardClip.scissorState(); }
windowRectsState()84     const GrWindowRectsState& windowRectsState() const { return fHardClip.windowRectsState(); }
stencilStackID()85     uint32_t stencilStackID() const { return fHardClip.stencilStackID(); }
hasStencilClip()86     bool hasStencilClip() const { return fHardClip.hasStencilClip(); }
numClipCoverageFragmentProcessors()87     int numClipCoverageFragmentProcessors() const { return fClipCoverageFPs.count(); }
clipCoverageFragmentProcessor(int i)88     const GrFragmentProcessor* clipCoverageFragmentProcessor(int i) const {
89         SkASSERT(fClipCoverageFPs[i]);
90         return fClipCoverageFPs[i].get();
91     }
detachClipCoverageFragmentProcessor(int i)92     std::unique_ptr<const GrFragmentProcessor> detachClipCoverageFragmentProcessor(int i) {
93         SkASSERT(fClipCoverageFPs[i]);
94         return std::move(fClipCoverageFPs[i]);
95     }
96 
hardClip()97     GrAppliedHardClip& hardClip() { return fHardClip; }
98 
addCoverageFP(std::unique_ptr<GrFragmentProcessor> fp)99     void addCoverageFP(std::unique_ptr<GrFragmentProcessor> fp) {
100         SkASSERT(fp);
101         fClipCoverageFPs.push_back(std::move(fp));
102     }
103 
doesClip()104     bool doesClip() const {
105         return fHardClip.doesClip() || !fClipCoverageFPs.empty();
106     }
107 
108     bool operator==(const GrAppliedClip& that) const {
109         if (fHardClip != that.fHardClip ||
110             fClipCoverageFPs.count() != that.fClipCoverageFPs.count()) {
111             return false;
112         }
113         for (int i = 0; i < fClipCoverageFPs.count(); ++i) {
114             if (!fClipCoverageFPs[i] || !that.fClipCoverageFPs[i]) {
115                 if (fClipCoverageFPs[i] == that.fClipCoverageFPs[i]) {
116                     continue; // Both are null.
117                 }
118                 return false;
119             }
120             if (!fClipCoverageFPs[i]->isEqual(*that.fClipCoverageFPs[i])) {
121                 return false;
122             }
123         }
124         return true;
125     }
126     bool operator!=(const GrAppliedClip& that) const { return !(*this == that); }
127 
visitProxies(const std::function<void (GrSurfaceProxy *)> & func)128     void visitProxies(const std::function<void(GrSurfaceProxy*)>& func) const {
129         for (const std::unique_ptr<GrFragmentProcessor>& fp : fClipCoverageFPs) {
130             if (fp) { // This might be called after detach.
131                 fp->visitProxies(func);
132             }
133         }
134     }
135 
136 private:
137     GrAppliedHardClip fHardClip;
138     SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> fClipCoverageFPs;
139 };
140 
141 #endif
142