diff options
author | Chris Dalton <csmartdalton@google.com> | 2017-12-08 10:59:58 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-12-08 20:13:18 +0000 |
commit | be4ffab4e208ec47b4298621b9c9e8456f31717e (patch) | |
tree | 28bee87fec500acab63c2e72c77a6b7a4fd53ba1 /src/gpu/ccpr | |
parent | 3f39bf8fe596f87120d189dbec2889b644f07e2d (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.cpp | 39 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageProcessor.cpp | 40 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageProcessor.h | 38 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCubicShader.cpp | 39 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCubicShader.h | 17 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRGeometry.cpp | 11 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRGeometry.h | 12 |
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 |