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 |