aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ccpr
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2017-12-08 10:59:58 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-12-08 20:13:18 +0000
commitbe4ffab4e208ec47b4298621b9c9e8456f31717e (patch)
tree28bee87fec500acab63c2e72c77a6b7a4fd53ba1 /src/gpu/ccpr
parent3f39bf8fe596f87120d189dbec2889b644f07e2d (diff)
CCPR: Combine loops and serpentines back into a single shader
Bug: skia: Change-Id: I945471ccd2580a2d39afd9c80acb8d9e5e196435 Reviewed-on: https://skia-review.googlesource.com/82460 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/gpu/ccpr')
-rw-r--r--src/gpu/ccpr/GrCCPRCoverageOp.cpp39
-rw-r--r--src/gpu/ccpr/GrCCPRCoverageProcessor.cpp40
-rw-r--r--src/gpu/ccpr/GrCCPRCoverageProcessor.h38
-rw-r--r--src/gpu/ccpr/GrCCPRCubicShader.cpp39
-rw-r--r--src/gpu/ccpr/GrCCPRCubicShader.h17
-rw-r--r--src/gpu/ccpr/GrCCPRGeometry.cpp11
-rw-r--r--src/gpu/ccpr/GrCCPRGeometry.h12
7 files changed, 71 insertions, 125 deletions
diff --git a/src/gpu/ccpr/GrCCPRCoverageOp.cpp b/src/gpu/ccpr/GrCCPRCoverageOp.cpp
index 8786ed4338..5775c5aa86 100644
--- a/src/gpu/ccpr/GrCCPRCoverageOp.cpp
+++ b/src/gpu/ccpr/GrCCPRCoverageOp.cpp
@@ -253,11 +253,9 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP,
// that will not overwrite previous TriangleInstance data.
int cubicBaseIdx = GR_CT_DIV_ROUND_UP(triEndIdx * sizeof(TriangleInstance),
sizeof(CubicInstance));
- baseInstances[0].fSerpentines = cubicBaseIdx;
- baseInstances[1].fSerpentines = baseInstances[0].fSerpentines + fTallies[0].fSerpentines;
- baseInstances[0].fLoops = baseInstances[1].fSerpentines + fTallies[1].fSerpentines;
- baseInstances[1].fLoops = baseInstances[0].fLoops + fTallies[0].fLoops;
- int cubicEndIdx = baseInstances[1].fLoops + fTallies[1].fLoops;
+ baseInstances[0].fCubics = cubicBaseIdx;
+ baseInstances[1].fCubics = baseInstances[0].fCubics + fTallies[0].fCubics;
+ int cubicEndIdx = baseInstances[1].fCubics + fTallies[1].fCubics;
sk_sp<GrBuffer> instanceBuffer = onFlushRP->makeBuffer(kVertex_GrBufferType,
cubicEndIdx * sizeof(CubicInstance));
@@ -325,17 +323,10 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP,
currFan.push_back(ptsIdx += 2);
continue;
- case GrCCPRGeometry::Verb::kMonotonicSerpentineTo:
+ case GrCCPRGeometry::Verb::kMonotonicCubicTo:
SkASSERT(!currFan.empty());
- cubicInstanceData[currIndices->fSerpentines++].set(&pts[ptsIdx],
- atlasOffsetX, atlasOffsetY);
- currFan.push_back(ptsIdx += 3);
- continue;
-
- case GrCCPRGeometry::Verb::kMonotonicLoopTo:
- SkASSERT(!currFan.empty());
- cubicInstanceData[currIndices->fLoops++].set(&pts[ptsIdx],
- atlasOffsetX, atlasOffsetY);
+ cubicInstanceData[currIndices->fCubics++].set(&pts[ptsIdx],
+ atlasOffsetX, atlasOffsetY);
currFan.push_back(ptsIdx += 3);
continue;
@@ -375,10 +366,8 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP,
SkASSERT(instanceIndices[1].fTriangles == initialBaseInstances[0].fQuadratics);
SkASSERT(instanceIndices[0].fQuadratics == initialBaseInstances[1].fQuadratics);
SkASSERT(instanceIndices[1].fQuadratics == triEndIdx);
- SkASSERT(instanceIndices[0].fSerpentines == initialBaseInstances[1].fSerpentines);
- SkASSERT(instanceIndices[1].fSerpentines == initialBaseInstances[0].fLoops);
- SkASSERT(instanceIndices[0].fLoops == initialBaseInstances[1].fLoops);
- SkASSERT(instanceIndices[1].fLoops == cubicEndIdx);
+ SkASSERT(instanceIndices[0].fCubics == initialBaseInstances[1].fCubics);
+ SkASSERT(instanceIndices[1].fCubics == cubicEndIdx);
return true;
}
@@ -421,14 +410,10 @@ void GrCCPRCoverageOp::onExecute(GrOpFlushState* flushState) {
// Cubics.
auto constexpr kCubicsGrPrimitiveType = GrCCPRCoverageProcessor::kCubicsGrPrimitiveType;
- this->drawMaskPrimitives(flushState, pipeline, RenderPass::kSerpentineHulls,
- kCubicsGrPrimitiveType, 4, &PrimitiveTallies::fSerpentines);
- this->drawMaskPrimitives(flushState, pipeline, RenderPass::kLoopHulls,
- kCubicsGrPrimitiveType, 4, &PrimitiveTallies::fLoops);
- this->drawMaskPrimitives(flushState, pipeline, RenderPass::kSerpentineCorners,
- kCubicsGrPrimitiveType, 4, &PrimitiveTallies::fSerpentines);
- this->drawMaskPrimitives(flushState, pipeline, RenderPass::kLoopCorners,
- kCubicsGrPrimitiveType, 4, &PrimitiveTallies::fLoops);
+ this->drawMaskPrimitives(flushState, pipeline, RenderPass::kCubicHulls,
+ kCubicsGrPrimitiveType, 4, &PrimitiveTallies::fCubics);
+ this->drawMaskPrimitives(flushState, pipeline, RenderPass::kCubicCorners,
+ kCubicsGrPrimitiveType, 4, &PrimitiveTallies::fCubics);
}
void GrCCPRCoverageOp::drawMaskPrimitives(GrOpFlushState* flushState, const GrPipeline& pipeline,
diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp
index d77324dd6f..61e431a2c9 100644
--- a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp
@@ -111,7 +111,6 @@ void GrCCPRCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&,
GrGLSLPrimitiveProcessor* GrCCPRCoverageProcessor::createGLSLInstance(const GrShaderCaps&) const {
std::unique_ptr<Shader> shader;
switch (fRenderPass) {
- using CubicType = GrCCPRCubicShader::CubicType;
case RenderPass::kTriangleHulls:
shader = skstd::make_unique<GrCCPRTriangleHullShader>();
break;
@@ -127,43 +126,12 @@ GrGLSLPrimitiveProcessor* GrCCPRCoverageProcessor::createGLSLInstance(const GrSh
case RenderPass::kQuadraticCorners:
shader = skstd::make_unique<GrCCPRQuadraticCornerShader>();
break;
- case RenderPass::kSerpentineHulls:
- shader = skstd::make_unique<GrCCPRCubicHullShader>(CubicType::kSerpentine);
+ case RenderPass::kCubicHulls:
+ shader = skstd::make_unique<GrCCPRCubicHullShader>();
break;
- case RenderPass::kLoopHulls:
- shader = skstd::make_unique<GrCCPRCubicHullShader>(CubicType::kLoop);
- break;
- case RenderPass::kSerpentineCorners:
- shader = skstd::make_unique<GrCCPRCubicCornerShader>(CubicType::kSerpentine);
- break;
- case RenderPass::kLoopCorners:
- shader = skstd::make_unique<GrCCPRCubicCornerShader>(CubicType::kLoop);
+ case RenderPass::kCubicCorners:
+ shader = skstd::make_unique<GrCCPRCubicCornerShader>();
break;
}
return CreateGSImpl(std::move(shader));
}
-
-const char* GrCCPRCoverageProcessor::GetRenderPassName(RenderPass renderPass) {
- switch (renderPass) {
- case RenderPass::kTriangleHulls:
- return "RenderPass::kTriangleHulls";
- case RenderPass::kTriangleEdges:
- return "RenderPass::kTriangleEdges";
- case RenderPass::kTriangleCorners:
- return "RenderPass::kTriangleCorners";
- case RenderPass::kQuadraticHulls:
- return "RenderPass::kQuadraticHulls";
- case RenderPass::kQuadraticCorners:
- return "RenderPass::kQuadraticCorners";
- case RenderPass::kSerpentineHulls:
- return "RenderPass::kSerpentineHulls";
- case RenderPass::kLoopHulls:
- return "RenderPass::kLoopHulls";
- case RenderPass::kSerpentineCorners:
- return "RenderPass::kSerpentineCorners";
- case RenderPass::kLoopCorners:
- return "RenderPass::kLoopCorners";
- }
- SK_ABORT("Unexpected GrCCPRCoverageProcessor::RenderPass.");
- return nullptr;
-}
diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.h b/src/gpu/ccpr/GrCCPRCoverageProcessor.h
index 75cc45b8eb..30aa2acdc2 100644
--- a/src/gpu/ccpr/GrCCPRCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.h
@@ -72,17 +72,39 @@ public:
kQuadraticCorners,
// Cubics.
- kSerpentineHulls,
- kLoopHulls,
- kSerpentineCorners,
- kLoopCorners
+ kCubicHulls,
+ kCubicCorners
};
- static constexpr bool RenderPassIsCubic(RenderPass pass) {
- return pass >= RenderPass::kSerpentineHulls && pass <= RenderPass::kLoopCorners;
+ static inline bool RenderPassIsCubic(RenderPass pass) {
+ switch (pass) {
+ case RenderPass::kTriangleHulls:
+ case RenderPass::kTriangleEdges:
+ case RenderPass::kTriangleCorners:
+ case RenderPass::kQuadraticHulls:
+ case RenderPass::kQuadraticCorners:
+ return false;
+ case RenderPass::kCubicHulls:
+ case RenderPass::kCubicCorners:
+ return true;
+ }
+ SK_ABORT("Invalid GrCCPRCoverageProcessor::RenderPass");
+ return false;
}
- static const char* GetRenderPassName(RenderPass);
+ static inline const char* RenderPassName(RenderPass pass) {
+ switch (pass) {
+ case RenderPass::kTriangleHulls: return "kTriangleHulls";
+ case RenderPass::kTriangleEdges: return "kTriangleEdges";
+ case RenderPass::kTriangleCorners: return "kTriangleCorners";
+ case RenderPass::kQuadraticHulls: return "kQuadraticHulls";
+ case RenderPass::kQuadraticCorners: return "kQuadraticCorners";
+ case RenderPass::kCubicHulls: return "kCubicHulls";
+ case RenderPass::kCubicCorners: return "kCubicCorners";
+ }
+ SK_ABORT("Invalid GrCCPRCoverageProcessor::RenderPass");
+ return "";
+ }
/**
* This serves as the base class for each RenderPass's Shader. It indicates what type of
@@ -191,7 +213,7 @@ public:
GrCCPRCoverageProcessor(RenderPass);
- const char* name() const override { return GetRenderPassName(fRenderPass); }
+ const char* name() const override { return RenderPassName(fRenderPass); }
SkString dumpInfo() const override {
return SkStringPrintf("%s\n%s", this->name(), this->INHERITED::dumpInfo().c_str());
}
diff --git a/src/gpu/ccpr/GrCCPRCubicShader.cpp b/src/gpu/ccpr/GrCCPRCubicShader.cpp
index 1c29862bea..4d63e98428 100644
--- a/src/gpu/ccpr/GrCCPRCubicShader.cpp
+++ b/src/gpu/ccpr/GrCCPRCubicShader.cpp
@@ -28,28 +28,25 @@ void GrCCPRCubicShader::emitSetupCode(GrGLSLShaderBuilder* s, const char* pts,
// Calculate the KLM matrix.
s->declareGlobal(fKLMMatrix);
- s->codeAppend ("float4 K, L, M;");
- s->codeAppend ("float2 l, m;");
s->codeAppend ("float discr = 3*D2*D2 - 4*D1*D3;");
- if (CubicType::kSerpentine == fCubicType) {
- // This math also works out for the "cusp" and "cusp at infinity" cases.
- s->codeAppend ("float q = sqrt(max(3*discr, 0));");
- s->codeAppend ("q = 3*D2 + (D2 >= 0 ? q : -q);");
- s->codeAppend ("l.ts = normalize(float2(q, 6*D1));");
- s->codeAppend ("m.ts = discr <= 0 ? l.ts : normalize(float2(2*D3, q));");
- s->codeAppend ("K = float4(0, l.s * m.s, -l.t * m.s - m.t * l.s, l.t * m.t);");
- s->codeAppend ("L = float4(-1,3,-3,1) * l.ssst * l.sstt * l.sttt;");
- s->codeAppend ("M = float4(-1,3,-3,1) * m.ssst * m.sstt * m.sttt;");
- } else {
- s->codeAppend ("float q = sqrt(max(-discr, 0));");
- s->codeAppend ("q = D2 + (D2 >= 0 ? q : -q);");
- s->codeAppend ("l.ts = normalize(float2(q, 2*D1));");
- s->codeAppend ("m.ts = discr >= 0 ? l.ts : normalize(float2(2 * (D2*D2 - D3*D1), D1*q));");
- s->codeAppend ("float4 lxm = float4(l.s * m.s, l.s * m.t, l.t * m.s, l.t * m.t);");
- s->codeAppend ("K = float4(0, lxm.x, -lxm.y - lxm.z, lxm.w);");
- s->codeAppend ("L = float4(-1,1,-1,1) * l.sstt * (lxm.xyzw + float4(0, 2*lxm.zy, 0));");
- s->codeAppend ("M = float4(-1,1,-1,1) * m.sstt * (lxm.xzyw + float4(0, 2*lxm.yz, 0));");
- }
+ s->codeAppend ("float x = discr >= 0 ? 3 : 1;");
+ s->codeAppend ("float q = sqrt(x * abs(discr));");
+ s->codeAppend ("q = x*D2 + (D2 >= 0 ? q : -q);");
+
+ s->codeAppend ("float2 l, m;");
+ s->codeAppend ("l.ts = normalize(float2(q, 2*x * D1));");
+ s->codeAppend ("m.ts = normalize(float2(2, q) * (discr >= 0 ? float2(D3, 1) "
+ ": float2(D2*D2 - D3*D1, D1)));");
+
+ s->codeAppend ("float4 K;");
+ s->codeAppend ("float4 lm = l.sstt * m.stst;");
+ s->codeAppend ("K = float4(0, lm.x, -lm.y - lm.z, lm.w);");
+
+ s->codeAppend ("float4 L, M;");
+ s->codeAppend ("lm.yz += 2*lm.zy;");
+ s->codeAppend ("L = float4(-1,x,-x,1) * l.sstt * (discr >= 0 ? l.ssst * l.sttt : lm);");
+ s->codeAppend ("M = float4(-1,x,-x,1) * m.sstt * (discr >= 0 ? m.ssst * m.sttt : lm.xzyw);");
+
s->codeAppend ("short middlerow = abs(D2) > abs(D1) ? 2 : 1;");
s->codeAppend ("float3x3 CI = inverse(float3x3(C[0][0], C[0][middlerow], C[0][3], "
"C[1][0], C[1][middlerow], C[1][3], "
diff --git a/src/gpu/ccpr/GrCCPRCubicShader.h b/src/gpu/ccpr/GrCCPRCubicShader.h
index c0cb0757d1..7b91a495b8 100644
--- a/src/gpu/ccpr/GrCCPRCubicShader.h
+++ b/src/gpu/ccpr/GrCCPRCubicShader.h
@@ -22,15 +22,7 @@
* (Use GrCCPRGeometry.)
*/
class GrCCPRCubicShader : public GrCCPRCoverageProcessor::Shader {
-public:
- enum class CubicType {
- kSerpentine,
- kLoop
- };
-
protected:
- GrCCPRCubicShader(CubicType cubicType) : fCubicType(cubicType) {}
-
void emitSetupCode(GrGLSLShaderBuilder*, const char* pts, const char* segmentId,
const char* wind, GeometryVars*) const final;
@@ -42,17 +34,12 @@ protected:
virtual void onEmitVaryings(GrGLSLVaryingHandler*, SkString* code) = 0;
- const CubicType fCubicType;
GrShaderVar fKLMMatrix{"klm_matrix", kFloat3x3_GrSLType};
GrShaderVar fEdgeDistanceEquation{"edge_distance_equation", kFloat3_GrSLType};
GrGLSLGeoToFrag fKLMD{kFloat4_GrSLType};
};
class GrCCPRCubicHullShader : public GrCCPRCubicShader {
-public:
- GrCCPRCubicHullShader(CubicType cubicType) : GrCCPRCubicShader(cubicType) {}
-
-private:
GeometryType getGeometryType() const override { return GeometryType::kHull; }
int getNumSegments() const override { return 4; } // 4 wedges.
void onEmitSetupCode(GrGLSLShaderBuilder*, const char* pts, const char* wedgeId,
@@ -64,10 +51,6 @@ private:
};
class GrCCPRCubicCornerShader : public GrCCPRCubicShader {
-public:
- GrCCPRCubicCornerShader(CubicType cubicType) : GrCCPRCubicShader(cubicType) {}
-
-private:
GeometryType getGeometryType() const override { return GeometryType::kCorners; }
int getNumSegments() const override { return 2; } // 2 corners.
void onEmitSetupCode(GrGLSLShaderBuilder*, const char* pts, const char* cornerId,
diff --git a/src/gpu/ccpr/GrCCPRGeometry.cpp b/src/gpu/ccpr/GrCCPRGeometry.cpp
index d6423effa3..f73cd55962 100644
--- a/src/gpu/ccpr/GrCCPRGeometry.cpp
+++ b/src/gpu/ccpr/GrCCPRGeometry.cpp
@@ -30,7 +30,7 @@ void GrCCPRGeometry::beginContour(const SkPoint& devPt) {
// Store the current verb count in the fTriangles field for now. When we close the contour we
// will use this value to calculate the actual number of triangles in its fan.
- fCurrContourTallies = {fVerbs.count(), 0, 0, 0};
+ fCurrContourTallies = {fVerbs.count(), 0, 0};
fPoints.push_back(devPt);
fVerbs.push_back(Verb::kBeginContour);
@@ -538,13 +538,8 @@ void GrCCPRGeometry::appendMonotonicCubics(const Sk2f& p0, const Sk2f& p1, const
p1.store(&fPoints.push_back());
p2.store(&fPoints.push_back());
p3.store(&fPoints.push_back());
- if (SkCubicType::kLoop != fCurrCubicType) {
- fVerbs.push_back(Verb::kMonotonicSerpentineTo);
- ++fCurrContourTallies.fSerpentines;
- } else {
- fVerbs.push_back(Verb::kMonotonicLoopTo);
- ++fCurrContourTallies.fLoops;
- }
+ fVerbs.push_back(Verb::kMonotonicCubicTo);
+ ++fCurrContourTallies.fCubics;
}
void GrCCPRGeometry::appendCubicApproximation(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
diff --git a/src/gpu/ccpr/GrCCPRGeometry.h b/src/gpu/ccpr/GrCCPRGeometry.h
index 407e655916..9a3b2553bb 100644
--- a/src/gpu/ccpr/GrCCPRGeometry.h
+++ b/src/gpu/ccpr/GrCCPRGeometry.h
@@ -30,8 +30,7 @@ public:
kBeginContour,
kLineTo,
kMonotonicQuadraticTo, // Monotonic relative to the vector between its endpoints [P2 - P0].
- kMonotonicSerpentineTo,
- kMonotonicLoopTo,
+ kMonotonicCubicTo,
kEndClosedContour, // endPt == startPt.
kEndOpenContour // endPt != startPt.
};
@@ -40,8 +39,7 @@ public:
struct PrimitiveTallies {
int fTriangles; // Number of triangles in the contour's fan.
int fQuadratics;
- int fSerpentines;
- int fLoops;
+ int fCubics;
void operator+=(const PrimitiveTallies&);
PrimitiveTallies operator-(const PrimitiveTallies&) const;
@@ -130,16 +128,14 @@ private:
inline void GrCCPRGeometry::PrimitiveTallies::operator+=(const PrimitiveTallies& b) {
fTriangles += b.fTriangles;
fQuadratics += b.fQuadratics;
- fSerpentines += b.fSerpentines;
- fLoops += b.fLoops;
+ fCubics += b.fCubics;
}
GrCCPRGeometry::PrimitiveTallies
inline GrCCPRGeometry::PrimitiveTallies::operator-(const PrimitiveTallies& b) const {
return {fTriangles - b.fTriangles,
fQuadratics - b.fQuadratics,
- fSerpentines - b.fSerpentines,
- fLoops - b.fLoops};
+ fCubics - b.fCubics};
}
#endif