OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrAALinearizingConvexPathRenderer.h" | 8 #include "GrAALinearizingConvexPathRenderer.h" |
9 | 9 |
10 #include "GrAAConvexTessellator.h" | 10 #include "GrAAConvexTessellator.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 if (!args.fShape->knownToBeConvex()) { | 43 if (!args.fShape->knownToBeConvex()) { |
44 return false; | 44 return false; |
45 } | 45 } |
46 if (args.fShape->style().pathEffect()) { | 46 if (args.fShape->style().pathEffect()) { |
47 return false; | 47 return false; |
48 } | 48 } |
49 if (args.fShape->inverseFilled()) { | 49 if (args.fShape->inverseFilled()) { |
50 return false; | 50 return false; |
51 } | 51 } |
52 const SkStrokeRec& stroke = args.fShape->style().strokeRec(); | 52 const SkStrokeRec& stroke = args.fShape->style().strokeRec(); |
53 if (stroke.getStyle() == SkStrokeRec::kStroke_Style) { | 53 |
| 54 if (stroke.getStyle() == SkStrokeRec::kStroke_Style || |
| 55 stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style) { |
54 if (!args.fViewMatrix->isSimilarity()) { | 56 if (!args.fViewMatrix->isSimilarity()) { |
55 return false; | 57 return false; |
56 } | 58 } |
57 SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth
(); | 59 SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth
(); |
58 return strokeWidth >= 1.0f && strokeWidth <= kMaxStrokeWidth && | 60 if (strokeWidth < 1.0f && stroke.getStyle() == SkStrokeRec::kStroke_Styl
e) { |
| 61 return false; |
| 62 } |
| 63 return strokeWidth <= kMaxStrokeWidth && |
59 args.fShape->knownToBeClosed() && | 64 args.fShape->knownToBeClosed() && |
60 stroke.getJoin() != SkPaint::Join::kRound_Join; | 65 stroke.getJoin() != SkPaint::Join::kRound_Join; |
61 } | 66 } |
62 return stroke.getStyle() == SkStrokeRec::kFill_Style; | 67 return stroke.getStyle() == SkStrokeRec::kFill_Style; |
63 } | 68 } |
64 | 69 |
65 // extract the result vertices and indices from the GrAAConvexTessellator | 70 // extract the result vertices and indices from the GrAAConvexTessellator |
66 static void extract_verts(const GrAAConvexTessellator& tess, | 71 static void extract_verts(const GrAAConvexTessellator& tess, |
67 void* vertices, | 72 void* vertices, |
68 size_t vertexStride, | 73 size_t vertexStride, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 } | 124 } |
120 | 125 |
121 class AAFlatteningConvexPathBatch : public GrVertexBatch { | 126 class AAFlatteningConvexPathBatch : public GrVertexBatch { |
122 public: | 127 public: |
123 DEFINE_BATCH_CLASS_ID | 128 DEFINE_BATCH_CLASS_ID |
124 | 129 |
125 AAFlatteningConvexPathBatch(GrColor color, | 130 AAFlatteningConvexPathBatch(GrColor color, |
126 const SkMatrix& viewMatrix, | 131 const SkMatrix& viewMatrix, |
127 const SkPath& path, | 132 const SkPath& path, |
128 SkScalar strokeWidth, | 133 SkScalar strokeWidth, |
| 134 SkStrokeRec::Style style, |
129 SkPaint::Join join, | 135 SkPaint::Join join, |
130 SkScalar miterLimit) : INHERITED(ClassID()) { | 136 SkScalar miterLimit) : INHERITED(ClassID()) { |
131 fGeoData.emplace_back(Geometry{color, viewMatrix, path, strokeWidth, joi
n, miterLimit}); | 137 fGeoData.emplace_back(Geometry{ color, viewMatrix, path, |
| 138 strokeWidth, style, join, miterLimit }); |
132 | 139 |
133 // compute bounds | 140 // compute bounds |
134 SkRect bounds = path.getBounds(); | 141 SkRect bounds = path.getBounds(); |
135 SkScalar w = strokeWidth; | 142 SkScalar w = strokeWidth; |
136 if (w > 0) { | 143 if (w > 0) { |
137 w /= 2; | 144 w /= 2; |
138 // If the half stroke width is < 1 then we effectively fallback to b
evel joins. | 145 // If the half stroke width is < 1 then we effectively fallback to b
evel joins. |
139 if (SkPaint::kMiter_Join == join && w > 1.f) { | 146 if (SkPaint::kMiter_Join == join && w > 1.f) { |
140 w *= miterLimit; | 147 w *= miterLimit; |
141 } | 148 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 int instanceCount = fGeoData.count(); | 229 int instanceCount = fGeoData.count(); |
223 | 230 |
224 int vertexCount = 0; | 231 int vertexCount = 0; |
225 int indexCount = 0; | 232 int indexCount = 0; |
226 int maxVertices = DEFAULT_BUFFER_SIZE; | 233 int maxVertices = DEFAULT_BUFFER_SIZE; |
227 int maxIndices = DEFAULT_BUFFER_SIZE; | 234 int maxIndices = DEFAULT_BUFFER_SIZE; |
228 uint8_t* vertices = (uint8_t*) sk_malloc_throw(maxVertices * vertexStrid
e); | 235 uint8_t* vertices = (uint8_t*) sk_malloc_throw(maxVertices * vertexStrid
e); |
229 uint16_t* indices = (uint16_t*) sk_malloc_throw(maxIndices * sizeof(uint
16_t)); | 236 uint16_t* indices = (uint16_t*) sk_malloc_throw(maxIndices * sizeof(uint
16_t)); |
230 for (int i = 0; i < instanceCount; i++) { | 237 for (int i = 0; i < instanceCount; i++) { |
231 const Geometry& args = fGeoData[i]; | 238 const Geometry& args = fGeoData[i]; |
232 GrAAConvexTessellator tess(args.fStrokeWidth, args.fJoin, args.fMite
rLimit); | 239 GrAAConvexTessellator tess(args.fStyle, args.fStrokeWidth, |
| 240 args.fJoin, args.fMiterLimit); |
233 | 241 |
234 if (!tess.tessellate(args.fViewMatrix, args.fPath)) { | 242 if (!tess.tessellate(args.fViewMatrix, args.fPath)) { |
235 continue; | 243 continue; |
236 } | 244 } |
237 | 245 |
238 int currentIndices = tess.numIndices(); | 246 int currentIndices = tess.numIndices(); |
239 SkASSERT(currentIndices <= UINT16_MAX); | 247 SkASSERT(currentIndices <= UINT16_MAX); |
240 if (indexCount + currentIndices > UINT16_MAX) { | 248 if (indexCount + currentIndices > UINT16_MAX) { |
241 // if we added the current instance, we would overflow the indic
es we can store in a | 249 // if we added the current instance, we would overflow the indic
es we can store in a |
242 // uint16_t. Draw what we've got so far and reset. | 250 // uint16_t. Draw what we've got so far and reset. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 bool fCoverageIgnored; | 310 bool fCoverageIgnored; |
303 bool fLinesOnly; | 311 bool fLinesOnly; |
304 bool fCanTweakAlphaForCoverage; | 312 bool fCanTweakAlphaForCoverage; |
305 }; | 313 }; |
306 | 314 |
307 struct Geometry { | 315 struct Geometry { |
308 GrColor fColor; | 316 GrColor fColor; |
309 SkMatrix fViewMatrix; | 317 SkMatrix fViewMatrix; |
310 SkPath fPath; | 318 SkPath fPath; |
311 SkScalar fStrokeWidth; | 319 SkScalar fStrokeWidth; |
| 320 SkStrokeRec::Style fStyle; |
312 SkPaint::Join fJoin; | 321 SkPaint::Join fJoin; |
313 SkScalar fMiterLimit; | 322 SkScalar fMiterLimit; |
314 }; | 323 }; |
315 | 324 |
316 BatchTracker fBatch; | 325 BatchTracker fBatch; |
317 SkSTArray<1, Geometry, true> fGeoData; | 326 SkSTArray<1, Geometry, true> fGeoData; |
318 | 327 |
319 typedef GrVertexBatch INHERITED; | 328 typedef GrVertexBatch INHERITED; |
320 }; | 329 }; |
321 | 330 |
322 bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) { | 331 bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) { |
323 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), | 332 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), |
324 "GrAALinearizingConvexPathRenderer::onDrawPath"); | 333 "GrAALinearizingConvexPathRenderer::onDrawPath"); |
325 SkASSERT(!args.fDrawContext->isUnifiedMultisampled()); | 334 SkASSERT(!args.fDrawContext->isUnifiedMultisampled()); |
326 SkASSERT(!args.fShape->isEmpty()); | 335 SkASSERT(!args.fShape->isEmpty()); |
| 336 SkASSERT(!args.fShape->style().pathEffect()); |
327 | 337 |
328 SkPath path; | 338 SkPath path; |
329 args.fShape->asPath(&path); | 339 args.fShape->asPath(&path); |
330 bool fill = args.fShape->style().isSimpleFill(); | 340 bool fill = args.fShape->style().isSimpleFill(); |
331 const SkStrokeRec& stroke = args.fShape->style().strokeRec(); | 341 const SkStrokeRec& stroke = args.fShape->style().strokeRec(); |
332 SkScalar strokeWidth = fill ? -1.0f : stroke.getWidth(); | 342 SkScalar strokeWidth = fill ? -1.0f : stroke.getWidth(); |
333 SkPaint::Join join = fill ? SkPaint::Join::kMiter_Join : stroke.getJoin(); | 343 SkPaint::Join join = fill ? SkPaint::Join::kMiter_Join : stroke.getJoin(); |
334 SkScalar miterLimit = stroke.getMiter(); | 344 SkScalar miterLimit = stroke.getMiter(); |
335 | 345 |
336 SkAutoTUnref<GrDrawBatch> batch(new AAFlatteningConvexPathBatch(args.fPaint-
>getColor(), | 346 SkAutoTUnref<GrDrawBatch> batch(new AAFlatteningConvexPathBatch(args.fPaint-
>getColor(), |
337 *args.fViewM
atrix, | 347 *args.fViewM
atrix, |
338 path, stroke
Width, join, | 348 path, stroke
Width, |
339 miterLimit))
; | 349 stroke.getSt
yle(), |
| 350 join, miterL
imit)); |
340 | 351 |
341 GrPipelineBuilder pipelineBuilder(*args.fPaint); | 352 GrPipelineBuilder pipelineBuilder(*args.fPaint); |
342 pipelineBuilder.setUserStencil(args.fUserStencilSettings); | 353 pipelineBuilder.setUserStencil(args.fUserStencilSettings); |
343 | 354 |
344 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); | 355 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); |
345 | 356 |
346 return true; | 357 return true; |
347 } | 358 } |
348 | 359 |
349 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 360 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
350 | 361 |
351 #ifdef GR_TEST_UTILS | 362 #ifdef GR_TEST_UTILS |
352 | 363 |
353 DRAW_BATCH_TEST_DEFINE(AAFlatteningConvexPathBatch) { | 364 DRAW_BATCH_TEST_DEFINE(AAFlatteningConvexPathBatch) { |
354 GrColor color = GrRandomColor(random); | 365 GrColor color = GrRandomColor(random); |
355 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 366 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); |
356 SkPath path = GrTest::TestPathConvex(random); | 367 SkPath path = GrTest::TestPathConvex(random); |
357 SkScalar strokeWidth = random->nextBool() ? -1.f : 2.f; | 368 |
| 369 SkStrokeRec::Style styles[3] = { SkStrokeRec::kFill_Style, |
| 370 SkStrokeRec::kStroke_Style, |
| 371 SkStrokeRec::kStrokeAndFill_Style }; |
| 372 |
| 373 SkStrokeRec::Style style = styles[random->nextU() % 3]; |
| 374 |
| 375 SkScalar strokeWidth = -1.f; |
358 SkPaint::Join join = SkPaint::kMiter_Join; | 376 SkPaint::Join join = SkPaint::kMiter_Join; |
359 SkScalar miterLimit = 0.5f; | 377 SkScalar miterLimit = 0.5f; |
360 return new AAFlatteningConvexPathBatch(color, viewMatrix, path, strokeWidth,
join, miterLimit); | 378 |
| 379 if (SkStrokeRec::kFill_Style != style) { |
| 380 strokeWidth = random->nextRangeF(1.0f, 10.0f); |
| 381 if (random->nextBool()) { |
| 382 join = SkPaint::kMiter_Join; |
| 383 } else { |
| 384 join = SkPaint::kBevel_Join; |
| 385 } |
| 386 miterLimit = random->nextRangeF(0.5f, 2.0f); |
| 387 } |
| 388 |
| 389 return new AAFlatteningConvexPathBatch(color, viewMatrix, path, strokeWidth,
|
| 390 style, join, miterLimit); |
361 } | 391 } |
362 | 392 |
363 #endif | 393 #endif |
OLD | NEW |