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

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

Issue 2108523002: Make lines a special case in GrShape (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: reject empty shape in GrDC::internalDrawPath Created 4 years, 5 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/GrSoftwarePathRenderer.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 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 fStyle = that.fStyle; 11 fStyle = that.fStyle;
12 this->changeType(that.fType, Type::kPath == that.fType ? &that.path() : null ptr); 12 this->changeType(that.fType, Type::kPath == that.fType ? &that.path() : null ptr);
13 switch (fType) { 13 switch (fType) {
14 case Type::kEmpty: 14 case Type::kEmpty:
15 break; 15 break;
16 case Type::kRRect: 16 case Type::kRRect:
17 fRRectData.fRRect = that.fRRectData.fRRect; 17 fRRectData = that.fRRectData;
18 fRRectData.fDir = that.fRRectData.fDir; 18 break;
19 fRRectData.fStart = that.fRRectData.fStart; 19 case Type::kLine:
20 fRRectData.fInverted = that.fRRectData.fInverted; 20 fLineData = that.fLineData;
21 break; 21 break;
22 case Type::kPath: 22 case Type::kPath:
23 fPathData.fGenID = that.fPathData.fGenID; 23 fPathData.fGenID = that.fPathData.fGenID;
24 break; 24 break;
25 } 25 }
26 fInheritedKey.reset(that.fInheritedKey.count()); 26 fInheritedKey.reset(that.fInheritedKey.count());
27 sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(), 27 sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(),
28 sizeof(uint32_t) * fInheritedKey.count()); 28 sizeof(uint32_t) * fInheritedKey.count());
29 return *this; 29 return *this;
30 } 30 }
31 31
32 const SkRect& GrShape::bounds() const { 32 SkRect GrShape::bounds() const {
33 static constexpr SkRect kEmpty = SkRect::MakeEmpty(); 33 static constexpr SkRect kEmpty = SkRect::MakeEmpty();
34 switch (fType) { 34 switch (fType) {
35 case Type::kEmpty: 35 case Type::kEmpty:
36 return kEmpty; 36 return kEmpty;
37 case Type::kLine: {
38 SkRect bounds;
39 if (fLineData.fPts[0].fX < fLineData.fPts[1].fX) {
40 bounds.fLeft = fLineData.fPts[0].fX;
41 bounds.fRight = fLineData.fPts[1].fX;
42 } else {
43 bounds.fLeft = fLineData.fPts[1].fX;
44 bounds.fRight = fLineData.fPts[0].fX;
45 }
46 if (fLineData.fPts[0].fY < fLineData.fPts[1].fY) {
47 bounds.fTop = fLineData.fPts[0].fY;
48 bounds.fBottom = fLineData.fPts[1].fY;
49 } else {
50 bounds.fTop = fLineData.fPts[1].fY;
51 bounds.fBottom = fLineData.fPts[0].fY;
52 }
53 return bounds;
54 }
37 case Type::kRRect: 55 case Type::kRRect:
38 return fRRectData.fRRect.getBounds(); 56 return fRRectData.fRRect.getBounds();
39 case Type::kPath: 57 case Type::kPath:
40 return this->path().getBounds(); 58 return this->path().getBounds();
41 } 59 }
42 SkFAIL("Unknown shape type"); 60 SkFAIL("Unknown shape type");
43 return kEmpty; 61 return kEmpty;
44 } 62 }
45 63
46 void GrShape::styledBounds(SkRect* bounds) const { 64 SkRect GrShape::styledBounds() const {
47 if (Type::kEmpty == fType && !fStyle.hasNonDashPathEffect()) { 65 if (Type::kEmpty == fType && !fStyle.hasNonDashPathEffect()) {
48 *bounds = SkRect::MakeEmpty(); 66 return SkRect::MakeEmpty();
49 } else {
50 fStyle.adjustBounds(bounds, this->bounds());
51 } 67 }
68 SkRect bounds;
69 fStyle.adjustBounds(&bounds, this->bounds());
70 return bounds;
52 } 71 }
53 72
54 int GrShape::unstyledKeySize() const { 73 int GrShape::unstyledKeySize() const {
55 if (fInheritedKey.count()) { 74 if (fInheritedKey.count()) {
56 return fInheritedKey.count(); 75 return fInheritedKey.count();
57 } 76 }
58 switch (fType) { 77 switch (fType) {
59 case Type::kEmpty: 78 case Type::kEmpty:
60 return 1; 79 return 1;
61 case Type::kRRect: 80 case Type::kRRect:
62 SkASSERT(!fInheritedKey.count()); 81 SkASSERT(!fInheritedKey.count());
63 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t)); 82 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
64 // + 1 for the direction, start index, and inverseness. 83 // + 1 for the direction, start index, and inverseness.
65 return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1; 84 return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1;
85 case Type::kLine:
86 GR_STATIC_ASSERT(2 * sizeof(uint32_t) == sizeof(SkPoint));
87 // 4 for the end points and 1 for the inverseness
88 return 5;
66 case Type::kPath: 89 case Type::kPath:
67 if (0 == fPathData.fGenID) { 90 if (0 == fPathData.fGenID) {
68 return -1; 91 return -1;
69 } else { 92 } else {
70 // The key is the path ID and fill type. 93 // The key is the path ID and fill type.
71 return 2; 94 return 2;
72 } 95 }
73 } 96 }
74 SkFAIL("Should never get here."); 97 SkFAIL("Should never get here.");
75 return 0; 98 return 0;
(...skipping 11 matching lines...) Expand all
87 *key++ = 1; 110 *key++ = 1;
88 break; 111 break;
89 case Type::kRRect: 112 case Type::kRRect:
90 fRRectData.fRRect.writeToMemory(key); 113 fRRectData.fRRect.writeToMemory(key);
91 key += SkRRect::kSizeInMemory / sizeof(uint32_t); 114 key += SkRRect::kSizeInMemory / sizeof(uint32_t);
92 *key = (fRRectData.fDir == SkPath::kCCW_Direction) ? (1 << 31) : 0; 115 *key = (fRRectData.fDir == SkPath::kCCW_Direction) ? (1 << 31) : 0;
93 *key |= fRRectData.fInverted ? (1 << 30) : 0; 116 *key |= fRRectData.fInverted ? (1 << 30) : 0;
94 *key++ |= fRRectData.fStart; 117 *key++ |= fRRectData.fStart;
95 SkASSERT(fRRectData.fStart < 8); 118 SkASSERT(fRRectData.fStart < 8);
96 break; 119 break;
120 case Type::kLine:
121 memcpy(key, fLineData.fPts, 2 * sizeof(SkPoint));
122 key += 4;
123 *key++ = fLineData.fInverted ? 1 : 0;
124 break;
97 case Type::kPath: 125 case Type::kPath:
98 SkASSERT(fPathData.fGenID); 126 SkASSERT(fPathData.fGenID);
99 *key++ = fPathData.fGenID; 127 *key++ = fPathData.fGenID;
100 // We could canonicalize the fill rule for paths that don't diff erentiate between 128 // We could canonicalize the fill rule for paths that don't diff erentiate between
101 // even/odd or winding fill (e.g. convex). 129 // even/odd or winding fill (e.g. convex).
102 *key++ = this->path().getFillType(); 130 *key++ = this->path().getFillType();
103 break; 131 break;
104 } 132 }
105 } 133 }
106 SkASSERT(key - origKey == this->unstyledKeySize()); 134 SkASSERT(key - origKey == this->unstyledKeySize());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 } 180 }
153 } 181 }
154 182
155 GrShape::GrShape(const GrShape& that) : fStyle(that.fStyle) { 183 GrShape::GrShape(const GrShape& that) : fStyle(that.fStyle) {
156 const SkPath* thatPath = Type::kPath == that.fType ? &that.fPathData.fPath : nullptr; 184 const SkPath* thatPath = Type::kPath == that.fType ? &that.fPathData.fPath : nullptr;
157 this->initType(that.fType, thatPath); 185 this->initType(that.fType, thatPath);
158 switch (fType) { 186 switch (fType) {
159 case Type::kEmpty: 187 case Type::kEmpty:
160 break; 188 break;
161 case Type::kRRect: 189 case Type::kRRect:
162 fRRectData.fRRect = that.fRRectData.fRRect; 190 fRRectData = that.fRRectData;
163 fRRectData.fDir = that.fRRectData.fDir; 191 break;
164 fRRectData.fStart = that.fRRectData.fStart; 192 case Type::kLine:
165 fRRectData.fInverted = that.fRRectData.fInverted; 193 fLineData = that.fLineData;
166 break; 194 break;
167 case Type::kPath: 195 case Type::kPath:
168 fPathData.fGenID = that.fPathData.fGenID; 196 fPathData.fGenID = that.fPathData.fGenID;
169 break; 197 break;
170 } 198 }
171 fInheritedKey.reset(that.fInheritedKey.count()); 199 fInheritedKey.reset(that.fInheritedKey.count());
172 sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(), 200 sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(),
173 sizeof(uint32_t) * fInheritedKey.count()); 201 sizeof(uint32_t) * fInheritedKey.count());
174 } 202 }
175 203
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 this->attemptToSimplifyPath(); 287 this->attemptToSimplifyPath();
260 this->setInheritedKey(*parentForKey, apply, scale); 288 this->setInheritedKey(*parentForKey, apply, scale);
261 } 289 }
262 290
263 void GrShape::attemptToSimplifyPath() { 291 void GrShape::attemptToSimplifyPath() {
264 SkRect rect; 292 SkRect rect;
265 SkRRect rrect; 293 SkRRect rrect;
266 SkPath::Direction rrectDir; 294 SkPath::Direction rrectDir;
267 unsigned rrectStart; 295 unsigned rrectStart;
268 bool inverted = this->path().isInverseFillType(); 296 bool inverted = this->path().isInverseFillType();
297 SkPoint pts[2];
269 if (this->path().isEmpty()) { 298 if (this->path().isEmpty()) {
270 this->changeType(Type::kEmpty); 299 this->changeType(Type::kEmpty);
300 } else if (this->path().isLine(pts)) {
301 this->changeType(Type::kLine);
302 fLineData.fPts[0] = pts[0];
303 fLineData.fPts[1] = pts[1];
304 fLineData.fInverted = inverted;
271 } else if (this->path().isRRect(&rrect, &rrectDir, &rrectStart)) { 305 } else if (this->path().isRRect(&rrect, &rrectDir, &rrectStart)) {
272 this->changeType(Type::kRRect); 306 this->changeType(Type::kRRect);
273 fRRectData.fRRect = rrect; 307 fRRectData.fRRect = rrect;
274 fRRectData.fDir = rrectDir; 308 fRRectData.fDir = rrectDir;
275 fRRectData.fStart = rrectStart; 309 fRRectData.fStart = rrectStart;
276 fRRectData.fInverted = inverted; 310 fRRectData.fInverted = inverted;
277 // Currently SkPath does not acknowledge that empty, rect, or oval subty pes as rrects. 311 // Currently SkPath does not acknowledge that empty, rect, or oval subty pes as rrects.
278 SkASSERT(!fRRectData.fRRect.isEmpty()); 312 SkASSERT(!fRRectData.fRRect.isEmpty());
279 SkASSERT(fRRectData.fRRect.getType() != SkRRect::kRect_Type); 313 SkASSERT(fRRectData.fRRect.getType() != SkRRect::kRect_Type);
280 SkASSERT(fRRectData.fRRect.getType() != SkRRect::kOval_Type); 314 SkASSERT(fRRectData.fRRect.getType() != SkRRect::kOval_Type);
(...skipping 25 matching lines...) Expand all
306 fRRectData.fStart = kDefaultRRectStart; 340 fRRectData.fStart = kDefaultRRectStart;
307 // There isn't dashing so we will have to preserver inverseness. 341 // There isn't dashing so we will have to preserver inverseness.
308 fRRectData.fInverted = inverted; 342 fRRectData.fInverted = inverted;
309 } 343 }
310 } 344 }
311 } 345 }
312 if (Type::kPath != fType) { 346 if (Type::kPath != fType) {
313 fInheritedKey.reset(0); 347 fInheritedKey.reset(0);
314 if (Type::kRRect == fType) { 348 if (Type::kRRect == fType) {
315 this->attemptToSimplifyRRect(); 349 this->attemptToSimplifyRRect();
350 } else if (Type::kLine == fType) {
351 this->attemptToSimplifyLine();
316 } 352 }
317 } else { 353 } else {
318 if (fInheritedKey.count() || this->path().isVolatile()) { 354 if (fInheritedKey.count() || this->path().isVolatile()) {
319 fPathData.fGenID = 0; 355 fPathData.fGenID = 0;
320 } else { 356 } else {
321 fPathData.fGenID = this->path().getGenerationID(); 357 fPathData.fGenID = this->path().getGenerationID();
322 } 358 }
323 if (this->style().isSimpleFill()) { 359 if (this->style().isSimpleFill()) {
324 // Filled paths are treated as though all their contours were closed . 360 this->path().close();
325 // Since SkPath doesn't track individual contours, this will only cl ose the last. :( 361 this->path().setIsVolatile(true);
326 // There is no point in closing lines, though, since they loose thei r line-ness.
327 if (!this->path().isLine(nullptr)) {
328 this->path().close();
329 this->path().setIsVolatile(true);
330 }
331 } 362 }
332 if (!this->style().hasNonDashPathEffect()) { 363 if (!this->style().hasNonDashPathEffect()) {
333 if (this->style().strokeRec().getStyle() == SkStrokeRec::kStroke_Sty le || 364 if (this->style().strokeRec().getStyle() == SkStrokeRec::kStroke_Sty le ||
334 this->style().strokeRec().getStyle() == SkStrokeRec::kHairline_S tyle) { 365 this->style().strokeRec().getStyle() == SkStrokeRec::kHairline_S tyle) {
335 // Stroke styles don't differentiate between winding and even/od d. 366 // Stroke styles don't differentiate between winding and even/od d.
336 // Moreover, dashing ignores inverseness (skbug.com/5421) 367 // Moreover, dashing ignores inverseness (skbug.com/5421)
337 bool inverse = !this->style().isDashed() && this->path().isInver seFillType(); 368 bool inverse = !this->style().isDashed() && this->path().isInver seFillType();
338 if (inverse) { 369 if (inverse) {
339 this->path().setFillType(kDefaultPathInverseFillType); 370 this->path().setFillType(kDefaultPathInverseFillType);
340 } else { 371 } else {
(...skipping 20 matching lines...) Expand all
361 return; 392 return;
362 } 393 }
363 if (!this->style().hasPathEffect()) { 394 if (!this->style().hasPathEffect()) {
364 fRRectData.fDir = kDefaultRRectDir; 395 fRRectData.fDir = kDefaultRRectDir;
365 fRRectData.fStart = kDefaultRRectStart; 396 fRRectData.fStart = kDefaultRRectStart;
366 } else if (fStyle.isDashed()) { 397 } else if (fStyle.isDashed()) {
367 // Dashing ignores the inverseness (currently). skbug.com/5421 398 // Dashing ignores the inverseness (currently). skbug.com/5421
368 fRRectData.fInverted = false; 399 fRRectData.fInverted = false;
369 } 400 }
370 } 401 }
402
403 void GrShape::attemptToSimplifyLine() {
404 if (fStyle.isSimpleFill() && !fLineData.fInverted) {
405 this->changeType(Type::kEmpty);
406 } else {
407 // Only path effects could care about the order of the points. Otherwise canonicalize
408 // the point order
409 if (!fStyle.hasPathEffect()) {
410 SkPoint* pts = fLineData.fPts;
411 if (pts[1].fY < pts[0].fY || (pts[1].fY == pts[0].fY && pts[1].fX < pts[0].fX)) {
412 SkTSwap(pts[0], pts[1]);
413 }
414 } else if (fStyle.isDashed()) {
415 // Dashing ignores inverseness.
416 fLineData.fInverted = false;
417 }
418 }
419 }
OLDNEW
« no previous file with comments | « src/gpu/GrShape.h ('k') | src/gpu/GrSoftwarePathRenderer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698