Chromium Code Reviews| Index: src/gpu/batches/GrAAStrokeRectBatch.cpp |
| diff --git a/src/gpu/batches/GrAAStrokeRectBatch.cpp b/src/gpu/batches/GrAAStrokeRectBatch.cpp |
| index 0a9601f3102f87f27bdd10eb4057e47f2e0cf055..1de74b7615be6a4c293c31400f64f87f26792ca2 100644 |
| --- a/src/gpu/batches/GrAAStrokeRectBatch.cpp |
| +++ b/src/gpu/batches/GrAAStrokeRectBatch.cpp |
| @@ -53,6 +53,7 @@ public: |
| SkRect fDevOutsideAssist; |
| SkRect fDevInside; |
| GrColor fColor; |
| + bool fDegenerate; |
| }; |
| static AAStrokeRectBatch* Create(const SkMatrix& viewMatrix, bool miterStroke) { |
| @@ -77,17 +78,19 @@ public: |
| } |
| void append(GrColor color, const SkRect& devOutside, const SkRect& devOutsideAssist, |
| - const SkRect& devInside) { |
| + const SkRect& devInside, bool degenerate) { |
| Geometry& geometry = fGeoData.push_back(); |
| geometry.fColor = color; |
| geometry.fDevOutside = devOutside; |
| geometry.fDevOutsideAssist = devOutsideAssist; |
| geometry.fDevInside = devInside; |
| + geometry.fDegenerate = degenerate; |
| } |
| void appendAndUpdateBounds(GrColor color, const SkRect& devOutside, |
| - const SkRect& devOutsideAssist, const SkRect& devInside) { |
| - this->append(color, devOutside, devOutsideAssist, devInside); |
| + const SkRect& devOutsideAssist, const SkRect& devInside, |
| + bool degenerate) { |
| + this->append(color, devOutside, devOutsideAssist, devInside, degenerate); |
| SkRect bounds; |
| this->updateBounds(&bounds, fGeoData.back()); |
| @@ -145,6 +148,7 @@ private: |
| const SkRect& devOutsideAssist, |
| const SkRect& devInside, |
| bool miterStroke, |
| + bool degenerate, |
| bool tweakAlphaForCoverage) const; |
| struct BatchTracker { |
| @@ -226,6 +230,7 @@ void AAStrokeRectBatch::onPrepareDraws(Target* target) { |
| args.fDevOutsideAssist, |
| args.fDevInside, |
| fMiterStroke, |
| + args.fDegenerate, |
| canTweakAlphaForCoverage); |
| } |
| helper.recordDraw(target); |
| @@ -356,6 +361,15 @@ bool AAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) { |
| return true; |
| } |
| +static void setup_scale(int* scale, SkScalar inset) { |
| + if (inset < SK_ScalarHalf) { |
| + *scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); |
| + SkASSERT(*scale >= 0 && *scale <= 255); |
| + } else { |
| + *scale = 0xff; |
| + } |
| +} |
| + |
| void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
| size_t offset, |
| size_t vertexStride, |
| @@ -366,6 +380,7 @@ void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
| const SkRect& devOutsideAssist, |
| const SkRect& devInside, |
| bool miterStroke, |
| + bool degenerate, |
| bool tweakAlphaForCoverage) const { |
| intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; |
| @@ -401,9 +416,19 @@ void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
| set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_ScalarHalf); |
| // inner two |
| set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); |
| - set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); |
| - // innermost |
| - set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_ScalarHalf); |
| + if (!degenerate) { |
| + set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); |
| + // innermost |
| + set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_ScalarHalf); |
| + } else { |
| + // When the interior rect has become degenerate we smoosh to a single point |
| + SkASSERT(devInside.fLeft == devInside.fRight && |
| + devInside.fTop == devInside.fBottom); |
| + fan2Pos->setRectFan(devInside.fLeft, devInside.fTop, |
| + devInside.fRight, devInside.fBottom, vertexStride); |
| + fan3Pos->setRectFan(devInside.fLeft, devInside.fTop, |
| + devInside.fRight, devInside.fBottom, vertexStride); |
| + } |
| } else { |
| SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); |
| SkPoint* fan1AssistPos = reinterpret_cast<SkPoint*>(verts + |
| @@ -416,10 +441,20 @@ void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
| // outer one of the inner two |
| set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); |
| set_inset_fan(fan1AssistPos, vertexStride, devOutsideAssist, inset, inset); |
| - // inner one of the inner two |
| - set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); |
| - // innermost |
| - set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_ScalarHalf); |
| + if (!degenerate) { |
| + // inner one of the inner two |
| + set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); |
| + // innermost |
| + set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_ScalarHalf); |
| + } else { |
| + // When the interior rect has become degenerate we smoosh to a single point |
| + SkASSERT(devInside.fLeft == devInside.fRight && |
| + devInside.fTop == devInside.fBottom); |
| + fan2Pos->setRectFan(devInside.fLeft, devInside.fTop, |
| + devInside.fRight, devInside.fBottom, vertexStride); |
| + fan3Pos->setRectFan(devInside.fLeft, devInside.fTop, |
| + devInside.fRight, devInside.fBottom, vertexStride); |
| + } |
| } |
| // Make verts point to vertex color and then set all the color and coverage vertex attrs |
| @@ -436,11 +471,16 @@ void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
| // scale is the coverage for the the inner two rects. |
| int scale; |
| - if (inset < SK_ScalarHalf) { |
| - scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); |
| - SkASSERT(scale >= 0 && scale <= 255); |
| + if (!degenerate) { |
| + setup_scale(&scale, inset); |
| } else { |
|
robertphillips
2015/09/21 19:57:39
typo degenrate
can -> need to ?
|
| - scale = 0xff; |
| + // If we are degenrate, we can scale the coverage over the entire rect and not just the |
| + // inset |
| + // 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
|
| + SkScalar aaInset = SkMinScalar(devOutside.width(), SK_Scalar1); |
| + aaInset = SK_ScalarHalf * SkMinScalar(aaInset, SkTMax(devOutside.height(), |
| + devOutsideAssist.height())); |
| + setup_scale(&scale, aaInset); |
| } |
| float innerCoverage = GrNormalizeByteToFloat(scale); |
| @@ -457,14 +497,18 @@ void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
| } |
| } |
| - // The innermost rect has 0 coverage |
| + // The innermost rect has 0 coverage, unless we are degenerate, in which case we must apply the |
| + // scaled coverage |
| verts += (outerVertexNum + innerVertexNum) * vertexStride; |
| + if (!degenerate) { |
| + scale = 0; |
| + } |
| for (int i = 0; i < innerVertexNum; ++i) { |
| if (tweakAlphaForCoverage) { |
| - *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; |
| + *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scale; |
| } else { |
| *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| - *reinterpret_cast<GrColor*>(verts + i * vertexStride + sizeof(GrColor)) = 0; |
| + *reinterpret_cast<GrColor*>(verts + i * vertexStride + sizeof(GrColor)) = scale; |
| } |
| } |
| } |
| @@ -476,9 +520,10 @@ GrDrawBatch* Create(GrColor color, |
| const SkRect& devOutside, |
| const SkRect& devOutsideAssist, |
| const SkRect& devInside, |
| - bool miterStroke) { |
| + bool miterStroke, |
| + bool degenerate) { |
| AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, miterStroke); |
| - batch->append(color, devOutside, devOutsideAssist, devInside); |
| + batch->append(color, devOutside, devOutsideAssist, devInside, degenerate); |
| batch->init(); |
| return batch; |
| } |
| @@ -489,7 +534,8 @@ bool Append(GrBatch* origBatch, |
| const SkRect& devOutside, |
| const SkRect& devOutsideAssist, |
| const SkRect& devInside, |
| - bool miterStroke) { |
| + bool miterStroke, |
| + bool degenerate) { |
| AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>(); |
| // we can't batch across vm changes |
| @@ -497,7 +543,7 @@ bool Append(GrBatch* origBatch, |
| return false; |
| } |
| - batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside); |
| + batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside, degenerate); |
| return true; |
| } |
| @@ -511,6 +557,7 @@ bool Append(GrBatch* origBatch, |
| DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { |
| bool miterStroke = random->nextBool(); |
| + bool degenerate = random->nextBool(); |
| // Create mock stroke rect |
| SkRect outside = GrTest::TestRect(random); |
| @@ -524,7 +571,7 @@ DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { |
| GrColor color = GrRandomColor(random); |
| return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outside, outsideAssist, |
| - inside, miterStroke); |
| + inside, degenerate, miterStroke); |
| } |
| #endif |