Hide geometry class in AAStrokeRectBatch and remove unused Append function.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2119813004 Review-Url: https://codereview.chromium.org/2119813004
This commit is contained in:
parent
069c464a6b
commit
8b7a9e1e5a
@ -21,6 +21,79 @@ static void set_inset_fan(SkPoint* pts, size_t stride,
|
||||
r.fRight - dx, r.fBottom - dy, stride);
|
||||
}
|
||||
|
||||
// We support all hairlines, bevels, and miters, but not round joins. Also, check whether the miter
|
||||
// limit makes a miter join effectively beveled.
|
||||
inline static bool allowed_stroke(const SkStrokeRec& stroke, bool* isMiter) {
|
||||
SkASSERT(stroke.getStyle() == SkStrokeRec::kStroke_Style ||
|
||||
stroke.getStyle() == SkStrokeRec::kHairline_Style);
|
||||
// For hairlines, make bevel and round joins appear the same as mitered ones.
|
||||
if (!stroke.getWidth()) {
|
||||
*isMiter = true;
|
||||
return true;
|
||||
}
|
||||
if (stroke.getJoin() == SkPaint::kBevel_Join) {
|
||||
*isMiter = false;
|
||||
return true;
|
||||
}
|
||||
if (stroke.getJoin() == SkPaint::kMiter_Join) {
|
||||
*isMiter = stroke.getMiter() >= SK_ScalarSqrt2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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 +120,36 @@ 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())
|
||||
, fViewMatrix(viewMatrix) {
|
||||
SkASSERT(!devOutside.isEmpty())
|
||||
SkASSERT(!devInside.isEmpty())
|
||||
|
||||
static AAStrokeRectBatch* Create(const SkMatrix& viewMatrix, bool miterStroke) {
|
||||
return new AAStrokeRectBatch(viewMatrix, miterStroke);
|
||||
fGeoData.emplace_back(Geometry{color, devOutside, devOutside, devInside, false});
|
||||
fBounds = devOutside;
|
||||
fMiterStroke = true;
|
||||
}
|
||||
|
||||
|
||||
static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
|
||||
const SkStrokeRec& stroke) {
|
||||
bool isMiter;
|
||||
if (!allowed_stroke(stroke, &isMiter)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AAStrokeRectBatch* batch = new AAStrokeRectBatch();
|
||||
batch->fMiterStroke = isMiter;
|
||||
Geometry& geo = batch->fGeoData.push_back();
|
||||
compute_rects(&geo.fDevOutside, &geo.fDevOutsideAssist, &geo.fDevInside, &geo.fDegenerate,
|
||||
viewMatrix, rect, stroke.getWidth(), isMiter);
|
||||
geo.fColor = color;
|
||||
batch->fBounds = geo.fDevOutside;
|
||||
batch->fBounds.join(geo.fDevOutsideAssist);
|
||||
batch->fViewMatrix = viewMatrix;
|
||||
return batch;
|
||||
}
|
||||
|
||||
const char* name() const override { return "AAStrokeRect"; }
|
||||
@ -70,51 +162,12 @@ 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);
|
||||
}
|
||||
AAStrokeRectBatch() : INHERITED(ClassID()) {}
|
||||
|
||||
void onPrepareDraws(Target*) const override;
|
||||
void initBatchTracker(const GrXPOverridesForBatch&) override;
|
||||
|
||||
AAStrokeRectBatch(const SkMatrix& viewMatrix,bool miterStroke)
|
||||
: INHERITED(ClassID()) {
|
||||
fViewMatrix = viewMatrix;
|
||||
fMiterStroke = miterStroke;
|
||||
}
|
||||
|
||||
static const int kMiterIndexCnt = 3 * 24;
|
||||
static const int kMiterVertexCnt = 16;
|
||||
static const int kNumMiterRectsInIndexBuffer = 256;
|
||||
@ -130,7 +183,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 +209,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 +413,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,114 +577,23 @@ void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices,
|
||||
}
|
||||
}
|
||||
|
||||
// We support all hairlines, bevels, and miters, but not round joins. Also, check whether the miter
|
||||
// limit makes a miter join effectively beveled.
|
||||
inline static bool allowed_stroke(const SkStrokeRec& stroke, bool* isMiter) {
|
||||
SkASSERT(stroke.getStyle() == SkStrokeRec::kStroke_Style ||
|
||||
stroke.getStyle() == SkStrokeRec::kHairline_Style);
|
||||
// For hairlines, make bevel and round joins appear the same as mitered ones.
|
||||
if (!stroke.getWidth()) {
|
||||
*isMiter = true;
|
||||
return true;
|
||||
}
|
||||
if (stroke.getJoin() == SkPaint::kBevel_Join) {
|
||||
*isMiter = false;
|
||||
return true;
|
||||
}
|
||||
if (stroke.getJoin() == SkPaint::kMiter_Join) {
|
||||
*isMiter = stroke.getMiter() >= SK_ScalarSqrt2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
if (!allowed_stroke(stroke, &isMiterStroke)) {
|
||||
return nullptr;
|
||||
}
|
||||
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 AAStrokeRectBatch::Create(color, viewMatrix, rect, stroke);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user