Chromium Code Reviews| 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 "GrAAStrokeRectBatch.h" | 8 #include "GrAAStrokeRectBatch.h" |
| 9 | 9 |
| 10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 class AAStrokeRectBatch : public GrVertexBatch { | 46 class AAStrokeRectBatch : public GrVertexBatch { |
| 47 public: | 47 public: |
| 48 DEFINE_BATCH_CLASS_ID | 48 DEFINE_BATCH_CLASS_ID |
| 49 | 49 |
| 50 // TODO support AA rotated stroke rects by copying around view matrices | 50 // TODO support AA rotated stroke rects by copying around view matrices |
| 51 struct Geometry { | 51 struct Geometry { |
| 52 SkRect fDevOutside; | 52 SkRect fDevOutside; |
| 53 SkRect fDevOutsideAssist; | 53 SkRect fDevOutsideAssist; |
| 54 SkRect fDevInside; | 54 SkRect fDevInside; |
| 55 GrColor fColor; | 55 GrColor fColor; |
| 56 bool fDegenerate; | |
| 56 }; | 57 }; |
| 57 | 58 |
| 58 static AAStrokeRectBatch* Create(const SkMatrix& viewMatrix, bool miterStrok e) { | 59 static AAStrokeRectBatch* Create(const SkMatrix& viewMatrix, bool miterStrok e) { |
| 59 return new AAStrokeRectBatch(viewMatrix, miterStroke); | 60 return new AAStrokeRectBatch(viewMatrix, miterStroke); |
| 60 } | 61 } |
| 61 | 62 |
| 62 const char* name() const override { return "AAStrokeRect"; } | 63 const char* name() const override { return "AAStrokeRect"; } |
| 63 | 64 |
| 64 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 65 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
| 65 // When this is called on a batch, there is only one geometry bundle | 66 // When this is called on a batch, there is only one geometry bundle |
| 66 out->setKnownFourComponents(fGeoData[0].fColor); | 67 out->setKnownFourComponents(fGeoData[0].fColor); |
| 67 } | 68 } |
| 68 | 69 |
| 69 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 70 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
| 70 out->setUnknownSingleComponent(); | 71 out->setUnknownSingleComponent(); |
| 71 } | 72 } |
| 72 | 73 |
| 73 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 74 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 74 | 75 |
| 75 bool canAppend(const SkMatrix& viewMatrix, bool miterStroke) { | 76 bool canAppend(const SkMatrix& viewMatrix, bool miterStroke) { |
| 76 return fViewMatrix.cheapEqualTo(viewMatrix) && fMiterStroke == miterStro ke; | 77 return fViewMatrix.cheapEqualTo(viewMatrix) && fMiterStroke == miterStro ke; |
| 77 } | 78 } |
| 78 | 79 |
| 79 void append(GrColor color, const SkRect& devOutside, const SkRect& devOutsid eAssist, | 80 void append(GrColor color, const SkRect& devOutside, const SkRect& devOutsid eAssist, |
| 80 const SkRect& devInside) { | 81 const SkRect& devInside, bool degenerate) { |
| 81 Geometry& geometry = fGeoData.push_back(); | 82 Geometry& geometry = fGeoData.push_back(); |
| 82 geometry.fColor = color; | 83 geometry.fColor = color; |
| 83 geometry.fDevOutside = devOutside; | 84 geometry.fDevOutside = devOutside; |
| 84 geometry.fDevOutsideAssist = devOutsideAssist; | 85 geometry.fDevOutsideAssist = devOutsideAssist; |
| 85 geometry.fDevInside = devInside; | 86 geometry.fDevInside = devInside; |
| 87 geometry.fDegenerate = degenerate; | |
| 86 } | 88 } |
| 87 | 89 |
| 88 void appendAndUpdateBounds(GrColor color, const SkRect& devOutside, | 90 void appendAndUpdateBounds(GrColor color, const SkRect& devOutside, |
| 89 const SkRect& devOutsideAssist, const SkRect& dev Inside) { | 91 const SkRect& devOutsideAssist, const SkRect& dev Inside, |
| 90 this->append(color, devOutside, devOutsideAssist, devInside); | 92 bool degenerate) { |
| 93 this->append(color, devOutside, devOutsideAssist, devInside, degenerate) ; | |
| 91 | 94 |
| 92 SkRect bounds; | 95 SkRect bounds; |
| 93 this->updateBounds(&bounds, fGeoData.back()); | 96 this->updateBounds(&bounds, fGeoData.back()); |
| 94 this->joinBounds(bounds); | 97 this->joinBounds(bounds); |
| 95 } | 98 } |
| 96 | 99 |
| 97 void init() { this->updateBounds(&fBounds, fGeoData[0]); } | 100 void init() { this->updateBounds(&fBounds, fGeoData[0]); } |
| 98 | 101 |
| 99 private: | 102 private: |
| 100 void updateBounds(SkRect* bounds, const Geometry& geo) { | 103 void updateBounds(SkRect* bounds, const Geometry& geo) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 void generateAAStrokeRectGeometry(void* vertices, | 141 void generateAAStrokeRectGeometry(void* vertices, |
| 139 size_t offset, | 142 size_t offset, |
| 140 size_t vertexStride, | 143 size_t vertexStride, |
| 141 int outerVertexNum, | 144 int outerVertexNum, |
| 142 int innerVertexNum, | 145 int innerVertexNum, |
| 143 GrColor color, | 146 GrColor color, |
| 144 const SkRect& devOutside, | 147 const SkRect& devOutside, |
| 145 const SkRect& devOutsideAssist, | 148 const SkRect& devOutsideAssist, |
| 146 const SkRect& devInside, | 149 const SkRect& devInside, |
| 147 bool miterStroke, | 150 bool miterStroke, |
| 151 bool degenerate, | |
| 148 bool tweakAlphaForCoverage) const; | 152 bool tweakAlphaForCoverage) const; |
| 149 | 153 |
| 150 struct BatchTracker { | 154 struct BatchTracker { |
| 151 GrColor fColor; | 155 GrColor fColor; |
| 152 bool fUsesLocalCoords; | 156 bool fUsesLocalCoords; |
| 153 bool fColorIgnored; | 157 bool fColorIgnored; |
| 154 bool fCoverageIgnored; | 158 bool fCoverageIgnored; |
| 155 bool fCanTweakAlphaForCoverage; | 159 bool fCanTweakAlphaForCoverage; |
| 156 }; | 160 }; |
| 157 | 161 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 this->generateAAStrokeRectGeometry(vertices, | 223 this->generateAAStrokeRectGeometry(vertices, |
| 220 i * verticesPerInstance * vertexStrid e, | 224 i * verticesPerInstance * vertexStrid e, |
| 221 vertexStride, | 225 vertexStride, |
| 222 outerVertexNum, | 226 outerVertexNum, |
| 223 innerVertexNum, | 227 innerVertexNum, |
| 224 args.fColor, | 228 args.fColor, |
| 225 args.fDevOutside, | 229 args.fDevOutside, |
| 226 args.fDevOutsideAssist, | 230 args.fDevOutsideAssist, |
| 227 args.fDevInside, | 231 args.fDevInside, |
| 228 fMiterStroke, | 232 fMiterStroke, |
| 233 args.fDegenerate, | |
| 229 canTweakAlphaForCoverage); | 234 canTweakAlphaForCoverage); |
| 230 } | 235 } |
| 231 helper.recordDraw(target); | 236 helper.recordDraw(target); |
| 232 } | 237 } |
| 233 | 238 |
| 234 const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resou rceProvider, | 239 const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resou rceProvider, |
| 235 bool miterStroke) { | 240 bool miterStroke) { |
| 236 | 241 |
| 237 if (miterStroke) { | 242 if (miterStroke) { |
| 238 static const uint16_t gMiterIndices[] = { | 243 static const uint16_t gMiterIndices[] = { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 } | 354 } |
| 350 | 355 |
| 351 if (this->color() != that->color()) { | 356 if (this->color() != that->color()) { |
| 352 fBatch.fColor = GrColor_ILLEGAL; | 357 fBatch.fColor = GrColor_ILLEGAL; |
| 353 } | 358 } |
| 354 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); | 359 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); |
| 355 this->joinBounds(that->bounds()); | 360 this->joinBounds(that->bounds()); |
| 356 return true; | 361 return true; |
| 357 } | 362 } |
| 358 | 363 |
| 364 static void setup_scale(int* scale, SkScalar inset) { | |
| 365 if (inset < SK_ScalarHalf) { | |
| 366 *scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); | |
| 367 SkASSERT(*scale >= 0 && *scale <= 255); | |
| 368 } else { | |
| 369 *scale = 0xff; | |
| 370 } | |
| 371 } | |
| 372 | |
| 359 void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, | 373 void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
| 360 size_t offset, | 374 size_t offset, |
| 361 size_t vertexStride, | 375 size_t vertexStride, |
| 362 int outerVertexNum, | 376 int outerVertexNum, |
| 363 int innerVertexNum, | 377 int innerVertexNum, |
| 364 GrColor color, | 378 GrColor color, |
| 365 const SkRect& devOutside, | 379 const SkRect& devOutside, |
| 366 const SkRect& devOutsideAss ist, | 380 const SkRect& devOutsideAss ist, |
| 367 const SkRect& devInside, | 381 const SkRect& devInside, |
| 368 bool miterStroke, | 382 bool miterStroke, |
| 383 bool degenerate, | |
| 369 bool tweakAlphaForCoverage) const { | 384 bool tweakAlphaForCoverage) const { |
| 370 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; | 385 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; |
| 371 | 386 |
| 372 // We create vertices for four nested rectangles. There are two ramps from 0 to full | 387 // We create vertices for four nested rectangles. There are two ramps from 0 to full |
| 373 // coverage, one on the exterior of the stroke and the other on the interior . | 388 // coverage, one on the exterior of the stroke and the other on the interior . |
| 374 // The following pointers refer to the four rects, from outermost to innermo st. | 389 // The following pointers refer to the four rects, from outermost to innermo st. |
| 375 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 390 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
| 376 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * verte xStride); | 391 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * verte xStride); |
| 377 SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * v ertexStride); | 392 SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * v ertexStride); |
| 378 SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts + | 393 SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts + |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 394 SkASSERT(inset >= 0); | 409 SkASSERT(inset >= 0); |
| 395 #else | 410 #else |
| 396 SkScalar inset = SK_ScalarHalf; | 411 SkScalar inset = SK_ScalarHalf; |
| 397 #endif | 412 #endif |
| 398 | 413 |
| 399 if (miterStroke) { | 414 if (miterStroke) { |
| 400 // outermost | 415 // outermost |
| 401 set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_Sca larHalf); | 416 set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_Sca larHalf); |
| 402 // inner two | 417 // inner two |
| 403 set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); | 418 set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); |
| 404 set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); | 419 if (!degenerate) { |
| 405 // innermost | 420 set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); |
| 406 set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_Sca larHalf); | 421 // innermost |
| 422 set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK _ScalarHalf); | |
| 423 } else { | |
| 424 // When the interior rect has become degenerate we smoosh to a singl e point | |
| 425 SkASSERT(devInside.fLeft == devInside.fRight && | |
| 426 devInside.fTop == devInside.fBottom); | |
| 427 fan2Pos->setRectFan(devInside.fLeft, devInside.fTop, | |
| 428 devInside.fRight, devInside.fBottom, vertexStrid e); | |
| 429 fan3Pos->setRectFan(devInside.fLeft, devInside.fTop, | |
| 430 devInside.fRight, devInside.fBottom, vertexStrid e); | |
| 431 } | |
| 407 } else { | 432 } else { |
| 408 SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vertexSt ride); | 433 SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vertexSt ride); |
| 409 SkPoint* fan1AssistPos = reinterpret_cast<SkPoint*>(verts + | 434 SkPoint* fan1AssistPos = reinterpret_cast<SkPoint*>(verts + |
| 410 (outerVertexNum + 4) * | 435 (outerVertexNum + 4) * |
| 411 vertexStride); | 436 vertexStride); |
| 412 // outermost | 437 // outermost |
| 413 set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_Sca larHalf); | 438 set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_Sca larHalf); |
| 414 set_inset_fan(fan0AssistPos, vertexStride, devOutsideAssist, -SK_ScalarH alf, | 439 set_inset_fan(fan0AssistPos, vertexStride, devOutsideAssist, -SK_ScalarH alf, |
| 415 -SK_ScalarHalf); | 440 -SK_ScalarHalf); |
| 416 // outer one of the inner two | 441 // outer one of the inner two |
| 417 set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); | 442 set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); |
| 418 set_inset_fan(fan1AssistPos, vertexStride, devOutsideAssist, inset, in set); | 443 set_inset_fan(fan1AssistPos, vertexStride, devOutsideAssist, inset, in set); |
| 419 // inner one of the inner two | 444 if (!degenerate) { |
| 420 set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); | 445 // inner one of the inner two |
| 421 // innermost | 446 set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); |
| 422 set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_Sca larHalf); | 447 // innermost |
| 448 set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK _ScalarHalf); | |
| 449 } else { | |
| 450 // When the interior rect has become degenerate we smoosh to a singl e point | |
| 451 SkASSERT(devInside.fLeft == devInside.fRight && | |
| 452 devInside.fTop == devInside.fBottom); | |
| 453 fan2Pos->setRectFan(devInside.fLeft, devInside.fTop, | |
| 454 devInside.fRight, devInside.fBottom, vertexStrid e); | |
| 455 fan3Pos->setRectFan(devInside.fLeft, devInside.fTop, | |
| 456 devInside.fRight, devInside.fBottom, vertexStrid e); | |
| 457 } | |
| 423 } | 458 } |
| 424 | 459 |
| 425 // Make verts point to vertex color and then set all the color and coverage vertex attrs | 460 // Make verts point to vertex color and then set all the color and coverage vertex attrs |
| 426 // values. The outermost rect has 0 coverage | 461 // values. The outermost rect has 0 coverage |
| 427 verts += sizeof(SkPoint); | 462 verts += sizeof(SkPoint); |
| 428 for (int i = 0; i < outerVertexNum; ++i) { | 463 for (int i = 0; i < outerVertexNum; ++i) { |
| 429 if (tweakAlphaForCoverage) { | 464 if (tweakAlphaForCoverage) { |
| 430 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; | 465 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; |
| 431 } else { | 466 } else { |
| 432 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 467 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| 433 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = 0; | 468 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = 0; |
| 434 } | 469 } |
| 435 } | 470 } |
| 436 | 471 |
| 437 // scale is the coverage for the the inner two rects. | 472 // scale is the coverage for the the inner two rects. |
| 438 int scale; | 473 int scale; |
| 439 if (inset < SK_ScalarHalf) { | 474 if (!degenerate) { |
| 440 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); | 475 setup_scale(&scale, inset); |
| 441 SkASSERT(scale >= 0 && scale <= 255); | |
| 442 } else { | 476 } else { |
|
robertphillips
2015/09/21 19:57:39
typo degenrate
can -> need to ?
| |
| 443 scale = 0xff; | 477 // If we are degenrate, we can scale the coverage over the entire rect a nd not just the |
| 478 // inset | |
| 479 // TODO use real devRect here | |
|
robertphillips
2015/09/21 19:57:39
So devOutsideAssist.width() shouldn't appear in th
joshualitt
2015/09/21 21:18:58
correct, it is always = devrect
| |
| 480 SkScalar aaInset = SkMinScalar(devOutside.width(), SK_Scalar1); | |
| 481 aaInset = SK_ScalarHalf * SkMinScalar(aaInset, SkTMax(devOutside.height( ), | |
| 482 devOutsideAssist.h eight())); | |
| 483 setup_scale(&scale, aaInset); | |
| 444 } | 484 } |
| 445 | 485 |
| 446 float innerCoverage = GrNormalizeByteToFloat(scale); | 486 float innerCoverage = GrNormalizeByteToFloat(scale); |
| 447 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); | 487 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); |
| 448 | 488 |
| 449 verts += outerVertexNum * vertexStride; | 489 verts += outerVertexNum * vertexStride; |
| 450 for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) { | 490 for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) { |
| 451 if (tweakAlphaForCoverage) { | 491 if (tweakAlphaForCoverage) { |
| 452 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; | 492 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
| 453 } else { | 493 } else { |
| 454 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 494 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| 455 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = | 495 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = |
| 456 innerCoverage; | 496 innerCoverage; |
| 457 } | 497 } |
| 458 } | 498 } |
| 459 | 499 |
| 460 // The innermost rect has 0 coverage | 500 // The innermost rect has 0 coverage, unless we are degenerate, in which cas e we must apply the |
| 501 // scaled coverage | |
| 461 verts += (outerVertexNum + innerVertexNum) * vertexStride; | 502 verts += (outerVertexNum + innerVertexNum) * vertexStride; |
| 503 if (!degenerate) { | |
| 504 scale = 0; | |
| 505 } | |
| 462 for (int i = 0; i < innerVertexNum; ++i) { | 506 for (int i = 0; i < innerVertexNum; ++i) { |
| 463 if (tweakAlphaForCoverage) { | 507 if (tweakAlphaForCoverage) { |
| 464 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; | 508 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scale; |
| 465 } else { | 509 } else { |
| 466 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 510 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| 467 *reinterpret_cast<GrColor*>(verts + i * vertexStride + sizeof(GrColo r)) = 0; | 511 *reinterpret_cast<GrColor*>(verts + i * vertexStride + sizeof(GrColo r)) = scale; |
| 468 } | 512 } |
| 469 } | 513 } |
| 470 } | 514 } |
| 471 | 515 |
| 472 namespace GrAAStrokeRectBatch { | 516 namespace GrAAStrokeRectBatch { |
| 473 | 517 |
| 474 GrDrawBatch* Create(GrColor color, | 518 GrDrawBatch* Create(GrColor color, |
| 475 const SkMatrix& viewMatrix, | 519 const SkMatrix& viewMatrix, |
| 476 const SkRect& devOutside, | 520 const SkRect& devOutside, |
| 477 const SkRect& devOutsideAssist, | 521 const SkRect& devOutsideAssist, |
| 478 const SkRect& devInside, | 522 const SkRect& devInside, |
| 479 bool miterStroke) { | 523 bool miterStroke, |
| 524 bool degenerate) { | |
| 480 AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, miterStroke ); | 525 AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, miterStroke ); |
| 481 batch->append(color, devOutside, devOutsideAssist, devInside); | 526 batch->append(color, devOutside, devOutsideAssist, devInside, degenerate); |
| 482 batch->init(); | 527 batch->init(); |
| 483 return batch; | 528 return batch; |
| 484 } | 529 } |
| 485 | 530 |
| 486 bool Append(GrBatch* origBatch, | 531 bool Append(GrBatch* origBatch, |
| 487 GrColor color, | 532 GrColor color, |
| 488 const SkMatrix& viewMatrix, | 533 const SkMatrix& viewMatrix, |
| 489 const SkRect& devOutside, | 534 const SkRect& devOutside, |
| 490 const SkRect& devOutsideAssist, | 535 const SkRect& devOutsideAssist, |
| 491 const SkRect& devInside, | 536 const SkRect& devInside, |
| 492 bool miterStroke) { | 537 bool miterStroke, |
| 538 bool degenerate) { | |
| 493 AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>(); | 539 AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>(); |
| 494 | 540 |
| 495 // we can't batch across vm changes | 541 // we can't batch across vm changes |
| 496 if (!batch->canAppend(viewMatrix, miterStroke)) { | 542 if (!batch->canAppend(viewMatrix, miterStroke)) { |
| 497 return false; | 543 return false; |
| 498 } | 544 } |
| 499 | 545 |
| 500 batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside) ; | 546 batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside, degenerate); |
| 501 return true; | 547 return true; |
| 502 } | 548 } |
| 503 | 549 |
| 504 }; | 550 }; |
| 505 | 551 |
| 506 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 552 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 507 | 553 |
| 508 #ifdef GR_TEST_UTILS | 554 #ifdef GR_TEST_UTILS |
| 509 | 555 |
| 510 #include "GrBatchTest.h" | 556 #include "GrBatchTest.h" |
| 511 | 557 |
| 512 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { | 558 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { |
| 513 bool miterStroke = random->nextBool(); | 559 bool miterStroke = random->nextBool(); |
| 560 bool degenerate = random->nextBool(); | |
| 514 | 561 |
| 515 // Create mock stroke rect | 562 // Create mock stroke rect |
| 516 SkRect outside = GrTest::TestRect(random); | 563 SkRect outside = GrTest::TestRect(random); |
| 517 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); | 564 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); |
| 518 SkScalar strokeWidth = minDim * 0.1f; | 565 SkScalar strokeWidth = minDim * 0.1f; |
| 519 SkRect outsideAssist = outside; | 566 SkRect outsideAssist = outside; |
| 520 outsideAssist.outset(strokeWidth, strokeWidth); | 567 outsideAssist.outset(strokeWidth, strokeWidth); |
| 521 SkRect inside = outside; | 568 SkRect inside = outside; |
| 522 inside.inset(strokeWidth, strokeWidth); | 569 inside.inset(strokeWidth, strokeWidth); |
| 523 | 570 |
| 524 GrColor color = GrRandomColor(random); | 571 GrColor color = GrRandomColor(random); |
| 525 | 572 |
| 526 return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outsid e, outsideAssist, | 573 return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outsid e, outsideAssist, |
| 527 inside, miterStroke); | 574 inside, degenerate, miterStroke); |
| 528 } | 575 } |
| 529 | 576 |
| 530 #endif | 577 #endif |
| OLD | NEW |