| 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 |