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

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

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/GrDrawContext.cpp ('k') | src/gpu/GrShape.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 #ifndef GrShape_DEFINED 8 #ifndef GrShape_DEFINED
9 #define GrShape_DEFINED 9 #define GrShape_DEFINED
10 10
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 if (inverted) { 145 if (inverted) {
146 *inverted = fRRectData.fInverted; 146 *inverted = fRRectData.fInverted;
147 } 147 }
148 return true; 148 return true;
149 } 149 }
150 150
151 /** 151 /**
152 * If the unstyled shape is a straight line segment, returns true and sets p ts to the endpoints. 152 * If the unstyled shape is a straight line segment, returns true and sets p ts to the endpoints.
153 * An inverse filled line path is still considered a line. 153 * An inverse filled line path is still considered a line.
154 */ 154 */
155 bool asLine(SkPoint pts[2]) const { 155 bool asLine(SkPoint pts[2], bool* inverted) const {
156 if (fType != Type::kPath) { 156 if (fType != Type::kLine) {
157 return false; 157 return false;
158 } 158 }
159 return this->path().isLine(pts); 159 if (pts) {
160 } 160 pts[0] = fLineData.fPts[0];
161 pts[1] = fLineData.fPts[1];
162 }
163 if (inverted) {
164 *inverted = fLineData.fInverted;
165 }
166 return true;
167 }
161 168
162 /** Returns the unstyled geometry as a path. */ 169 /** Returns the unstyled geometry as a path. */
163 void asPath(SkPath* out) const { 170 void asPath(SkPath* out) const {
164 switch (fType) { 171 switch (fType) {
165 case Type::kEmpty: 172 case Type::kEmpty:
166 out->reset(); 173 out->reset();
167 break; 174 break;
168 case Type::kRRect: 175 case Type::kRRect:
169 out->reset(); 176 out->reset();
170 out->addRRect(fRRectData.fRRect, fRRectData.fDir, fRRectData.fSt art); 177 out->addRRect(fRRectData.fRRect, fRRectData.fDir, fRRectData.fSt art);
171 // Below matches the fill type that attemptToSimplifyPath uses. 178 // Below matches the fill type that attemptToSimplifyPath uses.
172 if (fRRectData.fInverted) { 179 if (fRRectData.fInverted) {
173 out->setFillType(kDefaultPathInverseFillType); 180 out->setFillType(kDefaultPathInverseFillType);
174 } else { 181 } else {
175 out->setFillType(kDefaultPathFillType); 182 out->setFillType(kDefaultPathFillType);
176 } 183 }
177 break; 184 break;
185 case Type::kLine:
186 out->reset();
187 out->moveTo(fLineData.fPts[0]);
188 out->lineTo(fLineData.fPts[1]);
189 if (fLineData.fInverted) {
190 out->setFillType(kDefaultPathInverseFillType);
191 } else {
192 out->setFillType(kDefaultPathFillType);
193 }
194 break;
178 case Type::kPath: 195 case Type::kPath:
179 *out = this->path(); 196 *out = this->path();
180 break; 197 break;
181 } 198 }
182 } 199 }
183 200
184 /** 201 /**
185 * Returns whether the geometry is empty. Note that applying the style could produce a 202 * Returns whether the geometry is empty. Note that applying the style could produce a
186 * non-empty shape. 203 * non-empty shape.
187 */ 204 */
188 bool isEmpty() const { return Type::kEmpty == fType; } 205 bool isEmpty() const { return Type::kEmpty == fType; }
189 206
190 /** 207 /**
191 * Gets the bounds of the geometry without reflecting the shape's styling. T his ignores 208 * Gets the bounds of the geometry without reflecting the shape's styling. T his ignores
192 * the inverse fill nature of the geometry. 209 * the inverse fill nature of the geometry.
193 */ 210 */
194 const SkRect& bounds() const; 211 SkRect bounds() const;
195 212
196 /** 213 /**
197 * Gets the bounds of the geometry reflecting the shape's styling (ignoring inverse fill 214 * Gets the bounds of the geometry reflecting the shape's styling (ignoring inverse fill
198 * status). 215 * status).
199 */ 216 */
200 void styledBounds(SkRect* bounds) const; 217 SkRect styledBounds() const;
201 218
202 /** 219 /**
203 * Is this shape known to be convex, before styling is applied. An unclosed but otherwise 220 * Is this shape known to be convex, before styling is applied. An unclosed but otherwise
204 * convex path is considered to be closed if they styling reflects a fill an d not otherwise. 221 * convex path is considered to be closed if they styling reflects a fill an d not otherwise.
205 * This is because filling closes all contours in the path. 222 * This is because filling closes all contours in the path.
206 */ 223 */
207 bool knownToBeConvex() const { 224 bool knownToBeConvex() const {
208 switch (fType) { 225 switch (fType) {
209 case Type::kEmpty: 226 case Type::kEmpty:
210 return true; 227 return true;
211 case Type::kRRect: 228 case Type::kRRect:
212 return true; 229 return true;
230 case Type::kLine:
231 return true;
213 case Type::kPath: 232 case Type::kPath:
214 // SkPath.isConvex() really means "is this path convex were it t o be closed" and 233 // SkPath.isConvex() really means "is this path convex were it t o be closed" and
215 // thus doesn't give the correct answer for stroked paths, hence we also check 234 // thus doesn't give the correct answer for stroked paths, hence we also check
216 // whether the path is either filled or closed. Convex paths may only have one 235 // whether the path is either filled or closed. Convex paths may only have one
217 // contour hence isLastContourClosed() is a sufficient for a con vex path. 236 // contour hence isLastContourClosed() is a sufficient for a con vex path.
218 return (this->style().isSimpleFill() || this->path().isLastConto urClosed()) && 237 return (this->style().isSimpleFill() || this->path().isLastConto urClosed()) &&
219 this->path().isConvex(); 238 this->path().isConvex();
220 } 239 }
221 return false; 240 return false;
222 } 241 }
223 242
224 /** Is the pre-styled geometry inverse filled? */ 243 /** Is the pre-styled geometry inverse filled? */
225 bool inverseFilled() const { 244 bool inverseFilled() const {
226 bool ret = false; 245 bool ret = false;
227 switch (fType) { 246 switch (fType) {
228 case Type::kEmpty: 247 case Type::kEmpty:
229 ret = false; 248 ret = false;
230 break; 249 break;
231 case Type::kRRect: 250 case Type::kRRect:
232 ret = fRRectData.fInverted; 251 ret = fRRectData.fInverted;
233 break; 252 break;
253 case Type::kLine:
254 ret = fLineData.fInverted;
255 break;
234 case Type::kPath: 256 case Type::kPath:
235 ret = this->path().isInverseFillType(); 257 ret = this->path().isInverseFillType();
236 break; 258 break;
237 } 259 }
238 // Dashing ignores inverseness. We should have caught this earlier. skbu g.com/5421 260 // Dashing ignores inverseness. We should have caught this earlier. skbu g.com/5421
239 SkASSERT(!(ret && this->style().isDashed())); 261 SkASSERT(!(ret && this->style().isDashed()));
240 return ret; 262 return ret;
241 } 263 }
242 264
243 /** 265 /**
(...skipping 13 matching lines...) Expand all
257 /** 279 /**
258 * Is it known that the unstyled geometry has no unclosed contours. This mea ns that it will 280 * Is it known that the unstyled geometry has no unclosed contours. This mea ns that it will
259 * not have any caps if stroked (modulo the effect of any path effect). 281 * not have any caps if stroked (modulo the effect of any path effect).
260 */ 282 */
261 bool knownToBeClosed() const { 283 bool knownToBeClosed() const {
262 switch (fType) { 284 switch (fType) {
263 case Type::kEmpty: 285 case Type::kEmpty:
264 return true; 286 return true;
265 case Type::kRRect: 287 case Type::kRRect:
266 return true; 288 return true;
289 case Type::kLine:
290 return false;
267 case Type::kPath: 291 case Type::kPath:
268 // SkPath doesn't keep track of the closed status of each contou r. 292 // SkPath doesn't keep track of the closed status of each contou r.
269 return SkPathPriv::IsClosedSingleContour(this->path()); 293 return SkPathPriv::IsClosedSingleContour(this->path());
270 } 294 }
271 return false; 295 return false;
272 } 296 }
273 297
274 uint32_t segmentMask() const { 298 uint32_t segmentMask() const {
275 switch (fType) { 299 switch (fType) {
276 case Type::kEmpty: 300 case Type::kEmpty:
277 return 0; 301 return 0;
278 case Type::kRRect: 302 case Type::kRRect:
279 if (fRRectData.fRRect.getType() == SkRRect::kOval_Type) { 303 if (fRRectData.fRRect.getType() == SkRRect::kOval_Type) {
280 return SkPath::kConic_SegmentMask; 304 return SkPath::kConic_SegmentMask;
281 } else if (fRRectData.fRRect.getType() == SkRRect::kRect_Type) { 305 } else if (fRRectData.fRRect.getType() == SkRRect::kRect_Type) {
282 return SkPath::kLine_SegmentMask; 306 return SkPath::kLine_SegmentMask;
283 } 307 }
284 return SkPath::kLine_SegmentMask | SkPath::kConic_SegmentMask; 308 return SkPath::kLine_SegmentMask | SkPath::kConic_SegmentMask;
309 case Type::kLine:
310 return SkPath::kLine_SegmentMask;
285 case Type::kPath: 311 case Type::kPath:
286 return this->path().getSegmentMasks(); 312 return this->path().getSegmentMasks();
287 } 313 }
288 return 0; 314 return 0;
289 } 315 }
290 316
291 /** 317 /**
292 * Gets the size of the key for the shape represented by this GrShape (ignor ing its styling). 318 * Gets the size of the key for the shape represented by this GrShape (ignor ing its styling).
293 * A negative value is returned if the shape has no key (shouldn't be cached ). 319 * A negative value is returned if the shape has no key (shouldn't be cached ).
294 */ 320 */
295 int unstyledKeySize() const; 321 int unstyledKeySize() const;
296 322
297 bool hasUnstyledKey() const { return this->unstyledKeySize() >= 0; } 323 bool hasUnstyledKey() const { return this->unstyledKeySize() >= 0; }
298 324
299 /** 325 /**
300 * Writes unstyledKeySize() bytes into the provided pointer. Assumes that th ere is enough 326 * Writes unstyledKeySize() bytes into the provided pointer. Assumes that th ere is enough
301 * space allocated for the key and that unstyledKeySize() does not return a negative value 327 * space allocated for the key and that unstyledKeySize() does not return a negative value
302 * for this shape. 328 * for this shape.
303 */ 329 */
304 void writeUnstyledKey(uint32_t* key) const; 330 void writeUnstyledKey(uint32_t* key) const;
305 331
306 private: 332 private:
307 enum class Type { 333 enum class Type {
308 kEmpty, 334 kEmpty,
309 kRRect, 335 kRRect,
336 kLine,
310 kPath, 337 kPath,
311 }; 338 };
312 339
313 void initType(Type type, const SkPath* path = nullptr) { 340 void initType(Type type, const SkPath* path = nullptr) {
314 fType = Type::kEmpty; 341 fType = Type::kEmpty;
315 this->changeType(type, path); 342 this->changeType(type, path);
316 } 343 }
317 344
318 void changeType(Type type, const SkPath* path = nullptr) { 345 void changeType(Type type, const SkPath* path = nullptr) {
319 bool wasPath = Type::kPath == fType; 346 bool wasPath = Type::kPath == fType;
(...skipping 29 matching lines...) Expand all
349 GrShape(const GrShape& parentShape, GrStyle::Apply, SkScalar scale); 376 GrShape(const GrShape& parentShape, GrStyle::Apply, SkScalar scale);
350 377
351 /** 378 /**
352 * Determines the key we should inherit from the input shape's geometry and style when 379 * Determines the key we should inherit from the input shape's geometry and style when
353 * we are applying the style to create a new shape. 380 * we are applying the style to create a new shape.
354 */ 381 */
355 void setInheritedKey(const GrShape& parentShape, GrStyle::Apply, SkScalar sc ale); 382 void setInheritedKey(const GrShape& parentShape, GrStyle::Apply, SkScalar sc ale);
356 383
357 void attemptToSimplifyPath(); 384 void attemptToSimplifyPath();
358 void attemptToSimplifyRRect(); 385 void attemptToSimplifyRRect();
386 void attemptToSimplifyLine();
359 387
360 // Defaults to use when there is no distinction between even/odd and winding fills. 388 // Defaults to use when there is no distinction between even/odd and winding fills.
361 static constexpr SkPath::FillType kDefaultPathFillType = SkPath::kEvenOdd_Fi llType; 389 static constexpr SkPath::FillType kDefaultPathFillType = SkPath::kEvenOdd_Fi llType;
362 static constexpr SkPath::FillType kDefaultPathInverseFillType = 390 static constexpr SkPath::FillType kDefaultPathInverseFillType =
363 SkPath::kInverseEvenOdd_FillType; 391 SkPath::kInverseEvenOdd_FillType;
364 392
365 static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction; 393 static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction;
366 static constexpr unsigned kDefaultRRectStart = 0; 394 static constexpr unsigned kDefaultRRectStart = 0;
367 395
368 static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPath Effect, 396 static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPath Effect,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 SkRRect fRRect; 441 SkRRect fRRect;
414 SkPath::Direction fDir; 442 SkPath::Direction fDir;
415 unsigned fStart; 443 unsigned fStart;
416 bool fInverted; 444 bool fInverted;
417 } fRRectData; 445 } fRRectData;
418 struct { 446 struct {
419 SkPath fPath; 447 SkPath fPath;
420 // Gen ID of the original path (fPath may be modified) 448 // Gen ID of the original path (fPath may be modified)
421 int32_t fGenID; 449 int32_t fGenID;
422 } fPathData; 450 } fPathData;
451 struct {
452 SkPoint fPts[2];
453 bool fInverted;
454 } fLineData;
423 }; 455 };
424 GrStyle fStyle; 456 GrStyle fStyle;
425 SkAutoSTArray<8, uint32_t> fInheritedKey; 457 SkAutoSTArray<8, uint32_t> fInheritedKey;
426 }; 458 };
427 #endif 459 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrDrawContext.cpp ('k') | src/gpu/GrShape.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698