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

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

Powered by Google App Engine
This is Rietveld 408576698