blob: ba26d5c0817419e25da5e61486461e6ccb12e6a7 [file] [log] [blame]
joshualitt44701df2015-02-23 14:44:57 -08001/*
2 * Copyright 2010 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 GrClip_DEFINED
9#define GrClip_DEFINED
10
11#include "SkClipStack.h"
12#include "GrSurface.h"
13
14struct SkIRect;
15
16/**
17 * GrClip encapsulates the information required to construct the clip
18 * masks. 'A GrClip is either wide open, just an IRect, just a Rect(TODO), or a full clipstack.
19 * If the clip is a clipstack than the origin is used to translate the stack with
20 * respect to device coordinates. This allows us to use a clip stack that is
21 * specified for a root device with a layer device that is restricted to a subset
22 * of the original canvas. For other clip types the origin will always be (0,0).
23 *
24 * NOTE: GrClip *must* point to a const clipstack
25 */
26class GrClip : SkNoncopyable {
27public:
joshualitt0413d432015-02-23 17:52:51 -080028 GrClip() : fClipType(kWideOpen_ClipType) {
29 fOrigin.setZero();
30 }
joshualitt44701df2015-02-23 14:44:57 -080031 GrClip(const SkIRect& rect) : fClipType(kIRect_ClipType) {
joshualitt0413d432015-02-23 17:52:51 -080032 fOrigin.setZero();
joshualitt44701df2015-02-23 14:44:57 -080033 fClip.fIRect = rect;
34 }
35 ~GrClip() { this->reset(); }
36
37 const GrClip& operator=(const GrClip& other) {
38 this->reset();
39 fClipType = other.fClipType;
40 switch (other.fClipType) {
41 default:
42 SkFAIL("Incomplete Switch\n");
43 case kWideOpen_ClipType:
joshualitt0413d432015-02-23 17:52:51 -080044 fOrigin.setZero();
joshualitt44701df2015-02-23 14:44:57 -080045 break;
46 case kClipStack_ClipType:
joshualitt0413d432015-02-23 17:52:51 -080047 fClip.fStack = SkRef(other.clipStack());
48 fOrigin = other.origin();
joshualitt44701df2015-02-23 14:44:57 -080049 break;
50 case kIRect_ClipType:
51 fClip.fIRect = other.irect();
joshualitt0413d432015-02-23 17:52:51 -080052 fOrigin.setZero();
joshualitt44701df2015-02-23 14:44:57 -080053 break;
54 }
55 return *this;
56 }
57
58 bool operator==(const GrClip& other) const {
59 if (this->clipType() != other.clipType()) {
60 return false;
61 }
62
63 switch (fClipType) {
64 default:
65 SkFAIL("Incomplete Switch\n");
66 return false;
67 case kWideOpen_ClipType:
68 return true;
69 case kClipStack_ClipType:
70 if (this->origin() != other.origin()) {
71 return false;
72 }
73
74 if (this->clipStack() && other.clipStack()) {
75 return *this->clipStack() == *other.clipStack();
76 } else {
77 return this->clipStack() == other.clipStack();
78 }
79 break;
80 case kIRect_ClipType:
81 return this->irect() == other.irect();
82 break;
83 }
84 }
85
86 bool operator!=(const GrClip& other) const {
87 return !(*this == other);
88 }
89
90 const SkClipStack* clipStack() const {
91 SkASSERT(kClipStack_ClipType == fClipType);
joshualitt0413d432015-02-23 17:52:51 -080092 return fClip.fStack;
joshualitt44701df2015-02-23 14:44:57 -080093 }
94
95 void setClipStack(const SkClipStack* clipStack, const SkIPoint* origin = NULL) {
96 if (clipStack->isWideOpen()) {
97 fClipType = kWideOpen_ClipType;
joshualitt0413d432015-02-23 17:52:51 -080098 fOrigin.setZero();
joshualitt44701df2015-02-23 14:44:57 -080099 } else {
100 fClipType = kClipStack_ClipType;
joshualitt0413d432015-02-23 17:52:51 -0800101 fClip.fStack = SkRef(clipStack);
joshualitt44701df2015-02-23 14:44:57 -0800102 if (origin) {
joshualitt0413d432015-02-23 17:52:51 -0800103 fOrigin = *origin;
joshualitt44701df2015-02-23 14:44:57 -0800104 } else {
joshualitt0413d432015-02-23 17:52:51 -0800105 fOrigin.setZero();
joshualitt44701df2015-02-23 14:44:57 -0800106 }
107 }
108 }
109
110 const SkIRect& irect() const {
111 SkASSERT(kIRect_ClipType == fClipType);
112 return fClip.fIRect;
113 }
114
115 void reset() {
116 if (kClipStack_ClipType == fClipType) {
joshualitt0413d432015-02-23 17:52:51 -0800117 fClip.fStack->unref();
118 fClip.fStack = NULL;
joshualitt44701df2015-02-23 14:44:57 -0800119 }
120 fClipType = kWideOpen_ClipType;
joshualitt0413d432015-02-23 17:52:51 -0800121 fOrigin.setZero();
joshualitt44701df2015-02-23 14:44:57 -0800122 }
123
joshualitt0413d432015-02-23 17:52:51 -0800124 // We support this for all cliptypes to simplify the logic a bit in clip mask manager.
125 // non clipstack clip types MUST have a (0,0) origin
joshualitt44701df2015-02-23 14:44:57 -0800126 const SkIPoint& origin() const {
joshualitt0413d432015-02-23 17:52:51 -0800127 SkASSERT(fClipType == kClipStack_ClipType || (fOrigin.fX == 0 && fOrigin.fY == 0));
128 return fOrigin;
joshualitt44701df2015-02-23 14:44:57 -0800129 }
130
131 bool isWideOpen(const SkRect& rect) const {
132 return (kWideOpen_ClipType == fClipType) ||
133 (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) ||
134 (kIRect_ClipType == fClipType && this->irect().contains(rect));
135 }
136
137 bool isWideOpen(const SkIRect& rect) const {
138 return (kWideOpen_ClipType == fClipType) ||
139 (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) ||
140 (kIRect_ClipType == fClipType && this->irect().contains(rect));
141 }
142
143 bool isWideOpen() const {
144 return (kWideOpen_ClipType == fClipType) ||
145 (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen());
146 }
147
148 void getConservativeBounds(const GrSurface* surface,
149 SkIRect* devResult,
150 bool* isIntersectionOfRects = NULL) const {
151 this->getConservativeBounds(surface->width(), surface->height(),
152 devResult, isIntersectionOfRects);
153 }
154
155 void getConservativeBounds(int width, int height,
156 SkIRect* devResult,
157 bool* isIntersectionOfRects = NULL) const;
158
joshualitt9ece6a92015-02-23 17:03:33 -0800159 static const GrClip& WideOpen();
joshualitt44701df2015-02-23 14:44:57 -0800160
161 enum ClipType {
162 kClipStack_ClipType,
163 kWideOpen_ClipType,
164 kIRect_ClipType,
165 };
166
167 ClipType clipType() const { return fClipType; }
168
169private:
170 union Clip {
joshualitt0413d432015-02-23 17:52:51 -0800171 const SkClipStack* fStack;
joshualitt44701df2015-02-23 14:44:57 -0800172 SkIRect fIRect;
173 } fClip;
174
joshualitt0413d432015-02-23 17:52:51 -0800175 SkIPoint fOrigin;
joshualitt44701df2015-02-23 14:44:57 -0800176 ClipType fClipType;
177};
178
179#endif