Chromium Code Reviews| Index: src/gpu/batches/GrAAStrokeRectBatch.cpp |
| diff --git a/src/gpu/batches/GrAAStrokeRectBatch.cpp b/src/gpu/batches/GrAAStrokeRectBatch.cpp |
| index 98b764aa5b7106acbe780b99c9177c7cde7d16b6..52a9ae0d8d010afcff99afdbe238f218192bb4c9 100644 |
| --- a/src/gpu/batches/GrAAStrokeRectBatch.cpp |
| +++ b/src/gpu/batches/GrAAStrokeRectBatch.cpp |
| @@ -21,6 +21,68 @@ static void set_inset_fan(SkPoint* pts, size_t stride, |
| r.fRight - dx, r.fBottom - dy, stride); |
| } |
| +inline static bool is_miter(const SkStrokeRec& stroke) { |
|
bsalomon
2016/07/01 17:56:37
These two functions are just moved from below.
|
| + // For hairlines, make bevel and round joins appear the same as mitered ones. |
| + // small miter limit means right angles show bevel... |
| + if ((stroke.getWidth() > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || |
| + stroke.getMiter() < SK_ScalarSqrt2)) { |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +static void compute_rects(SkRect* devOutside, SkRect* devOutsideAssist, SkRect* devInside, |
| + bool* isDegenerate, const SkMatrix& viewMatrix, const SkRect& rect, |
| + SkScalar strokeWidth, bool miterStroke) { |
| + SkRect devRect; |
| + viewMatrix.mapRect(&devRect, rect); |
| + |
| + SkVector devStrokeSize; |
| + if (strokeWidth > 0) { |
| + devStrokeSize.set(strokeWidth, strokeWidth); |
| + viewMatrix.mapVectors(&devStrokeSize, 1); |
| + devStrokeSize.setAbs(devStrokeSize); |
| + } else { |
| + devStrokeSize.set(SK_Scalar1, SK_Scalar1); |
| + } |
| + |
| + const SkScalar dx = devStrokeSize.fX; |
| + const SkScalar dy = devStrokeSize.fY; |
| + const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); |
| + const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); |
| + |
| + *devOutside = devRect; |
| + *devOutsideAssist = devRect; |
| + *devInside = devRect; |
| + |
| + devOutside->outset(rx, ry); |
| + devInside->inset(rx, ry); |
| + |
| + // If we have a degenerate stroking rect(ie the stroke is larger than inner rect) then we |
| + // make a degenerate inside rect to avoid double hitting. We will also jam all of the points |
| + // together when we render these rects. |
| + SkScalar spare; |
| + { |
| + SkScalar w = devRect.width() - dx; |
| + SkScalar h = devRect.height() - dy; |
| + spare = SkTMin(w, h); |
| + } |
| + |
| + *isDegenerate = spare <= 0; |
| + if (*isDegenerate) { |
| + devInside->fLeft = devInside->fRight = devRect.centerX(); |
| + devInside->fTop = devInside->fBottom = devRect.centerY(); |
| + } |
| + |
| + // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) |
| + // to draw the outside of the octagon. Because there are 8 vertices on the outer |
| + // edge, while vertex number of inner edge is 4, the same as miter-stroke. |
| + if (!miterStroke) { |
| + devOutside->inset(0, ry); |
| + devOutsideAssist->outset(0, ry); |
| + } |
| +} |
| + |
| static sk_sp<GrGeometryProcessor> create_stroke_rect_gp(bool tweakAlphaForCoverage, |
| const SkMatrix& viewMatrix, |
| bool usesLocalCoords, |
| @@ -47,17 +109,29 @@ class AAStrokeRectBatch : public GrVertexBatch { |
| public: |
| DEFINE_BATCH_CLASS_ID |
| - // TODO support AA rotated stroke rects by copying around view matrices |
| - struct Geometry { |
| - SkRect fDevOutside; |
| - SkRect fDevOutsideAssist; |
| - SkRect fDevInside; |
| - GrColor fColor; |
| - bool fDegenerate; |
| - }; |
| + AAStrokeRectBatch(GrColor color, const SkMatrix& viewMatrix, |
| + const SkRect& devOutside, const SkRect& devInside) : INHERITED(ClassID()) { |
| + SkASSERT(!devOutside.isEmpty()) |
| + SkASSERT(!devInside.isEmpty()) |
| + |
| + fGeoData.emplace_back(Geometry{color, devOutside, devOutside, devInside, false}); |
| + fBounds = devOutside; |
| + fMiterStroke = true; |
| + } |
| + |
| + AAStrokeRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, |
| + const SkStrokeRec& stroke) : INHERITED(ClassID()) { |
| + fMiterStroke = is_miter(stroke); |
| + |
| + SkRect devOutside, devOutsideAssist, devInside; |
| + bool isDegenerate; |
| + compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, viewMatrix, |
| + rect, stroke.getWidth(), fMiterStroke); |
| - static AAStrokeRectBatch* Create(const SkMatrix& viewMatrix, bool miterStroke) { |
| - return new AAStrokeRectBatch(viewMatrix, miterStroke); |
| + fGeoData.emplace_back(Geometry{color, devOutside, devOutsideAssist, devInside, |
| + isDegenerate}); |
| + fBounds = devOutside; |
| + fBounds.join(devOutsideAssist); |
| } |
| const char* name() const override { return "AAStrokeRect"; } |
| @@ -70,51 +144,10 @@ public: |
| coverage->setUnknownSingleComponent(); |
| } |
| - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| - |
| - bool canAppend(const SkMatrix& viewMatrix, bool miterStroke) { |
| - return fViewMatrix.cheapEqualTo(viewMatrix) && fMiterStroke == miterStroke; |
| - } |
| - |
| - void append(GrColor color, const SkRect& devOutside, const SkRect& devOutsideAssist, |
| - 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, |
| - bool degenerate) { |
| - this->append(color, devOutside, devOutsideAssist, devInside, degenerate); |
| - |
| - SkRect bounds; |
| - this->updateBounds(&bounds, fGeoData.back()); |
| - this->joinBounds(bounds); |
| - } |
| - |
| - void init() { this->updateBounds(&fBounds, fGeoData[0]); } |
| - |
| private: |
| - void updateBounds(SkRect* bounds, const Geometry& geo) { |
| - // If we have miterstroke then we inset devOutside and outset devOutsideAssist, so we need |
| - // the join for proper bounds |
| - *bounds = geo.fDevOutside; |
| - bounds->join(geo.fDevOutsideAssist); |
| - } |
| - |
| void onPrepareDraws(Target*) const override; |
| void initBatchTracker(const GrXPOverridesForBatch&) override; |
| - AAStrokeRectBatch(const SkMatrix& viewMatrix,bool miterStroke) |
| - : INHERITED(ClassID()) { |
|
robertphillips
2016/07/01 19:14:01
Where did the init of 'fViewMatrix' go ?
Can we re
|
| - fViewMatrix = viewMatrix; |
| - fMiterStroke = miterStroke; |
| - } |
| - |
| static const int kMiterIndexCnt = 3 * 24; |
| static const int kMiterVertexCnt = 16; |
| static const int kNumMiterRectsInIndexBuffer = 256; |
| @@ -130,7 +163,6 @@ private: |
| bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } |
| bool colorIgnored() const { return fBatch.fColorIgnored; } |
| bool coverageIgnored() const { return fBatch.fCoverageIgnored; } |
| - const Geometry& geometry() const { return fGeoData[0]; } |
| const SkMatrix& viewMatrix() const { return fViewMatrix; } |
| bool miterStroke() const { return fMiterStroke; } |
| @@ -157,6 +189,15 @@ private: |
| bool fCanTweakAlphaForCoverage; |
| }; |
| + // TODO support AA rotated stroke rects by copying around view matrices |
| + struct Geometry { |
| + GrColor fColor; |
| + SkRect fDevOutside; |
| + SkRect fDevOutsideAssist; |
| + SkRect fDevInside; |
| + bool fDegenerate; |
| + }; |
| + |
| BatchTracker fBatch; |
| SkSTArray<1, Geometry, true> fGeoData; |
| SkMatrix fViewMatrix; |
| @@ -352,7 +393,7 @@ bool AAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) { |
| if (this->color() != that->color()) { |
| fBatch.fColor = GrColor_ILLEGAL; |
| } |
| - fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); |
| + fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); |
| this->joinBounds(that->bounds()); |
| return true; |
| } |
| @@ -516,123 +557,24 @@ void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
| } |
| } |
| -inline static bool is_miter(const SkStrokeRec& stroke) { |
| - // For hairlines, make bevel and round joins appear the same as mitered ones. |
| - // small miter limit means right angles show bevel... |
| - if ((stroke.getWidth() > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || |
| - stroke.getMiter() < SK_ScalarSqrt2)) { |
| - return false; |
| - } |
| - return true; |
| -} |
| - |
| -static void compute_rects(SkRect* devOutside, SkRect* devOutsideAssist, SkRect* devInside, |
| - bool* isDegenerate, const SkMatrix& viewMatrix, const SkRect& rect, |
| - SkScalar strokeWidth, bool miterStroke) { |
| - SkRect devRect; |
| - viewMatrix.mapRect(&devRect, rect); |
| - |
| - SkVector devStrokeSize; |
| - if (strokeWidth > 0) { |
| - devStrokeSize.set(strokeWidth, strokeWidth); |
| - viewMatrix.mapVectors(&devStrokeSize, 1); |
| - devStrokeSize.setAbs(devStrokeSize); |
| - } else { |
| - devStrokeSize.set(SK_Scalar1, SK_Scalar1); |
| - } |
| - |
| - const SkScalar dx = devStrokeSize.fX; |
| - const SkScalar dy = devStrokeSize.fY; |
| - const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); |
| - const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); |
| - |
| - *devOutside = devRect; |
| - *devOutsideAssist = devRect; |
| - *devInside = devRect; |
| - |
| - devOutside->outset(rx, ry); |
| - devInside->inset(rx, ry); |
| - |
| - // If we have a degenerate stroking rect(ie the stroke is larger than inner rect) then we |
| - // make a degenerate inside rect to avoid double hitting. We will also jam all of the points |
| - // together when we render these rects. |
| - SkScalar spare; |
| - { |
| - SkScalar w = devRect.width() - dx; |
| - SkScalar h = devRect.height() - dy; |
| - spare = SkTMin(w, h); |
| - } |
| - |
| - *isDegenerate = spare <= 0; |
| - if (*isDegenerate) { |
| - devInside->fLeft = devInside->fRight = devRect.centerX(); |
| - devInside->fTop = devInside->fBottom = devRect.centerY(); |
| - } |
| - |
| - // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) |
| - // to draw the outside of the octagon. Because there are 8 vertices on the outer |
| - // edge, while vertex number of inner edge is 4, the same as miter-stroke. |
| - if (!miterStroke) { |
| - devOutside->inset(0, ry); |
| - devOutsideAssist->outset(0, ry); |
| - } |
| -} |
| - |
| namespace GrAAStrokeRectBatch { |
| GrDrawBatch* CreateFillBetweenRects(GrColor color, |
| const SkMatrix& viewMatrix, |
| const SkRect& devOutside, |
| const SkRect& devInside) { |
| - SkASSERT(!devOutside.isEmpty()) |
| - SkASSERT(!devInside.isEmpty()) |
| - AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, true); |
| - batch->append(color, devOutside, devOutside, devInside, false); |
| - batch->init(); |
| - return batch; |
| + return new AAStrokeRectBatch(color, viewMatrix, devOutside, devInside); |
| } |
| GrDrawBatch* Create(GrColor color, |
| const SkMatrix& viewMatrix, |
| const SkRect& rect, |
| const SkStrokeRec& stroke) { |
| - bool isMiterStroke = is_miter(stroke); |
| - AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, isMiterStroke); |
| - |
| - SkRect devOutside, devOutsideAssist, devInside; |
| - bool isDegenerate; |
| - compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, viewMatrix, |
| - rect, stroke.getWidth(), isMiterStroke); |
| - |
| - batch->append(color, devOutside, devOutsideAssist, devInside, isDegenerate); |
| - batch->init(); |
| - return batch; |
| + return new AAStrokeRectBatch(color, viewMatrix, rect, stroke); |
| } |
| -bool Append(GrBatch* origBatch, |
| - GrColor color, |
| - const SkMatrix& viewMatrix, |
| - const SkRect& rect, |
| - const SkStrokeRec& stroke) { |
| - AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>(); |
| - |
| - // we can't batch across vm changes |
| - bool isMiterStroke = is_miter(stroke); |
| - if (!batch->canAppend(viewMatrix, isMiterStroke)) { |
| - return false; |
| - } |
| - |
| - SkRect devOutside, devOutsideAssist, devInside; |
| - bool isDegenerate; |
| - compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, viewMatrix, |
| - rect, stroke.getWidth(), isMiterStroke); |
| - |
| - batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside, isDegenerate); |
| - return true; |
| } |
| -}; |
| - |
| /////////////////////////////////////////////////////////////////////////////////////////////////// |
| #ifdef GR_TEST_UTILS |