Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: src/core/SkRasterClip.cpp

Issue 554033003: Revert of allow canvas to force conservative clips (for speed) (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkRasterClip.h ('k') | src/core/SkRecorder.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2010 Google Inc. 2 * Copyright 2010 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkRasterClip.h" 8 #include "SkRasterClip.h"
9 #include "SkPath.h" 9
10
11 SkRasterClip::SkRasterClip() {
12 fIsBW = true;
13 fIsEmpty = true;
14 fIsRect = false;
15 SkDEBUGCODE(this->validate();)
16 }
10 17
11 SkRasterClip::SkRasterClip(const SkRasterClip& src) { 18 SkRasterClip::SkRasterClip(const SkRasterClip& src) {
12 AUTO_RASTERCLIP_VALIDATE(src); 19 AUTO_RASTERCLIP_VALIDATE(src);
13 20
14 fForceConservativeRects = src.fForceConservativeRects;
15 fIsBW = src.fIsBW; 21 fIsBW = src.fIsBW;
16 if (fIsBW) { 22 if (fIsBW) {
17 fBW = src.fBW; 23 fBW = src.fBW;
18 } else { 24 } else {
19 fAA = src.fAA; 25 fAA = src.fAA;
20 } 26 }
21 27
22 fIsEmpty = src.isEmpty(); 28 fIsEmpty = src.isEmpty();
23 fIsRect = src.isRect(); 29 fIsRect = src.isRect();
24 SkDEBUGCODE(this->validate();) 30 SkDEBUGCODE(this->validate();)
25 } 31 }
26 32
27 SkRasterClip::SkRasterClip(const SkIRect& bounds, bool forceConservativeRects) : fBW(bounds) { 33 SkRasterClip::SkRasterClip(const SkIRect& bounds) : fBW(bounds) {
28 fForceConservativeRects = forceConservativeRects;
29 fIsBW = true; 34 fIsBW = true;
30 fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute 35 fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute
31 fIsRect = !fIsEmpty; 36 fIsRect = !fIsEmpty;
32 SkDEBUGCODE(this->validate();) 37 SkDEBUGCODE(this->validate();)
33 } 38 }
34 39
35 SkRasterClip::SkRasterClip(bool forceConservativeRects) {
36 fForceConservativeRects = forceConservativeRects;
37 fIsBW = true;
38 fIsEmpty = true;
39 fIsRect = false;
40 SkDEBUGCODE(this->validate();)
41 }
42
43 SkRasterClip::~SkRasterClip() { 40 SkRasterClip::~SkRasterClip() {
44 SkDEBUGCODE(this->validate();) 41 SkDEBUGCODE(this->validate();)
45 } 42 }
46 43
47 bool SkRasterClip::isComplex() const { 44 bool SkRasterClip::isComplex() const {
48 return fIsBW ? fBW.isComplex() : !fAA.isEmpty(); 45 return fIsBW ? fBW.isComplex() : !fAA.isEmpty();
49 } 46 }
50 47
51 const SkIRect& SkRasterClip::getBounds() const { 48 const SkIRect& SkRasterClip::getBounds() const {
52 return fIsBW ? fBW.getBounds() : fAA.getBounds(); 49 return fIsBW ? fBW.getBounds() : fAA.getBounds();
(...skipping 13 matching lines...) Expand all
66 bool SkRasterClip::setRect(const SkIRect& rect) { 63 bool SkRasterClip::setRect(const SkIRect& rect) {
67 AUTO_RASTERCLIP_VALIDATE(*this); 64 AUTO_RASTERCLIP_VALIDATE(*this);
68 65
69 fIsBW = true; 66 fIsBW = true;
70 fAA.setEmpty(); 67 fAA.setEmpty();
71 fIsRect = fBW.setRect(rect); 68 fIsRect = fBW.setRect(rect);
72 fIsEmpty = !fIsRect; 69 fIsEmpty = !fIsRect;
73 return fIsRect; 70 return fIsRect;
74 } 71 }
75 72
76 //////////////////////////////////////////////////////////////////////////////// /////
77
78 bool SkRasterClip::setConservativeRect(const SkRect& r, const SkIRect& clipR, bo ol isInverse) {
79 SkIRect ir;
80 r.roundOut(&ir);
81
82 SkRegion::Op op;
83 if (isInverse) {
84 op = SkRegion::kDifference_Op;
85 } else {
86 op = SkRegion::kIntersect_Op;
87 }
88 fBW.setRect(clipR);
89 fBW.op(ir, op);
90 return this->updateCacheAndReturnNonEmpty();
91 }
92
93 //////////////////////////////////////////////////////////////////////////////// /////
94
95 enum MutateResult {
96 kDoNothing_MutateResult,
97 kReplaceClippedAgainstGlobalBounds_MutateResult,
98 kContinue_MutateResult,
99 };
100
101 static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) {
102 if (inverseFilled) {
103 switch (*op) {
104 case SkRegion::kIntersect_Op:
105 case SkRegion::kDifference_Op:
106 // These ops can only shrink the current clip. So leaving
107 // the clip unchanged conservatively respects the contract.
108 return kDoNothing_MutateResult;
109 case SkRegion::kUnion_Op:
110 case SkRegion::kReplace_Op:
111 case SkRegion::kReverseDifference_Op:
112 case SkRegion::kXOR_Op: {
113 // These ops can grow the current clip up to the extents of
114 // the input clip, which is inverse filled, so we just set
115 // the current clip to the device bounds.
116 *op = SkRegion::kReplace_Op;
117 return kReplaceClippedAgainstGlobalBounds_MutateResult;
118 }
119 }
120 } else {
121 // Not inverse filled
122 switch (*op) {
123 case SkRegion::kIntersect_Op:
124 case SkRegion::kUnion_Op:
125 case SkRegion::kReplace_Op:
126 return kContinue_MutateResult;
127 case SkRegion::kDifference_Op:
128 // Difference can only shrink the current clip.
129 // Leaving clip unchanged conservatively fullfills the contract.
130 return kDoNothing_MutateResult;
131 case SkRegion::kReverseDifference_Op:
132 // To reverse, we swap in the bounds with a replace op.
133 // As with difference, leave it unchanged.
134 *op = SkRegion::kReplace_Op;
135 return kContinue_MutateResult;
136 case SkRegion::kXOR_Op:
137 // Be conservative, based on (A XOR B) always included in (A uni on B),
138 // which is always included in (bounds(A) union bounds(B))
139 *op = SkRegion::kUnion_Op;
140 return kContinue_MutateResult;
141 }
142 }
143 SkFAIL("should not get here");
144 return kDoNothing_MutateResult;
145 }
146
147 bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) { 73 bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) {
148 AUTO_RASTERCLIP_VALIDATE(*this); 74 AUTO_RASTERCLIP_VALIDATE(*this);
149 75
150 if (fForceConservativeRects) {
151 return this->setConservativeRect(path.getBounds(), clip.getBounds(), pat h.isInverseFillType());
152 }
153
154 if (this->isBW() && !doAA) { 76 if (this->isBW() && !doAA) {
155 (void)fBW.setPath(path, clip); 77 (void)fBW.setPath(path, clip);
156 } else { 78 } else {
157 // TODO: since we are going to over-write fAA completely (aren't we?) 79 // TODO: since we are going to over-write fAA completely (aren't we?)
158 // we should just clear our BW data (if any) and set fIsAA=true 80 // we should just clear our BW data (if any) and set fIsAA=true
159 if (this->isBW()) { 81 if (this->isBW()) {
160 this->convertToAA(); 82 this->convertToAA();
161 } 83 }
162 (void)fAA.setPath(path, &clip, doAA); 84 (void)fAA.setPath(path, &clip, doAA);
163 } 85 }
164 return this->updateCacheAndReturnNonEmpty(); 86 return this->updateCacheAndReturnNonEmpty();
165 } 87 }
166 88
167 bool SkRasterClip::op(const SkPath& path, const SkISize& size, SkRegion::Op op, bool doAA) { 89 bool SkRasterClip::op(const SkPath& path, const SkISize& size, SkRegion::Op op, bool doAA) {
168 // base is used to limit the size (and therefore memory allocation) of the 90 // base is used to limit the size (and therefore memory allocation) of the
169 // region that results from scan converting devPath. 91 // region that results from scan converting devPath.
170 SkRegion base; 92 SkRegion base;
171 93
172 if (fForceConservativeRects) {
173 SkIRect ir;
174 switch (mutate_conservative_op(&op, path.isInverseFillType())) {
175 case kDoNothing_MutateResult:
176 return !this->isEmpty();
177 case kReplaceClippedAgainstGlobalBounds_MutateResult:
178 ir = SkIRect::MakeSize(size);
179 break;
180 case kContinue_MutateResult:
181 path.getBounds().roundOut(&ir);
182 break;
183 }
184 return this->op(ir, op);
185 }
186
187 if (SkRegion::kIntersect_Op == op) { 94 if (SkRegion::kIntersect_Op == op) {
188 // since we are intersect, we can do better (tighter) with currRgn's 95 // since we are intersect, we can do better (tighter) with currRgn's
189 // bounds, than just using the device. However, if currRgn is complex, 96 // bounds, than just using the device. However, if currRgn is complex,
190 // our region blitter may hork, so we do that case in two steps. 97 // our region blitter may hork, so we do that case in two steps.
191 if (this->isRect()) { 98 if (this->isRect()) {
192 // FIXME: we should also be able to do this when this->isBW(), 99 // FIXME: we should also be able to do this when this->isBW(),
193 // but relaxing the test above triggers GM asserts in 100 // but relaxing the test above triggers GM asserts in
194 // SkRgnBuilder::blitH(). We need to investigate what's going on. 101 // SkRgnBuilder::blitH(). We need to investigate what's going on.
195 return this->setPath(path, this->bwRgn(), doAA); 102 return this->setPath(path, this->bwRgn(), doAA);
196 } else { 103 } else {
197 base.setRect(this->getBounds()); 104 base.setRect(this->getBounds());
198 SkRasterClip clip(fForceConservativeRects); 105 SkRasterClip clip;
199 clip.setPath(path, base, doAA); 106 clip.setPath(path, base, doAA);
200 return this->op(clip, op); 107 return this->op(clip, op);
201 } 108 }
202 } else { 109 } else {
203 base.setRect(0, 0, size.width(), size.height()); 110 base.setRect(0, 0, size.width(), size.height());
204 111
205 if (SkRegion::kReplace_Op == op) { 112 if (SkRegion::kReplace_Op == op) {
206 return this->setPath(path, base, doAA); 113 return this->setPath(path, base, doAA);
207 } else { 114 } else {
208 SkRasterClip clip(fForceConservativeRects); 115 SkRasterClip clip;
209 clip.setPath(path, base, doAA); 116 clip.setPath(path, base, doAA);
210 return this->op(clip, op); 117 return this->op(clip, op);
211 } 118 }
212 } 119 }
213 } 120 }
214 121
215 bool SkRasterClip::setPath(const SkPath& path, const SkIRect& clip, bool doAA) { 122 bool SkRasterClip::setPath(const SkPath& path, const SkIRect& clip, bool doAA) {
216 SkRegion tmp; 123 SkRegion tmp;
217 tmp.setRect(clip); 124 tmp.setRect(clip);
218 return this->setPath(path, tmp, doAA); 125 return this->setPath(path, tmp, doAA);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 * from its nearest int by < half of that value (1.8 in this case). 175 * from its nearest int by < half of that value (1.8 in this case).
269 */ 176 */
270 static bool nearly_integral(SkScalar x) { 177 static bool nearly_integral(SkScalar x) {
271 static const SkScalar domain = SK_Scalar1 / 4; 178 static const SkScalar domain = SK_Scalar1 / 4;
272 static const SkScalar halfDomain = domain / 2; 179 static const SkScalar halfDomain = domain / 2;
273 180
274 x += halfDomain; 181 x += halfDomain;
275 return x - SkScalarFloorToScalar(x) < domain; 182 return x - SkScalarFloorToScalar(x) < domain;
276 } 183 }
277 184
278 bool SkRasterClip::op(const SkRect& r, const SkISize& size, SkRegion::Op op, boo l doAA) { 185 bool SkRasterClip::op(const SkRect& r, SkRegion::Op op, bool doAA) {
279 AUTO_RASTERCLIP_VALIDATE(*this); 186 AUTO_RASTERCLIP_VALIDATE(*this);
280 187
281 if (fForceConservativeRects) {
282 SkIRect ir;
283 switch (mutate_conservative_op(&op, false)) {
284 case kDoNothing_MutateResult:
285 return !this->isEmpty();
286 case kReplaceClippedAgainstGlobalBounds_MutateResult:
287 ir = SkIRect::MakeSize(size);
288 break;
289 case kContinue_MutateResult:
290 r.roundOut(&ir);
291 break;
292 }
293 return this->op(ir, op);
294 }
295
296 if (fIsBW && doAA) { 188 if (fIsBW && doAA) {
297 // check that the rect really needs aa, or is it close enought to 189 // check that the rect really needs aa, or is it close enought to
298 // integer boundaries that we can just treat it as a BW rect? 190 // integer boundaries that we can just treat it as a BW rect?
299 if (nearly_integral(r.fLeft) && nearly_integral(r.fTop) && 191 if (nearly_integral(r.fLeft) && nearly_integral(r.fTop) &&
300 nearly_integral(r.fRight) && nearly_integral(r.fBottom)) { 192 nearly_integral(r.fRight) && nearly_integral(r.fBottom)) {
301 doAA = false; 193 doAA = false;
302 } 194 }
303 } 195 }
304 196
305 if (fIsBW && !doAA) { 197 if (fIsBW && !doAA) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 AUTO_RASTERCLIP_VALIDATE(*this); 244 AUTO_RASTERCLIP_VALIDATE(*this);
353 245
354 if (!fIsBW) { 246 if (!fIsBW) {
355 fBW.setRect(fAA.getBounds()); 247 fBW.setRect(fAA.getBounds());
356 } 248 }
357 return fBW; 249 return fBW;
358 } 250 }
359 251
360 void SkRasterClip::convertToAA() { 252 void SkRasterClip::convertToAA() {
361 AUTO_RASTERCLIP_VALIDATE(*this); 253 AUTO_RASTERCLIP_VALIDATE(*this);
362 254
363 SkASSERT(!fForceConservativeRects);
364
365 SkASSERT(fIsBW); 255 SkASSERT(fIsBW);
366 fAA.setRegion(fBW); 256 fAA.setRegion(fBW);
367 fIsBW = false; 257 fIsBW = false;
368 258
369 // since we are being explicitly asked to convert-to-aa, we pass false so we don't "optimize" 259 // since we are being explicitly asked to convert-to-aa, we pass false so we don't "optimize"
370 // ourselves back to BW. 260 // ourselves back to BW.
371 (void)this->updateCacheAndReturnNonEmpty(false); 261 (void)this->updateCacheAndReturnNonEmpty(false);
372 } 262 }
373 263
374 #ifdef SK_DEBUG 264 #ifdef SK_DEBUG
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 fBlitter = blitter; 306 fBlitter = blitter;
417 } else { 307 } else {
418 const SkAAClip& aaclip = clip.aaRgn(); 308 const SkAAClip& aaclip = clip.aaRgn();
419 fBWRgn.setRect(aaclip.getBounds()); 309 fBWRgn.setRect(aaclip.getBounds());
420 fAABlitter.init(blitter, &aaclip); 310 fAABlitter.init(blitter, &aaclip);
421 // now our return values 311 // now our return values
422 fClipRgn = &fBWRgn; 312 fClipRgn = &fBWRgn;
423 fBlitter = &fAABlitter; 313 fBlitter = &fAABlitter;
424 } 314 }
425 } 315 }
OLDNEW
« no previous file with comments | « src/core/SkRasterClip.h ('k') | src/core/SkRecorder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698