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 /**
16  * Produced by GrClip. It provides a set of modifications to the drawing state that are used to
17  * create the final GrPipeline for a GrOp.
18  */
19 class GrAppliedClip {
20 public:
21     GrAppliedClip() = default;
22     GrAppliedClip(GrAppliedClip&& that) = default;
23     GrAppliedClip(const GrAppliedClip&) = delete;
24 
scissorState()25     const GrScissorState& scissorState() const { return fScissorState; }
windowRectsState()26     const GrWindowRectsState& windowRectsState() const { return fWindowRectsState; }
clipCoverageFragmentProcessor()27     GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP.get(); }
hasStencilClip()28     bool hasStencilClip() const { return fHasStencilClip; }
29 
30     /**
31      * Intersects the applied clip with the provided rect. Returns false if the draw became empty.
32      * 'clippedDrawBounds' will be intersected with 'irect'. This returns false if the clip becomes
33      * empty or the draw no longer intersects the clip. In either case the draw can be skipped.
34      */
addScissor(const SkIRect & irect,SkRect * clippedDrawBounds)35     bool addScissor(const SkIRect& irect, SkRect* clippedDrawBounds) {
36         return fScissorState.intersect(irect) && clippedDrawBounds->intersect(SkRect::Make(irect));
37     }
38 
addWindowRectangles(const GrWindowRectsState & windowState)39     void addWindowRectangles(const GrWindowRectsState& windowState) {
40         SkASSERT(!fWindowRectsState.enabled());
41         fWindowRectsState = windowState;
42     }
43 
addWindowRectangles(const GrWindowRectangles & windows,GrWindowRectsState::Mode mode)44     void addWindowRectangles(const GrWindowRectangles& windows, GrWindowRectsState::Mode mode) {
45         SkASSERT(!fWindowRectsState.enabled());
46         fWindowRectsState.set(windows, mode);
47     }
48 
addCoverageFP(sk_sp<GrFragmentProcessor> fp)49     void addCoverageFP(sk_sp<GrFragmentProcessor> fp) {
50         SkASSERT(!fClipCoverageFP);
51         fClipCoverageFP = fp;
52     }
53 
addStencilClip()54     void addStencilClip() {
55         SkASSERT(!fHasStencilClip);
56         fHasStencilClip = true;
57     }
58 
doesClip()59     bool doesClip() const {
60         return fScissorState.enabled() || fClipCoverageFP || fHasStencilClip ||
61                fWindowRectsState.enabled();
62     }
63 
64     bool operator==(const GrAppliedClip& that) const {
65         if (fScissorState != that.fScissorState || fHasStencilClip != that.fHasStencilClip) {
66             return false;
67         }
68         if (SkToBool(fClipCoverageFP)) {
69             if (!SkToBool(that.fClipCoverageFP) ||
70                 !that.fClipCoverageFP->isEqual(*fClipCoverageFP)) {
71                 return false;
72             }
73         } else if (SkToBool(that.fClipCoverageFP)) {
74             return false;
75         }
76         return fWindowRectsState == that.fWindowRectsState;
77     }
78     bool operator!=(const GrAppliedClip& that) const { return !(*this == that); }
79 
80 private:
81     GrScissorState             fScissorState;
82     GrWindowRectsState         fWindowRectsState;
83     sk_sp<GrFragmentProcessor> fClipCoverageFP;
84     bool                       fHasStencilClip = false;
85 };
86 
87 #endif
88