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