Remove HairlineAA from the clip-edge types.

GrQuadEffect and GrConicEffect were the only FPs that supported the
HairlineAA clip-edge type. These FPs have been updated to implicitly
always use HairlineAA, and other FPs no longer need to consider the
HairlineAA case.

This CL also updates the bezier-effects GM images to remove the non-
hairline test columns.

Change-Id: Ice942106344cf48480e972da4aab1c6055f9911e
Bug: skia:10393
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297019
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
John Stiles 2020-06-17 12:45:57 -04:00 committed by Skia Commit-Bot
parent abae40299c
commit 3b2c06c46b
14 changed files with 150 additions and 310 deletions

View File

@ -78,11 +78,10 @@ public:
}
protected:
BezierTestOp(GrClipEdgeType et, const SkRect& rect, const SkPMColor4f& color, int32_t classID)
BezierTestOp(const SkRect& rect, const SkPMColor4f& color, int32_t classID)
: INHERITED(classID)
, fRect(rect)
, fColor(color)
, fEdgeType(et)
, fProcessorSet(SkBlendMode::kSrc) {
this->setBounds(rect, HasAABloat::kYes, IsHairline::kNo);
}
@ -125,8 +124,6 @@ protected:
flushState->drawMesh(*fMesh);
}
GrClipEdgeType edgeType() const { return fEdgeType; }
const SkRect& rect() const { return fRect; }
const SkPMColor4f& color() const { return fColor; }
@ -136,7 +133,6 @@ protected:
private:
SkRect fRect;
SkPMColor4f fColor;
GrClipEdgeType fEdgeType;
GrProcessorSet fProcessorSet;
GrProgramInfo* fProgramInfo = nullptr;
@ -153,21 +149,20 @@ public:
const char* name() const final { return "BezierConicTestOp"; }
static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
GrClipEdgeType et,
const SkRect& rect,
const SkPMColor4f& color,
const SkMatrix& klm) {
GrOpMemoryPool* pool = context->priv().opMemoryPool();
return pool->allocate<BezierConicTestOp>(et, rect, color, klm);
return pool->allocate<BezierConicTestOp>(rect, color, klm);
}
private:
friend class ::GrOpMemoryPool; // for ctor
BezierConicTestOp(GrClipEdgeType et, const SkRect& rect,
const SkPMColor4f& color, const SkMatrix& klm)
: INHERITED(et, rect, color, ClassID()), fKLM(klm) {}
BezierConicTestOp(const SkRect& rect, const SkPMColor4f& color, const SkMatrix& klm)
: INHERITED(rect, color, ClassID())
, fKLM(klm) {}
struct Vertex {
SkPoint fPosition;
@ -175,8 +170,8 @@ private:
};
GrGeometryProcessor* makeGP(const GrCaps& caps, SkArenaAlloc* arena) final {
auto tmp = GrConicEffect::Make(arena, this->color(), SkMatrix::I(), this->edgeType(),
caps, SkMatrix::I(), false);
auto tmp = GrConicEffect::Make(arena, this->color(), SkMatrix::I(), caps, SkMatrix::I(),
false);
if (!tmp) {
return nullptr;
}
@ -228,7 +223,7 @@ protected:
}
SkISize onISize() override {
return SkISize::Make(kGrClipEdgeTypeCnt*kCellWidth, kNumConics*kCellHeight);
return SkISize::Make(kCellWidth, kNumConics*kCellHeight);
}
void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
@ -270,43 +265,39 @@ protected:
for (int row = 0; row < kNumConics; ++row) {
for(int col = 0; col < kGrClipEdgeTypeCnt; ++col) {
GrClipEdgeType et = (GrClipEdgeType) col;
SkScalar x = 0;
SkScalar y = row * h;
SkPoint controlPts[] = {
{x + baseControlPts[row][0].fX, y + baseControlPts[row][0].fY},
{x + baseControlPts[row][1].fX, y + baseControlPts[row][1].fY},
{x + baseControlPts[row][2].fX, y + baseControlPts[row][2].fY}
};
SkScalar x = col * w;
SkScalar y = row * h;
SkPoint controlPts[] = {
{x + baseControlPts[row][0].fX, y + baseControlPts[row][0].fY},
{x + baseControlPts[row][1].fX, y + baseControlPts[row][1].fY},
{x + baseControlPts[row][2].fX, y + baseControlPts[row][2].fY}
};
for (int i = 0; i < 3; ++i) {
canvas->drawCircle(controlPts[i], 6.f, ctrlPtPaint);
}
canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
SkConic dst[4];
SkMatrix klm;
int cnt = ChopConic(controlPts, dst, weights[row]);
GrPathUtils::getConicKLM(controlPts, weights[row], &klm);
for (int c = 0; c < cnt; ++c) {
SkPoint* pts = dst[c].fPts;
for (int i = 0; i < 3; ++i) {
canvas->drawCircle(controlPts[i], 6.f, ctrlPtPaint);
canvas->drawCircle(pts[i], 3.f, choppedPtPaint);
}
canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
SkRect bounds;
bounds.setBounds(pts, 3);
SkConic dst[4];
SkMatrix klm;
int cnt = ChopConic(controlPts, dst, weights[row]);
GrPathUtils::getConicKLM(controlPts, weights[row], &klm);
canvas->drawRect(bounds, boundsPaint);
for (int c = 0; c < cnt; ++c) {
SkPoint* pts = dst[c].fPts;
for (int i = 0; i < 3; ++i) {
canvas->drawCircle(pts[i], 3.f, choppedPtPaint);
}
SkRect bounds;
bounds.setBounds(pts, 3);
canvas->drawRect(bounds, boundsPaint);
std::unique_ptr<GrDrawOp> op = BezierConicTestOp::Make(context, et, bounds,
kOpaqueBlack, klm);
renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
}
std::unique_ptr<GrDrawOp> op = BezierConicTestOp::Make(context, bounds,
kOpaqueBlack, klm);
renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
}
}
}
@ -363,21 +354,21 @@ public:
const char* name() const override { return "BezierQuadTestOp"; }
static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
GrClipEdgeType et,
const SkRect& rect,
const SkPMColor4f& color,
const GrPathUtils::QuadUVMatrix& devToUV) {
GrOpMemoryPool* pool = context->priv().opMemoryPool();
return pool->allocate<BezierQuadTestOp>(et, rect, color, devToUV);
return pool->allocate<BezierQuadTestOp>(rect, color, devToUV);
}
private:
friend class ::GrOpMemoryPool; // for ctor
BezierQuadTestOp(GrClipEdgeType et, const SkRect& rect,
const SkPMColor4f& color, const GrPathUtils::QuadUVMatrix& devToUV)
: INHERITED(et, rect, color, ClassID()), fDevToUV(devToUV) {}
BezierQuadTestOp(const SkRect& rect, const SkPMColor4f& color,
const GrPathUtils::QuadUVMatrix& devToUV)
: INHERITED(rect, color, ClassID())
, fDevToUV(devToUV) {}
struct Vertex {
SkPoint fPosition;
@ -385,8 +376,8 @@ private:
};
GrGeometryProcessor* makeGP(const GrCaps& caps, SkArenaAlloc* arena) final {
auto tmp = GrQuadEffect::Make(arena, this->color(), SkMatrix::I(), this->edgeType(),
caps, SkMatrix::I(), false);
auto tmp = GrQuadEffect::Make(arena, this->color(), SkMatrix::I(), caps, SkMatrix::I(),
false);
if (!tmp) {
return nullptr;
}
@ -434,7 +425,7 @@ protected:
}
SkISize onISize() override {
return SkISize::Make(kGrClipEdgeTypeCnt*kCellWidth, kNumQuads*kCellHeight);
return SkISize::Make(kCellWidth, kNumQuads*kCellHeight);
}
void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
@ -468,44 +459,40 @@ protected:
boundsPaint.setStyle(SkPaint::kStroke_Style);
for (int row = 0; row < kNumQuads; ++row) {
for(int col = 0; col < kGrClipEdgeTypeCnt; ++col) {
GrClipEdgeType et = (GrClipEdgeType) col;
SkScalar x = 0;
SkScalar y = row * h;
SkPoint controlPts[] = {
{x + baseControlPts[row][0].fX, y + baseControlPts[row][0].fY},
{x + baseControlPts[row][1].fX, y + baseControlPts[row][1].fY},
{x + baseControlPts[row][2].fX, y + baseControlPts[row][2].fY}
};
SkScalar x = col * w;
SkScalar y = row * h;
SkPoint controlPts[] = {
{x + baseControlPts[row][0].fX, y + baseControlPts[row][0].fY},
{x + baseControlPts[row][1].fX, y + baseControlPts[row][1].fY},
{x + baseControlPts[row][2].fX, y + baseControlPts[row][2].fY}
};
for (int i = 0; i < 3; ++i) {
canvas->drawCircle(controlPts[i], 6.f, ctrlPtPaint);
}
canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
SkPoint chopped[5];
int cnt = SkChopQuadAtMaxCurvature(controlPts, chopped);
for (int c = 0; c < cnt; ++c) {
SkPoint* pts = chopped + 2 * c;
for (int i = 0; i < 3; ++i) {
canvas->drawCircle(controlPts[i], 6.f, ctrlPtPaint);
canvas->drawCircle(pts[i], 3.f, choppedPtPaint);
}
canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
SkRect bounds;
bounds.setBounds(pts, 3);
SkPoint chopped[5];
int cnt = SkChopQuadAtMaxCurvature(controlPts, chopped);
canvas->drawRect(bounds, boundsPaint);
for (int c = 0; c < cnt; ++c) {
SkPoint* pts = chopped + 2 * c;
GrPathUtils::QuadUVMatrix DevToUV(pts);
for (int i = 0; i < 3; ++i) {
canvas->drawCircle(pts[i], 3.f, choppedPtPaint);
}
SkRect bounds;
bounds.setBounds(pts, 3);
canvas->drawRect(bounds, boundsPaint);
GrPathUtils::QuadUVMatrix DevToUV(pts);
std::unique_ptr<GrDrawOp> op = BezierQuadTestOp::Make(context, et, bounds,
kOpaqueBlack, DevToUV);
renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
}
std::unique_ptr<GrDrawOp> op = BezierQuadTestOp::Make(context, bounds,
kOpaqueBlack, DevToUV);
renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
}
}
}

View File

@ -15,17 +15,15 @@
/**
* We have coverage effects that clip rendering to the edge of some geometric primitive.
* This enum specifies how that clipping is performed. Not all factories that take a
* GrProcessorEdgeType will succeed with all values and it is up to the caller to check for
* a NULL return.
* GrProcessorEdgeType will succeed with all values and it is up to the caller to verify success.
*/
enum class GrClipEdgeType {
kFillBW,
kFillAA,
kInverseFillBW,
kInverseFillAA,
kHairlineAA,
kLast = kHairlineAA
kLast = kInverseFillAA
};
enum class PMConversion {

View File

@ -655,10 +655,8 @@ static inline GrClipEdgeType GrInvertProcessorEdgeType(const GrClipEdgeType edge
return GrClipEdgeType::kFillBW;
case GrClipEdgeType::kInverseFillAA:
return GrClipEdgeType::kFillAA;
case GrClipEdgeType::kHairlineAA:
SK_ABORT("Hairline fill isn't invertible.");
}
return GrClipEdgeType::kFillAA; // suppress warning.
SkUNREACHABLE;
}
/**

View File

@ -51,7 +51,6 @@ private:
SkMatrix fViewMatrix;
SkPMColor4f fColor;
uint8_t fCoverageScale;
GrClipEdgeType fEdgeType;
UniformHandle fColorUniform;
UniformHandle fCoverageScaleUniform;
UniformHandle fViewMatrixUniform;
@ -60,10 +59,9 @@ private:
};
GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor)
: fViewMatrix(SkMatrix::InvalidMatrix()), fColor(SK_PMColor4fILLEGAL), fCoverageScale(0xff) {
const GrConicEffect& ce = processor.cast<GrConicEffect>();
fEdgeType = ce.getEdgeType();
}
: fViewMatrix(SkMatrix::InvalidMatrix())
, fColor(SK_PMColor4fILLEGAL)
, fCoverageScale(0xff) {}
void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
@ -120,74 +118,31 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
fragBuilder->declAppend(gFM);
fragBuilder->declAppend(func);
switch (fEdgeType) {
case GrClipEdgeType::kHairlineAA: {
fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdx.c_str(),
v.fsIn(), dklmdx.c_str(),
v.fsIn(), dklmdx.c_str(),
v.fsIn(), dklmdx.c_str());
fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdy.c_str(),
v.fsIn(), dklmdy.c_str(),
v.fsIn(), dklmdy.c_str(),
v.fsIn(), dklmdy.c_str());
fragBuilder->codeAppendf("%s = float2(%s, %s);", gF.c_str(), dfdx.c_str(),
dfdy.c_str());
fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
gFM.c_str(), gF.c_str(), gF.c_str());
fragBuilder->codeAppendf("%s = %s.x*%s.x - %s.y*%s.z;",
func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
fragBuilder->codeAppendf("%s = half(%s / %s);",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
edgeAlpha.c_str(), edgeAlpha.c_str());
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
break;
}
case GrClipEdgeType::kFillAA: {
fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s ="
"2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdx.c_str(),
v.fsIn(), dklmdx.c_str(),
v.fsIn(), dklmdx.c_str(),
v.fsIn(), dklmdx.c_str());
fragBuilder->codeAppendf("%s ="
"2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdy.c_str(),
v.fsIn(), dklmdy.c_str(),
v.fsIn(), dklmdy.c_str(),
v.fsIn(), dklmdy.c_str());
fragBuilder->codeAppendf("%s = float2(%s, %s);", gF.c_str(), dfdx.c_str(),
dfdy.c_str());
fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
gFM.c_str(), gF.c_str(), gF.c_str());
fragBuilder->codeAppendf("%s = %s.x * %s.x - %s.y * %s.z;",
func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = half(%s / %s);",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
fragBuilder->codeAppendf("%s = saturate(0.5 - %s);",
edgeAlpha.c_str(), edgeAlpha.c_str());
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
break;
}
case GrClipEdgeType::kFillBW: {
fragBuilder->codeAppendf("%s = half(%s.x * %s.x - %s.y * %s.z);",
edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = half(%s < 0.0);",
edgeAlpha.c_str(), edgeAlpha.c_str());
break;
}
default:
SK_ABORT("Shouldn't get here");
}
fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdx.c_str(),
v.fsIn(), dklmdx.c_str(),
v.fsIn(), dklmdx.c_str(),
v.fsIn(), dklmdx.c_str());
fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdy.c_str(),
v.fsIn(), dklmdy.c_str(),
v.fsIn(), dklmdy.c_str(),
v.fsIn(), dklmdy.c_str());
fragBuilder->codeAppendf("%s = float2(%s, %s);", gF.c_str(), dfdx.c_str(),
dfdy.c_str());
fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
gFM.c_str(), gF.c_str(), gF.c_str());
fragBuilder->codeAppendf("%s = %s.x*%s.x - %s.y*%s.z;",
func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
fragBuilder->codeAppendf("%s = half(%s / %s);",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
edgeAlpha.c_str(), edgeAlpha.c_str());
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
// TODO should we really be doing this?
if (gp.coverageScale() != 0xff) {
@ -231,15 +186,13 @@ GrGLSLPrimitiveProcessor* GrConicEffect::createGLSLInstance(const GrShaderCaps&)
}
GrConicEffect::GrConicEffect(const SkPMColor4f& color, const SkMatrix& viewMatrix, uint8_t coverage,
GrClipEdgeType edgeType, const SkMatrix& localMatrix,
bool usesLocalCoords)
const SkMatrix& localMatrix, bool usesLocalCoords)
: INHERITED(kGrConicEffect_ClassID)
, fColor(color)
, fViewMatrix(viewMatrix)
, fLocalMatrix(viewMatrix)
, fUsesLocalCoords(usesLocalCoords)
, fCoverageScale(coverage)
, fEdgeType(edgeType) {
, fCoverageScale(coverage) {
this->setVertexAttributes(kAttributes, SK_ARRAY_COUNT(kAttributes));
}
@ -249,17 +202,10 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
#if GR_TEST_UTILS
GrGeometryProcessor* GrConicEffect::TestCreate(GrProcessorTestData* d) {
GrGeometryProcessor* gp;
do {
GrClipEdgeType edgeType =
static_cast<GrClipEdgeType>(
d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
gp = GrConicEffect::Make(d->allocator(),
SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)),
GrTest::TestMatrix(d->fRandom), edgeType, *d->caps(),
GrTest::TestMatrix(d->fRandom), d->fRandom->nextBool());
} while (nullptr == gp);
return gp;
return GrConicEffect::Make(d->allocator(),
SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)),
GrTest::TestMatrix(d->fRandom), *d->caps(),
GrTest::TestMatrix(d->fRandom), d->fRandom->nextBool());
}
#endif
@ -304,7 +250,6 @@ private:
SkMatrix fViewMatrix;
SkPMColor4f fColor;
uint8_t fCoverageScale;
GrClipEdgeType fEdgeType;
UniformHandle fColorUniform;
UniformHandle fCoverageScaleUniform;
UniformHandle fViewMatrixUniform;
@ -313,10 +258,9 @@ private:
};
GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor)
: fViewMatrix(SkMatrix::InvalidMatrix()), fColor(SK_PMColor4fILLEGAL), fCoverageScale(0xff) {
const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
fEdgeType = ce.getEdgeType();
}
: fViewMatrix(SkMatrix::InvalidMatrix())
, fColor(SK_PMColor4fILLEGAL)
, fCoverageScale(0xff) {}
void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
@ -353,44 +297,17 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
fragBuilder->codeAppendf("half edgeAlpha;");
switch (fEdgeType) {
case GrClipEdgeType::kHairlineAA: {
fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 gF = half2(2.0 * %s.x * duvdx.x - duvdx.y,"
" 2.0 * %s.x * duvdy.x - duvdy.y);",
v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
break;
}
case GrClipEdgeType::kFillAA: {
fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 gF = half2(2.0 * %s.x * duvdx.x - duvdx.y,"
" 2.0 * %s.x * duvdy.x - duvdy.y);",
v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
fragBuilder->codeAppend("edgeAlpha = saturate(0.5 - edgeAlpha);");
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
break;
}
case GrClipEdgeType::kFillBW: {
fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = half(edgeAlpha < 0.0);");
break;
}
default:
SK_ABORT("Shouldn't get here");
}
fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 gF = half2(2.0 * %s.x * duvdx.x - duvdx.y,"
" 2.0 * %s.x * duvdy.x - duvdy.y);",
v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
if (0xff != gp.coverageScale()) {
const char* coverageScale;
@ -433,15 +350,13 @@ GrGLSLPrimitiveProcessor* GrQuadEffect::createGLSLInstance(const GrShaderCaps&)
}
GrQuadEffect::GrQuadEffect(const SkPMColor4f& color, const SkMatrix& viewMatrix, uint8_t coverage,
GrClipEdgeType edgeType, const SkMatrix& localMatrix,
bool usesLocalCoords)
const SkMatrix& localMatrix, bool usesLocalCoords)
: INHERITED(kGrQuadEffect_ClassID)
, fColor(color)
, fViewMatrix(viewMatrix)
, fLocalMatrix(localMatrix)
, fUsesLocalCoords(usesLocalCoords)
, fCoverageScale(coverage)
, fEdgeType(edgeType) {
, fCoverageScale(coverage) {
this->setVertexAttributes(kAttributes, SK_ARRAY_COUNT(kAttributes));
}
@ -451,15 +366,9 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
#if GR_TEST_UTILS
GrGeometryProcessor* GrQuadEffect::TestCreate(GrProcessorTestData* d) {
GrGeometryProcessor* gp;
do {
GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(
d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
gp = GrQuadEffect::Make(d->allocator(),
SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)),
GrTest::TestMatrix(d->fRandom), edgeType, *d->caps(),
GrTest::TestMatrix(d->fRandom), d->fRandom->nextBool());
} while (nullptr == gp);
return gp;
return GrQuadEffect::Make(d->allocator(),
SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)),
GrTest::TestMatrix(d->fRandom), *d->caps(),
GrTest::TestMatrix(d->fRandom), d->fRandom->nextBool());
}
#endif

View File

@ -61,25 +61,15 @@ public:
static GrGeometryProcessor* Make(SkArenaAlloc* arena,
const SkPMColor4f& color,
const SkMatrix& viewMatrix,
const GrClipEdgeType edgeType,
const GrCaps& caps,
const SkMatrix& localMatrix,
bool usesLocalCoords,
uint8_t coverage = 0xff) {
switch (edgeType) {
case GrClipEdgeType::kFillAA: // fall through
case GrClipEdgeType::kHairlineAA:
if (!caps.shaderCaps()->shaderDerivativeSupport()) {
return nullptr;
}
break;
case GrClipEdgeType::kFillBW:
break;
default: // kInverseFillBW or kInverseFillAA
return nullptr;
if (!caps.shaderCaps()->shaderDerivativeSupport()) {
return nullptr;
}
return arena->make<GrConicEffect>(color, viewMatrix, coverage, edgeType, localMatrix,
return arena->make<GrConicEffect>(color, viewMatrix, coverage, localMatrix,
usesLocalCoords);
}
@ -89,9 +79,8 @@ public:
inline const Attribute& inPosition() const { return kAttributes[0]; }
inline const Attribute& inConicCoeffs() const { return kAttributes[1]; }
inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
inline GrClipEdgeType getEdgeType() const { return fEdgeType; }
inline bool isAntiAliased() const { return true; }
inline bool isFilled() const { return false; }
const SkPMColor4f& color() const { return fColor; }
const SkMatrix& viewMatrix() const { return fViewMatrix; }
const SkMatrix& localMatrix() const { return fLocalMatrix; }
@ -105,7 +94,7 @@ public:
private:
friend class ::SkArenaAlloc; // for access to ctor
GrConicEffect(const SkPMColor4f&, const SkMatrix& viewMatrix, uint8_t coverage, GrClipEdgeType,
GrConicEffect(const SkPMColor4f&, const SkMatrix& viewMatrix, uint8_t coverage,
const SkMatrix& localMatrix, bool usesLocalCoords);
SkPMColor4f fColor;
@ -113,7 +102,6 @@ private:
SkMatrix fLocalMatrix;
bool fUsesLocalCoords;
uint8_t fCoverageScale;
GrClipEdgeType fEdgeType;
static constexpr Attribute kAttributes[] = {
{"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType},
{"inConicCoeffs", kFloat4_GrVertexAttribType, kHalf4_GrSLType}
@ -140,26 +128,15 @@ public:
static GrGeometryProcessor* Make(SkArenaAlloc* arena,
const SkPMColor4f& color,
const SkMatrix& viewMatrix,
const GrClipEdgeType edgeType,
const GrCaps& caps,
const SkMatrix& localMatrix,
bool usesLocalCoords,
uint8_t coverage = 0xff) {
switch (edgeType) {
case GrClipEdgeType::kFillAA: // fall through
case GrClipEdgeType::kHairlineAA:
if (!caps.shaderCaps()->shaderDerivativeSupport()) {
return nullptr;
}
break;
case GrClipEdgeType::kFillBW:
break;
default: // kInverseFillBW and kInverseFillAA
return nullptr;
if (!caps.shaderCaps()->shaderDerivativeSupport()) {
return nullptr;
}
return arena->make<GrQuadEffect>(color, viewMatrix, coverage, edgeType,
localMatrix, usesLocalCoords);
return arena->make<GrQuadEffect>(color, viewMatrix, coverage, localMatrix, usesLocalCoords);
}
~GrQuadEffect() override;
@ -168,9 +145,8 @@ public:
inline const Attribute& inPosition() const { return kAttributes[0]; }
inline const Attribute& inHairQuadEdge() const { return kAttributes[1]; }
inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
inline GrClipEdgeType getEdgeType() const { return fEdgeType; }
inline bool isAntiAliased() const { return true; }
inline bool isFilled() const { return false; }
const SkPMColor4f& color() const { return fColor; }
const SkMatrix& viewMatrix() const { return fViewMatrix; }
const SkMatrix& localMatrix() const { return fLocalMatrix; }
@ -184,7 +160,7 @@ public:
private:
friend class ::SkArenaAlloc; // for access to ctor
GrQuadEffect(const SkPMColor4f&, const SkMatrix& viewMatrix, uint8_t coverage, GrClipEdgeType,
GrQuadEffect(const SkPMColor4f&, const SkMatrix& viewMatrix, uint8_t coverage,
const SkMatrix& localMatrix, bool usesLocalCoords);
SkPMColor4f fColor;
@ -192,7 +168,6 @@ private:
SkMatrix fLocalMatrix;
bool fUsesLocalCoords;
uint8_t fCoverageScale;
GrClipEdgeType fEdgeType;
static constexpr Attribute kAttributes[] = {
{"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType},

View File

@ -65,8 +65,7 @@ void main() {
}
half4 inputColor = sample(inputFP, sk_InColor);
@if (edgeType == GrClipEdgeType::kFillAA ||
edgeType == GrClipEdgeType::kInverseFillAA ||
edgeType == GrClipEdgeType::kHairlineAA) {
edgeType == GrClipEdgeType::kInverseFillAA) {
sk_OutColor = inputColor * saturate(d);
} else {
sk_OutColor = d > 0.5 ? inputColor : half4(0);
@ -78,9 +77,6 @@ void main() {
center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
SkScalar radius = testData->fRandom->nextRangeF(1.f, 1000.f);
GrClipEdgeType et;
do {
et = (GrClipEdgeType) testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
} while (GrClipEdgeType::kHairlineAA == et);
GrClipEdgeType et = (GrClipEdgeType) testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
return GrCircleEffect::Make(/*inputFP=*/nullptr, et, center, radius);
}

View File

@ -97,9 +97,6 @@ void GrGLConvexPolyEffect::GenKey(const GrProcessor& processor, const GrShaderCa
GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType type, const SkPath& path) {
if (GrClipEdgeType::kHairlineAA == type) {
return MakeFailure(std::move(inputFP));
}
if (path.getSegmentMasks() != SkPath::kLine_SegmentMask || !path.isConvex()) {
return MakeFailure(std::move(inputFP));
}
@ -173,10 +170,7 @@ GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, const SkRect& rect) {
if (GrClipEdgeType::kHairlineAA == edgeType) {
return MakeFailure(std::move(inputFP));
}
// TODO: Replace calls to this method with calling GrAARectEffect::Make directly
return MakeSuccess(GrAARectEffect::Make(std::move(inputFP), edgeType, rect));
}

View File

@ -38,7 +38,7 @@ public:
*/
static MakeResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, int n, const SkScalar edges[]) {
if (n <= 0 || n > kMaxEdges || GrClipEdgeType::kHairlineAA == edgeType) {
if (n <= 0 || n > kMaxEdges) {
return MakeFailure(std::move(inputFP));
}

View File

@ -130,10 +130,7 @@ void main() {
center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
SkScalar rx = testData->fRandom->nextRangeF(0.f, 1000.f);
SkScalar ry = testData->fRandom->nextRangeF(0.f, 1000.f);
GrClipEdgeType et;
do {
et = (GrClipEdgeType) testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
} while (GrClipEdgeType::kHairlineAA == et);
GrClipEdgeType et = (GrClipEdgeType) testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
return GrEllipseEffect::Make(/*inputFP=*/nullptr, et, center, SkPoint::Make(rx, ry),
*testData->caps()->shaderCaps());
}

View File

@ -14,9 +14,6 @@
std::unique_ptr<GrFragmentProcessor> GrOvalEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP, GrClipEdgeType edgeType,
const SkRect& oval, const GrShaderCaps& caps) {
if (GrClipEdgeType::kHairlineAA == edgeType) {
return nullptr;
}
SkScalar w = oval.width();
SkScalar h = oval.height();
if (SkScalarNearlyEqual(w, h)) {

View File

@ -51,11 +51,10 @@ public:
_sample2569 = _input2569;
}
fragBuilder->codeAppendf(
"\nhalf4 inputColor = %s;\n@if ((%d == 1 || %d == 3) || %d == 4) {\n %s = "
"inputColor * clamp(d, 0.0, 1.0);\n} else {\n %s = d > 0.5 ? inputColor : "
"half4(0.0);\n}\n",
_sample2569.c_str(), (int)_outer.edgeType, (int)_outer.edgeType,
(int)_outer.edgeType, args.fOutputColor, args.fOutputColor);
"\nhalf4 inputColor = %s;\n@if (%d == 1 || %d == 3) {\n %s = inputColor * "
"clamp(d, 0.0, 1.0);\n} else {\n %s = d > 0.5 ? inputColor : half4(0.0);\n}\n",
_sample2569.c_str(), (int)_outer.edgeType, (int)_outer.edgeType, args.fOutputColor,
args.fOutputColor);
}
private:
@ -125,10 +124,7 @@ std::unique_ptr<GrFragmentProcessor> GrCircleEffect::TestCreate(GrProcessorTestD
center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
SkScalar radius = testData->fRandom->nextRangeF(1.f, 1000.f);
GrClipEdgeType et;
do {
et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
} while (GrClipEdgeType::kHairlineAA == et);
GrClipEdgeType et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
return GrCircleEffect::Make(/*inputFP=*/nullptr, et, center, radius);
}
#endif

View File

@ -150,10 +150,7 @@ std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::TestCreate(GrProcessorTest
center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
SkScalar rx = testData->fRandom->nextRangeF(0.f, 1000.f);
SkScalar ry = testData->fRandom->nextRangeF(0.f, 1000.f);
GrClipEdgeType et;
do {
et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
} while (GrClipEdgeType::kHairlineAA == et);
GrClipEdgeType et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
return GrEllipseEffect::Make(/*inputFP=*/nullptr, et, center, SkPoint::Make(rx, ry),
*testData->caps()->shaderCaps());
}

View File

@ -1011,7 +1011,6 @@ void AAHairlineOp::makeQuadProgramInfo(const GrCaps& caps, SkArenaAlloc* arena,
GrGeometryProcessor* quadGP = GrQuadEffect::Make(arena,
this->color(),
*geometryProcessorViewM,
GrClipEdgeType::kHairlineAA,
caps,
*geometryProcessorLocalM,
fHelper.usesLocalCoords(),
@ -1034,7 +1033,6 @@ void AAHairlineOp::makeConicProgramInfo(const GrCaps& caps, SkArenaAlloc* arena,
GrGeometryProcessor* conicGP = GrConicEffect::Make(arena,
this->color(),
*geometryProcessorViewM,
GrClipEdgeType::kHairlineAA,
caps,
*geometryProcessorLocalM,
fHelper.usesLocalCoords(),

View File

@ -13,17 +13,15 @@ R"(/*
/**
* We have coverage effects that clip rendering to the edge of some geometric primitive.
* This enum specifies how that clipping is performed. Not all factories that take a
* GrProcessorEdgeType will succeed with all values and it is up to the caller to check for
* a NULL return.
* GrProcessorEdgeType will succeed with all values and it is up to the caller to verify success.
*/
enum class GrClipEdgeType {
kFillBW,
kFillAA,
kInverseFillBW,
kInverseFillAA,
kHairlineAA,
kLast = kHairlineAA
kLast = kInverseFillAA
};
enum class PMConversion {