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

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

Issue 2067283003: Apply canonicalizations to path GrShapes. (Closed) Base URL: https://chromium.googlesource.com/skia.git@intermediate_grshape
Patch Set: fix indentation 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') | tests/GrShapeTest.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) {
(...skipping 14 matching lines...) Expand all
25 fRRectDir = that.fRRectDir; 25 fRRectDir = that.fRRectDir;
26 fRRectStart = that.fRRectStart; 26 fRRectStart = that.fRRectStart;
27 fRRectIsInverted = that.fRRectIsInverted; 27 fRRectIsInverted = that.fRRectIsInverted;
28 break; 28 break;
29 case Type::kPath: 29 case Type::kPath:
30 if (wasPath) { 30 if (wasPath) {
31 *fPath.get() = *that.fPath.get(); 31 *fPath.get() = *that.fPath.get();
32 } else { 32 } else {
33 fPath.set(*that.fPath.get()); 33 fPath.set(*that.fPath.get());
34 } 34 }
35 fPathGenID = that.fPathGenID;
35 break; 36 break;
36 } 37 }
37 fInheritedKey.reset(that.fInheritedKey.count()); 38 fInheritedKey.reset(that.fInheritedKey.count());
38 sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(), 39 sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(),
39 sizeof(uint32_t) * fInheritedKey.count()); 40 sizeof(uint32_t) * fInheritedKey.count());
40 return *this; 41 return *this;
41 } 42 }
42 43
43 const SkRect& GrShape::bounds() const { 44 const SkRect& GrShape::bounds() const {
44 static constexpr SkRect kEmpty = SkRect::MakeEmpty(); 45 static constexpr SkRect kEmpty = SkRect::MakeEmpty();
(...skipping 23 matching lines...) Expand all
68 } 69 }
69 switch (fType) { 70 switch (fType) {
70 case Type::kEmpty: 71 case Type::kEmpty:
71 return 1; 72 return 1;
72 case Type::kRRect: 73 case Type::kRRect:
73 SkASSERT(!fInheritedKey.count()); 74 SkASSERT(!fInheritedKey.count());
74 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t)); 75 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
75 // + 1 for the direction, start index, and inverseness. 76 // + 1 for the direction, start index, and inverseness.
76 return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1; 77 return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1;
77 case Type::kPath: 78 case Type::kPath:
78 if (fPath.get()->isVolatile()) { 79 if (0 == fPathGenID) {
79 return -1; 80 return -1;
80 } else { 81 } else {
81 // The key is the path ID and fill type. 82 // The key is the path ID and fill type.
82 return 2; 83 return 2;
83 } 84 }
84 } 85 }
85 SkFAIL("Should never get here."); 86 SkFAIL("Should never get here.");
86 return 0; 87 return 0;
87 } 88 }
88 89
(...skipping 10 matching lines...) Expand all
99 break; 100 break;
100 case Type::kRRect: 101 case Type::kRRect:
101 fRRect.writeToMemory(key); 102 fRRect.writeToMemory(key);
102 key += SkRRect::kSizeInMemory / sizeof(uint32_t); 103 key += SkRRect::kSizeInMemory / sizeof(uint32_t);
103 *key = (fRRectDir == SkPath::kCCW_Direction) ? (1 << 31) : 0; 104 *key = (fRRectDir == SkPath::kCCW_Direction) ? (1 << 31) : 0;
104 *key |= fRRectIsInverted ? (1 << 30) : 0; 105 *key |= fRRectIsInverted ? (1 << 30) : 0;
105 *key++ |= fRRectStart; 106 *key++ |= fRRectStart;
106 SkASSERT(fRRectStart < 8); 107 SkASSERT(fRRectStart < 8);
107 break; 108 break;
108 case Type::kPath: 109 case Type::kPath:
109 SkASSERT(!fPath.get()->isVolatile()); 110 SkASSERT(fPathGenID);
110 *key++ = fPath.get()->getGenerationID(); 111 *key++ = fPathGenID;
111 // We could canonicalize the fill rule for paths that don't diff erentiate between 112 // We could canonicalize the fill rule for paths that don't diff erentiate between
112 // even/odd or winding fill (e.g. convex). 113 // even/odd or winding fill (e.g. convex).
113 *key++ = fPath.get()->getFillType(); 114 *key++ = fPath.get()->getFillType();
114 break; 115 break;
115 } 116 }
116 } 117 }
117 SkASSERT(key - origKey == this->unstyledKeySize()); 118 SkASSERT(key - origKey == this->unstyledKeySize());
118 } 119 }
119 120
120 void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca lar scale) { 121 void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca lar scale) {
121 SkASSERT(!fInheritedKey.count()); 122 SkASSERT(!fInheritedKey.count());
122 // If the output shape turns out to be simple, then we will just use its geo metric key 123 // If the output shape turns out to be simple, then we will just use its geo metric key
123 if (Type::kPath == fType) { 124 if (Type::kPath == fType) {
124 // We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key a s 125 // We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key a s
125 // ApplyFullStyle(shape). 126 // ApplyFullStyle(shape).
126 // The full key is structured as (geo,path_effect,stroke). 127 // The full key is structured as (geo,path_effect,stroke).
127 // If we do ApplyPathEffect we get get,path_effect as the inherited key. If we then 128 // If we do ApplyPathEffect we get get,path_effect as the inherited key. If we then
128 // do ApplyFullStyle we'll memcpy geo,path_effect into the new inherited key 129 // do ApplyFullStyle we'll memcpy geo,path_effect into the new inherited key
129 // and then append the style key (which should now be stroke only) at th e end. 130 // and then append the style key (which should now be stroke only) at th e end.
130 int parentCnt = parent.fInheritedKey.count(); 131 int parentCnt = parent.fInheritedKey.count();
131 bool useParentGeoKey = !parentCnt; 132 bool useParentGeoKey = !parentCnt;
132 if (useParentGeoKey) { 133 if (useParentGeoKey) {
133 parentCnt = parent.unstyledKeySize(); 134 parentCnt = parent.unstyledKeySize();
134 if (parentCnt < 0) { 135 if (parentCnt < 0) {
135 // The parent's geometry has no key so we will have no key. 136 // The parent's geometry has no key so we will have no key.
136 fPath.get()->setIsVolatile(true); 137 fPathGenID = 0;
137 return; 138 return;
138 } 139 }
139 } 140 }
140 uint32_t styleKeyFlags = 0; 141 uint32_t styleKeyFlags = 0;
141 if (parent.knownToBeClosed()) { 142 if (parent.knownToBeClosed()) {
142 styleKeyFlags |= GrStyle::kClosed_KeyFlag; 143 styleKeyFlags |= GrStyle::kClosed_KeyFlag;
143 } 144 }
144 int styleCnt = GrStyle::KeySize(parent.fStyle, apply, styleKeyFlags); 145 int styleCnt = GrStyle::KeySize(parent.fStyle, apply, styleKeyFlags);
145 if (styleCnt < 0) { 146 if (styleCnt < 0) {
146 // The style doesn't allow a key, set the path to volatile so that w e fail when 147 // The style doesn't allow a key, set the path gen ID to 0 so that w e fail when
147 // we try to get a key for the shape. 148 // we try to get a key for the shape.
148 fPath.get()->setIsVolatile(true); 149 fPathGenID = 0;
149 return; 150 return;
150 } 151 }
151 fInheritedKey.reset(parentCnt + styleCnt); 152 fInheritedKey.reset(parentCnt + styleCnt);
152 if (useParentGeoKey) { 153 if (useParentGeoKey) {
153 // This will be the geo key. 154 // This will be the geo key.
154 parent.writeUnstyledKey(fInheritedKey.get()); 155 parent.writeUnstyledKey(fInheritedKey.get());
155 } else { 156 } else {
156 // This should be (geo,path_effect). 157 // This should be (geo,path_effect).
157 memcpy(fInheritedKey.get(), parent.fInheritedKey.get(), 158 memcpy(fInheritedKey.get(), parent.fInheritedKey.get(),
158 parentCnt * sizeof(uint32_t)); 159 parentCnt * sizeof(uint32_t));
159 } 160 }
160 // Now turn (geo,path_effect) or (geo) into (geo,path_effect,stroke) 161 // Now turn (geo,path_effect) or (geo) into (geo,path_effect,stroke)
161 GrStyle::WriteKey(fInheritedKey.get() + parentCnt, parent.fStyle, apply, scale, 162 GrStyle::WriteKey(fInheritedKey.get() + parentCnt, parent.fStyle, apply, scale,
162 styleKeyFlags); 163 styleKeyFlags);
163 } 164 }
164 } 165 }
165 166
166 GrShape::GrShape(const GrShape& that) : fType(that.fType), fStyle(that.fStyle) { 167 GrShape::GrShape(const GrShape& that) : fType(that.fType), fStyle(that.fStyle) {
167 switch (fType) { 168 switch (fType) {
168 case Type::kEmpty: 169 case Type::kEmpty:
169 return; 170 break;
170 case Type::kRRect: 171 case Type::kRRect:
171 fRRect = that.fRRect; 172 fRRect = that.fRRect;
172 fRRectDir = that.fRRectDir; 173 fRRectDir = that.fRRectDir;
173 fRRectStart = that.fRRectStart; 174 fRRectStart = that.fRRectStart;
174 fRRectIsInverted = that.fRRectIsInverted; 175 fRRectIsInverted = that.fRRectIsInverted;
175 return; 176 break;
176 case Type::kPath: 177 case Type::kPath:
177 fPath.set(*that.fPath.get()); 178 fPath.set(*that.fPath.get());
178 return; 179 fPathGenID = that.fPathGenID;
180 break;
179 } 181 }
180 fInheritedKey.reset(that.fInheritedKey.count()); 182 fInheritedKey.reset(that.fInheritedKey.count());
181 memcpy(fInheritedKey.get(), that.fInheritedKey.get(), 183 sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(),
182 sizeof(uint32_t) * fInheritedKey.count()); 184 sizeof(uint32_t) * fInheritedKey.count());
183 } 185 }
184 186
185 GrShape::GrShape(const GrShape& parent, GrStyle::Apply apply, SkScalar scale) { 187 GrShape::GrShape(const GrShape& parent, GrStyle::Apply apply, SkScalar scale) {
186 // TODO: Add some quantization of scale for better cache performance here or leave that up 188 // TODO: Add some quantization of scale for better cache performance here or leave that up
187 // to caller? 189 // to caller?
188 // TODO: For certain shapes and stroke params we could ignore the scale. (e. g. miter or bevel 190 // TODO: For certain shapes and stroke params we could ignore the scale. (e. g. miter or bevel
189 // stroke of a rect). 191 // stroke of a rect).
190 if (!parent.style().applies() || 192 if (!parent.style().applies() ||
191 (GrStyle::Apply::kPathEffectOnly == apply && !parent.style().pathEffect( ))) { 193 (GrStyle::Apply::kPathEffectOnly == apply && !parent.style().pathEffect( ))) {
192 fType = Type::kEmpty; 194 fType = Type::kEmpty;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 fType = Type::kRRect; 310 fType = Type::kRRect;
309 } 311 }
310 } 312 }
311 } 313 }
312 if (Type::kPath != fType) { 314 if (Type::kPath != fType) {
313 fPath.reset(); 315 fPath.reset();
314 fInheritedKey.reset(0); 316 fInheritedKey.reset(0);
315 if (Type::kRRect == fType) { 317 if (Type::kRRect == fType) {
316 this->attemptToSimplifyRRect(); 318 this->attemptToSimplifyRRect();
317 } 319 }
320 } else {
321 if (fInheritedKey.count() || fPath.get()->isVolatile()) {
322 fPathGenID = 0;
323 } else {
324 fPathGenID = fPath.get()->getGenerationID();
325 }
326 if (this->style().isSimpleFill()) {
327 // Filled paths are treated as though all their contours were closed .
328 // Since SkPath doesn't track individual contours, this will only cl ose the last. :(
329 // There is no point in closing lines, though, since they loose thei r line-ness.
bsalomon 2016/06/20 20:18:58 In the future we'll extract the line during simpli
330 if (!fPath.get()->isLine(nullptr)) {
331 fPath.get()->close();
332 fPath.get()->setIsVolatile(true);
333 }
334 }
335 if (fPath.get()->isConvex()) {
336 // There is no distinction between even/odd and non-zero winding cou nt for convex
337 // paths.
338 if (fPath.get()->isInverseFillType()) {
339 fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType);
340 } else {
341 fPath.get()->setFillType(SkPath::kEvenOdd_FillType);
342 }
343 }
344 if (this->style().isDashed()) {
345 // Dashing ignores inverseness (skbug.com/5421)
346 switch (fPath.get()->getFillType()) {
347 case SkPath::kWinding_FillType:
348 case SkPath::kEvenOdd_FillType:
349 break;
350 case SkPath::kInverseWinding_FillType:
351 fPath.get()->setFillType(SkPath::kWinding_FillType);
352 break;
353 case SkPath::kInverseEvenOdd_FillType:
354 fPath.get()->setFillType(SkPath::kEvenOdd_FillType);
355 break;
356 }
357 }
318 } 358 }
319 } 359 }
320 360
321 void GrShape::attemptToSimplifyRRect() { 361 void GrShape::attemptToSimplifyRRect() {
322 SkASSERT(Type::kRRect == fType); 362 SkASSERT(Type::kRRect == fType);
323 SkASSERT(!fInheritedKey.count()); 363 SkASSERT(!fInheritedKey.count());
324 if (fRRect.isEmpty()) { 364 if (fRRect.isEmpty()) {
325 fType = Type::kEmpty; 365 fType = Type::kEmpty;
326 return; 366 return;
327 } 367 }
328 if (!this->style().hasPathEffect()) { 368 if (!this->style().hasPathEffect()) {
329 fRRectDir = kDefaultRRectDir; 369 fRRectDir = kDefaultRRectDir;
330 fRRectStart = kDefaultRRectStart; 370 fRRectStart = kDefaultRRectStart;
331 } else if (fStyle.isDashed()) { 371 } else if (fStyle.isDashed()) {
332 // Dashing ignores the inverseness (currently). skbug.com/5421 372 // Dashing ignores the inverseness (currently). skbug.com/5421
333 fRRectIsInverted = false; 373 fRRectIsInverted = false;
334 } 374 }
335 } 375 }
OLDNEW
« no previous file with comments | « src/gpu/GrShape.h ('k') | tests/GrShapeTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698