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

Side by Side Diff: src/gpu/GrShape.cpp

Issue 2042813002: Make GrShape track the winding direction and starting point for rrect types. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Fix more MSVS warnings Created 4 years, 6 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/gpu/GrShape.h ('k') | src/gpu/GrStyle.h » ('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 2016 Google Inc. 2 * Copyright 2016 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 "GrShape.h" 8 #include "GrShape.h"
9 9
10 GrShape& GrShape::operator=(const GrShape& that) { 10 GrShape& GrShape::operator=(const GrShape& that) {
11 bool wasPath = Type::kPath == fType; 11 bool wasPath = Type::kPath == fType;
12 fStyle = that.fStyle; 12 fStyle = that.fStyle;
13 fType = that.fType; 13 fType = that.fType;
14 switch (fType) { 14 switch (fType) {
15 case Type::kEmpty: 15 case Type::kEmpty:
16 if (wasPath) { 16 if (wasPath) {
17 fPath.reset(); 17 fPath.reset();
18 } 18 }
19 break; 19 break;
20 case Type::kRRect: 20 case Type::kRRect:
21 if (wasPath) { 21 if (wasPath) {
22 fPath.reset(); 22 fPath.reset();
23 } 23 }
24 fRRect = that.fRRect; 24 fRRect = that.fRRect;
25 fRRectDir = that.fRRectDir;
26 fRRectStart = that.fRRectStart;
25 break; 27 break;
26 case Type::kPath: 28 case Type::kPath:
27 if (wasPath) { 29 if (wasPath) {
28 *fPath.get() = *that.fPath.get(); 30 *fPath.get() = *that.fPath.get();
29 } else { 31 } else {
30 fPath.set(*that.fPath.get()); 32 fPath.set(*that.fPath.get());
31 } 33 }
32 break; 34 break;
33 } 35 }
34 fInheritedKey.reset(that.fInheritedKey.count()); 36 fInheritedKey.reset(that.fInheritedKey.count());
(...skipping 27 matching lines...) Expand all
62 int GrShape::unstyledKeySize() const { 64 int GrShape::unstyledKeySize() const {
63 if (fInheritedKey.count()) { 65 if (fInheritedKey.count()) {
64 return fInheritedKey.count(); 66 return fInheritedKey.count();
65 } 67 }
66 switch (fType) { 68 switch (fType) {
67 case Type::kEmpty: 69 case Type::kEmpty:
68 return 1; 70 return 1;
69 case Type::kRRect: 71 case Type::kRRect:
70 SkASSERT(!fInheritedKey.count()); 72 SkASSERT(!fInheritedKey.count());
71 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t)); 73 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
72 return SkRRect::kSizeInMemory / sizeof(uint32_t); 74 // + 1 for the direction + start index.
75 return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1;
73 case Type::kPath: 76 case Type::kPath:
74 if (fPath.get()->isVolatile()) { 77 if (fPath.get()->isVolatile()) {
75 return -1; 78 return -1;
76 } else { 79 } else {
77 return 1; 80 return 1;
78 } 81 }
79 } 82 }
80 SkFAIL("Should never get here."); 83 SkFAIL("Should never get here.");
81 return 0; 84 return 0;
82 } 85 }
83 86
84 void GrShape::writeUnstyledKey(uint32_t* key) const { 87 void GrShape::writeUnstyledKey(uint32_t* key) const {
85 SkASSERT(this->unstyledKeySize()); 88 SkASSERT(this->unstyledKeySize());
86 SkDEBUGCODE(uint32_t* origKey = key;) 89 SkDEBUGCODE(uint32_t* origKey = key;)
87 if (fInheritedKey.count()) { 90 if (fInheritedKey.count()) {
88 memcpy(key, fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count( )); 91 memcpy(key, fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count( ));
89 SkDEBUGCODE(key += fInheritedKey.count();) 92 SkDEBUGCODE(key += fInheritedKey.count();)
90 } else { 93 } else {
91 switch (fType) { 94 switch (fType) {
92 case Type::kEmpty: 95 case Type::kEmpty:
93 *key++ = 1; 96 *key++ = 1;
94 break; 97 break;
95 case Type::kRRect: 98 case Type::kRRect:
96 fRRect.writeToMemory(key); 99 fRRect.writeToMemory(key);
97 key += SkRRect::kSizeInMemory / sizeof(uint32_t); 100 key += SkRRect::kSizeInMemory / sizeof(uint32_t);
101 *key = (fRRectDir == SkPath::kCCW_Direction) ? (1 << 31) : 0;
102 *key++ |= fRRectStart;
103 SkASSERT(fRRectStart < 8);
98 break; 104 break;
99 case Type::kPath: 105 case Type::kPath:
100 SkASSERT(!fPath.get()->isVolatile()); 106 SkASSERT(!fPath.get()->isVolatile());
101 *key++ = fPath.get()->getGenerationID(); 107 *key++ = fPath.get()->getGenerationID();
102 break; 108 break;
103 } 109 }
104 } 110 }
105 SkASSERT(key - origKey == this->unstyledKeySize()); 111 SkASSERT(key - origKey == this->unstyledKeySize());
106 } 112 }
107 113
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 if (GrStyle::Apply::kPathEffectAndStrokeRec == apply) { 216 if (GrStyle::Apply::kPathEffectAndStrokeRec == apply) {
211 if (strokeRec.needToApply()) { 217 if (strokeRec.needToApply()) {
212 // The intermediate shape may not be a general path. If we we're just applying 218 // The intermediate shape may not be a general path. If we we're just applying
213 // the path effect then attemptToReduceFromPath would catch it. This means that 219 // the path effect then attemptToReduceFromPath would catch it. This means that
214 // when we subsequently applied the remaining strokeRec we would have a non-path 220 // when we subsequently applied the remaining strokeRec we would have a non-path
215 // parent shape that would be used to determine the the stroked path's key. 221 // parent shape that would be used to determine the the stroked path's key.
216 // We detect that case here and change parentForKey to a tempora ry that represents 222 // We detect that case here and change parentForKey to a tempora ry that represents
217 // the simpler shape so that applying both path effect and the s trokerec all at 223 // the simpler shape so that applying both path effect and the s trokerec all at
218 // once produces the same key. 224 // once produces the same key.
219 SkRRect rrect; 225 SkRRect rrect;
220 Type parentType = AttemptToReduceFromPathImpl(*fPath.get(), &rre ct, nullptr, 226 SkPath::Direction dir;
221 strokeRec); 227 unsigned start;
228 Type parentType = AttemptToReduceFromPathImpl(*fPath.get(), &rre ct, &dir, &start,
229 nullptr, strokeRec );
222 switch (parentType) { 230 switch (parentType) {
223 case Type::kEmpty: 231 case Type::kEmpty:
224 tmpParent.init(); 232 tmpParent.init();
225 parentForKey = tmpParent.get(); 233 parentForKey = tmpParent.get();
226 break; 234 break;
227 case Type::kRRect: 235 case Type::kRRect:
228 tmpParent.init(rrect, GrStyle(strokeRec, nullptr)); 236 tmpParent.init(rrect, dir, start, GrStyle(strokeRec, nul lptr));
229 parentForKey = tmpParent.get(); 237 parentForKey = tmpParent.get();
230 case Type::kPath: 238 case Type::kPath:
231 break; 239 break;
232 } 240 }
233 SkAssertResult(strokeRec.applyToPath(fPath.get(), *fPath.get())) ; 241 SkAssertResult(strokeRec.applyToPath(fPath.get(), *fPath.get())) ;
234 } else { 242 } else {
235 fStyle = GrStyle(strokeRec, nullptr); 243 fStyle = GrStyle(strokeRec, nullptr);
236 } 244 }
237 } else { 245 } else {
238 fStyle = GrStyle(strokeRec, nullptr); 246 fStyle = GrStyle(strokeRec, nullptr);
239 } 247 }
240 } else { 248 } else {
241 const SkPath* srcForParentStyle; 249 const SkPath* srcForParentStyle;
242 if (parent.fType == Type::kPath) { 250 if (parent.fType == Type::kPath) {
243 srcForParentStyle = parent.fPath.get(); 251 srcForParentStyle = parent.fPath.get();
244 } else { 252 } else {
245 srcForParentStyle = tmpPath.init(); 253 srcForParentStyle = tmpPath.init();
246 parent.asPath(tmpPath.get()); 254 parent.asPath(tmpPath.get());
247 } 255 }
248 SkStrokeRec::InitStyle fillOrHairline; 256 SkStrokeRec::InitStyle fillOrHairline;
249 SkASSERT(parent.fStyle.applies()); 257 SkASSERT(parent.fStyle.applies());
250 SkASSERT(!parent.fStyle.pathEffect()); 258 SkASSERT(!parent.fStyle.pathEffect());
251 SkAssertResult(parent.fStyle.applyToPath(fPath.get(), &fillOrHairline, * srcForParentStyle, 259 SkAssertResult(parent.fStyle.applyToPath(fPath.get(), &fillOrHairline, * srcForParentStyle,
252 scale)); 260 scale));
253 fStyle.resetToInitStyle(fillOrHairline); 261 fStyle.resetToInitStyle(fillOrHairline);
254 } 262 }
255 this->attemptToReduceFromPath(); 263 this->attemptToReduceFromPath();
256 this->setInheritedKey(*parentForKey, apply, scale); 264 this->setInheritedKey(*parentForKey, apply, scale);
257 } 265 }
266
267 GrShape::Type GrShape::AttemptToReduceFromPathImpl(const SkPath& path, SkRRect* rrect,
268 SkPath::Direction* rrectDir,
269 unsigned* rrectStart,
270 const SkPathEffect* pe,
271 const SkStrokeRec& strokeRec) {
272 if (path.isEmpty()) {
273 return Type::kEmpty;
274 }
275 if (path.isRRect(rrect, rrectDir, rrectStart)) {
276 // Currently SkPath does not acknowledge that empty, rect, or oval subty pes as rrects.
277 SkASSERT(!rrect->isEmpty());
278 SkASSERT(rrect->getType() != SkRRect::kRect_Type);
279 SkASSERT(rrect->getType() != SkRRect::kOval_Type);
280 if (!pe) {
281 *rrectStart = DefaultRRectDirAndStartIndex(*rrect, false, rrectDir);
282 }
283 return Type::kRRect;
284 }
285 SkRect rect;
286 if (path.isOval(&rect, rrectDir, rrectStart)) {
287 rrect->setOval(rect);
288 if (!pe) {
289 *rrectDir = kDefaultRRectDir;
290 *rrectStart = kDefaultRRectStart;
291 } else {
292 // convert from oval indexing to rrect indexiing.
293 *rrectStart *= 2;
294 }
295 return Type::kRRect;
296 }
297 // When there is a path effect we restrict rect detection to the narrower AP I that
298 // gives us the starting position. Otherwise, we will retry with the more ag gressive isRect().
299 if (SkPathPriv::IsSimpleClosedRect(path, &rect, rrectDir, rrectStart)) {
300 if (!pe) {
301 *rrectDir = kDefaultRRectDir;
302 *rrectStart = kDefaultRRectStart;
303 } else {
304 // convert from rect indexing to rrect indexiing.
305 *rrectStart *= 2;
306 }
307 rrect->setRect(rect);
308 return Type::kRRect;
309 }
310 if (!pe) {
311 bool closed;
312 if (path.isRect(&rect, &closed, nullptr)) {
313 if (closed || strokeRec.isFillStyle()) {
314 rrect->setRect(rect);
315 // Since there is no path effect the dir and start index is imma terial.
316 *rrectDir = kDefaultRRectDir;
317 *rrectStart = kDefaultRRectStart;
318 return Type::kRRect;
319 }
320 }
321 }
322 return Type::kPath;
323 }
OLDNEW
« no previous file with comments | « src/gpu/GrShape.h ('k') | src/gpu/GrStyle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698