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