Chromium Code Reviews| Index: src/gpu/GrOvalRenderer.cpp |
| diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp |
| index 1fb214a260ed432a0e1824e2e576f79b6e5fb310..af37f3294142e329c380e060c50189ee8e79eb34 100644 |
| --- a/src/gpu/GrOvalRenderer.cpp |
| +++ b/src/gpu/GrOvalRenderer.cpp |
| @@ -62,74 +62,73 @@ inline bool circle_stays_circle(const SkMatrix& m) { |
| /** |
| * The output of this effect is a modulation of the input color and coverage for a circle. It |
| * operates in a space normalized by the circle radius (outer radius in the case of a stroke) |
| - * with origin at the circle center. Two vertex attributes are used: |
| + * with origin at the circle center. Three vertex attributes are used: |
| * vec2f : position in device space of the bounding geometry vertices |
| + * vec4ub: color |
| * vec4f : (p.xy, outerRad, innerRad) |
| * p is the position in the normalized space. |
| * outerRad is the outerRadius in device space. |
| * innerRad is the innerRadius in normalized space (ignored if not stroking). |
| */ |
| -class CircleEdgeEffect : public GrGeometryProcessor { |
| +class CircleGeometryProcessor : public GrGeometryProcessor { |
| public: |
| - static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatrix& localMatrix, |
| - bool usesLocalCoords) { |
| - return new CircleEdgeEffect(color, stroke, localMatrix, usesLocalCoords); |
| + CircleGeometryProcessor(bool stroke, const SkMatrix& localMatrix) : fLocalMatrix(localMatrix){ |
| + this->initClassID<CircleGeometryProcessor>(); |
| + fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType, |
| + kHigh_GrSLPrecision)); |
| + fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); |
| + fInCircleEdge = &this->addVertexAttrib(Attribute("inCircleEdge", |
| + kVec4f_GrVertexAttribType)); |
| + fStroke = stroke; |
| } |
| const Attribute* inPosition() const { return fInPosition; } |
| const Attribute* inColor() const { return fInColor; } |
| const Attribute* inCircleEdge() const { return fInCircleEdge; } |
| - GrColor color() const { return fColor; } |
| - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } |
| const SkMatrix& localMatrix() const { return fLocalMatrix; } |
| - bool usesLocalCoords() const { return fUsesLocalCoords; } |
| - virtual ~CircleEdgeEffect() {} |
| + virtual ~CircleGeometryProcessor() {} |
| const char* name() const override { return "CircleEdge"; } |
| - inline bool isStroked() const { return fStroke; } |
| - |
| class GLSLProcessor : public GrGLSLGeometryProcessor { |
| public: |
| GLSLProcessor() {} |
| void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
| - const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>(); |
| + const CircleGeometryProcessor& cgp = args.fGP.cast<CircleGeometryProcessor>(); |
| GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
| GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
| GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
| // emit attributes |
| - varyingHandler->emitAttributes(ce); |
| + varyingHandler->emitAttributes(cgp); |
| GrGLSLVertToFrag v(kVec4f_GrSLType); |
| varyingHandler->addVarying("CircleEdge", &v); |
| - vertBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName); |
| + vertBuilder->codeAppendf("%s = %s;", v.vsOut(), cgp.inCircleEdge()->fName); |
| GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; |
| // setup pass through color |
| - if (!ce.colorIgnored()) { |
| - varyingHandler->addPassThroughAttribute(ce.inColor(), args.fOutputColor); |
| - } |
| + varyingHandler->addPassThroughAttribute(cgp.inColor(), args.fOutputColor); |
| // Setup position |
| - this->setupPosition(vertBuilder, gpArgs, ce.inPosition()->fName); |
| + this->setupPosition(vertBuilder, gpArgs, cgp.inPosition()->fName); |
| // emit transforms |
| this->emitTransforms(vertBuilder, |
| varyingHandler, |
| uniformHandler, |
| gpArgs->fPositionVar, |
| - ce.inPosition()->fName, |
| - ce.localMatrix(), |
| + cgp.inPosition()->fName, |
| + cgp.localMatrix(), |
| args.fTransformsIn, |
| args.fTransformsOut); |
| fragBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn()); |
| fragBuilder->codeAppendf("float edgeAlpha = clamp(%s.z * (1.0 - d), 0.0, 1.0);", |
| v.fsIn()); |
| - if (ce.isStroked()) { |
| + if (cgp.fStroke) { |
| fragBuilder->codeAppendf("float innerAlpha = clamp(%s.z * (d - %s.w), 0.0, 1.0);", |
| v.fsIn(), v.fsIn()); |
| fragBuilder->codeAppend("edgeAlpha *= innerAlpha;"); |
| @@ -141,10 +140,9 @@ public: |
| static void GenKey(const GrGeometryProcessor& gp, |
| const GrGLSLCaps&, |
| GrProcessorKeyBuilder* b) { |
| - const CircleEdgeEffect& ce = gp.cast<CircleEdgeEffect>(); |
| - uint16_t key = ce.isStroked() ? 0x1 : 0x0; |
| - key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x2 : 0x0; |
| - key |= ce.colorIgnored() ? 0x4 : 0x0; |
| + const CircleGeometryProcessor& cgp = gp.cast<CircleGeometryProcessor>(); |
| + uint16_t key = cgp.fStroke ? 0x1 : 0x0; |
| + key |= cgp.localMatrix().hasPerspective() ? 0x2 : 0x0; |
| b->add32(key); |
| } |
| @@ -156,7 +154,8 @@ public: |
| const GrGLSLProgramDataManager& pdman, |
| int index, |
| const SkTArray<const GrCoordTransform*, true>& transforms) override { |
| - this->setTransformDataHelper<CircleEdgeEffect>(primProc, pdman, index, transforms); |
| + this->setTransformDataHelper<CircleGeometryProcessor>(primProc, pdman, index, |
| + transforms); |
| } |
| private: |
| @@ -172,39 +171,21 @@ public: |
| } |
| private: |
| - CircleEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix, bool usesLocalCoords) |
| - : fColor(color) |
| - , fLocalMatrix(localMatrix) |
| - , fUsesLocalCoords(usesLocalCoords) { |
| - this->initClassID<CircleEdgeEffect>(); |
| - fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType, |
| - kHigh_GrSLPrecision)); |
| - fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); |
| - fInCircleEdge = &this->addVertexAttrib(Attribute("inCircleEdge", |
| - kVec4f_GrVertexAttribType)); |
| - fStroke = stroke; |
| - } |
| - |
| - GrColor fColor; |
| - SkMatrix fLocalMatrix; |
| + SkMatrix fLocalMatrix; |
| const Attribute* fInPosition; |
| const Attribute* fInColor; |
| const Attribute* fInCircleEdge; |
| - bool fStroke; |
| - bool fUsesLocalCoords; |
| + bool fStroke; |
| GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
| typedef GrGeometryProcessor INHERITED; |
| }; |
| -GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); |
| +GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleGeometryProcessor); |
| -const GrGeometryProcessor* CircleEdgeEffect::TestCreate(GrProcessorTestData* d) { |
| - return CircleEdgeEffect::Create(GrRandomColor(d->fRandom), |
| - d->fRandom->nextBool(), |
| - GrTest::TestMatrix(d->fRandom), |
| - d->fRandom->nextBool()); |
| +const GrGeometryProcessor* CircleGeometryProcessor::TestCreate(GrProcessorTestData* d) { |
| + return new CircleGeometryProcessor(d->fRandom->nextBool(), GrTest::TestMatrix(d->fRandom)); |
| } |
| /////////////////////////////////////////////////////////////////////////////// |
| @@ -217,14 +198,21 @@ const GrGeometryProcessor* CircleEdgeEffect::TestCreate(GrProcessorTestData* d) |
| * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. |
| */ |
| -class EllipseEdgeEffect : public GrGeometryProcessor { |
| +class EllipseGeometryProcessor : public GrGeometryProcessor { |
| public: |
| - static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatrix& localMatrix, |
| - bool usesLocalCoords) { |
| - return new EllipseEdgeEffect(color, stroke, localMatrix, usesLocalCoords); |
| + EllipseGeometryProcessor(bool stroke, const SkMatrix& localMatrix) |
| + : fLocalMatrix(localMatrix) { |
| + this->initClassID<EllipseGeometryProcessor>(); |
| + fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); |
| + fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); |
| + fInEllipseOffset = &this->addVertexAttrib(Attribute("inEllipseOffset", |
| + kVec2f_GrVertexAttribType)); |
| + fInEllipseRadii = &this->addVertexAttrib(Attribute("inEllipseRadii", |
| + kVec4f_GrVertexAttribType)); |
| + fStroke = stroke; |
| } |
| - virtual ~EllipseEdgeEffect() {} |
| + virtual ~EllipseGeometryProcessor() {} |
| const char* name() const override { return "EllipseEdge"; } |
| @@ -232,52 +220,45 @@ public: |
| const Attribute* inColor() const { return fInColor; } |
| const Attribute* inEllipseOffset() const { return fInEllipseOffset; } |
| const Attribute* inEllipseRadii() const { return fInEllipseRadii; } |
| - GrColor color() const { return fColor; } |
| - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } |
| const SkMatrix& localMatrix() const { return fLocalMatrix; } |
| - bool usesLocalCoords() const { return fUsesLocalCoords; } |
| - |
| - inline bool isStroked() const { return fStroke; } |
| class GLSLProcessor : public GrGLSLGeometryProcessor { |
| public: |
| GLSLProcessor() {} |
| void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
| - const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>(); |
| + const EllipseGeometryProcessor& egp = args.fGP.cast<EllipseGeometryProcessor>(); |
| GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
| GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
| GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
| // emit attributes |
| - varyingHandler->emitAttributes(ee); |
| + varyingHandler->emitAttributes(egp); |
| GrGLSLVertToFrag ellipseOffsets(kVec2f_GrSLType); |
| varyingHandler->addVarying("EllipseOffsets", &ellipseOffsets); |
| vertBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(), |
| - ee.inEllipseOffset()->fName); |
| + egp.inEllipseOffset()->fName); |
| GrGLSLVertToFrag ellipseRadii(kVec4f_GrSLType); |
| varyingHandler->addVarying("EllipseRadii", &ellipseRadii); |
| vertBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), |
| - ee.inEllipseRadii()->fName); |
| + egp.inEllipseRadii()->fName); |
| GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; |
| // setup pass through color |
| - if (!ee.colorIgnored()) { |
| - varyingHandler->addPassThroughAttribute(ee.inColor(), args.fOutputColor); |
| - } |
| + varyingHandler->addPassThroughAttribute(egp.inColor(), args.fOutputColor); |
| // Setup position |
| - this->setupPosition(vertBuilder, gpArgs, ee.inPosition()->fName); |
| + this->setupPosition(vertBuilder, gpArgs, egp.inPosition()->fName); |
| // emit transforms |
| this->emitTransforms(vertBuilder, |
| varyingHandler, |
| uniformHandler, |
| gpArgs->fPositionVar, |
| - ee.inPosition()->fName, |
| - ee.localMatrix(), |
| + egp.inPosition()->fName, |
| + egp.localMatrix(), |
| args.fTransformsIn, |
| args.fTransformsOut); |
| @@ -294,7 +275,7 @@ public: |
| fragBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);"); |
| // for inner curve |
| - if (ee.isStroked()) { |
| + if (egp.fStroke) { |
| fragBuilder->codeAppendf("scaledOffset = %s*%s.zw;", |
| ellipseOffsets.fsIn(), ellipseRadii.fsIn()); |
| fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;"); |
| @@ -310,10 +291,9 @@ public: |
| static void GenKey(const GrGeometryProcessor& gp, |
| const GrGLSLCaps&, |
| GrProcessorKeyBuilder* b) { |
| - const EllipseEdgeEffect& ee = gp.cast<EllipseEdgeEffect>(); |
| - uint16_t key = ee.isStroked() ? 0x1 : 0x0; |
| - key |= ee.usesLocalCoords() && ee.localMatrix().hasPerspective() ? 0x2 : 0x0; |
| - key |= ee.colorIgnored() ? 0x4 : 0x0; |
| + const EllipseGeometryProcessor& egp = gp.cast<EllipseGeometryProcessor>(); |
| + uint16_t key = egp.fStroke ? 0x1 : 0x0; |
| + key |= egp.localMatrix().hasPerspective() ? 0x2 : 0x0; |
| b->add32(key); |
| } |
| @@ -324,7 +304,8 @@ public: |
| const GrGLSLProgramDataManager& pdman, |
| int index, |
| const SkTArray<const GrCoordTransform*, true>& transforms) override { |
| - this->setTransformDataHelper<EllipseEdgeEffect>(primProc, pdman, index, transforms); |
| + this->setTransformDataHelper<EllipseGeometryProcessor>(primProc, pdman, index, |
| + transforms); |
| } |
| private: |
| @@ -340,42 +321,22 @@ public: |
| } |
| private: |
| - EllipseEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix, |
| - bool usesLocalCoords) |
| - : fColor(color) |
| - , fLocalMatrix(localMatrix) |
| - , fUsesLocalCoords(usesLocalCoords) { |
| - this->initClassID<EllipseEdgeEffect>(); |
| - fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); |
| - fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); |
| - fInEllipseOffset = &this->addVertexAttrib(Attribute("inEllipseOffset", |
| - kVec2f_GrVertexAttribType)); |
| - fInEllipseRadii = &this->addVertexAttrib(Attribute("inEllipseRadii", |
| - kVec4f_GrVertexAttribType)); |
| - fStroke = stroke; |
| - } |
| - |
| const Attribute* fInPosition; |
| const Attribute* fInColor; |
| const Attribute* fInEllipseOffset; |
| const Attribute* fInEllipseRadii; |
| - GrColor fColor; |
| SkMatrix fLocalMatrix; |
| bool fStroke; |
| - bool fUsesLocalCoords; |
| GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
| typedef GrGeometryProcessor INHERITED; |
| }; |
| -GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); |
| +GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseGeometryProcessor); |
| -const GrGeometryProcessor* EllipseEdgeEffect::TestCreate(GrProcessorTestData* d) { |
| - return EllipseEdgeEffect::Create(GrRandomColor(d->fRandom), |
| - d->fRandom->nextBool(), |
| - GrTest::TestMatrix(d->fRandom), |
| - d->fRandom->nextBool()); |
| +const GrGeometryProcessor* EllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) { |
| + return new EllipseGeometryProcessor(d->fRandom->nextBool(), GrTest::TestMatrix(d->fRandom)); |
| } |
| /////////////////////////////////////////////////////////////////////////////// |
| @@ -389,16 +350,16 @@ const GrGeometryProcessor* EllipseEdgeEffect::TestCreate(GrProcessorTestData* d) |
| * The result is device-independent and can be used with any affine matrix. |
| */ |
| -class DIEllipseEdgeEffect : public GrGeometryProcessor { |
| +enum class DIEllipseStyle { kStroke = 0, kHairline, kFill }; |
| + |
| +class DIEllipseGeometryProcessor : public GrGeometryProcessor { |
| public: |
| - enum Mode { kStroke = 0, kHairline, kFill }; |
| - static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, Mode mode, |
| - bool usesLocalCoords) { |
| - return new DIEllipseEdgeEffect(color, viewMatrix, mode, usesLocalCoords); |
| + static GrGeometryProcessor* Create(const SkMatrix& viewMatrix, DIEllipseStyle style) { |
|
Brian Osman
2016/03/07 14:45:45
Any reason to keep the factory method here (vs. Ci
bsalomon
2016/03/07 14:57:39
Nope, just bleariness. Will change.
bsalomon
2016/03/07 15:53:50
Done, brings it to an even 200 net LOC reduction.
|
| + return new DIEllipseGeometryProcessor (viewMatrix, style); |
| } |
| - virtual ~DIEllipseEdgeEffect() {} |
| + virtual ~DIEllipseGeometryProcessor() {} |
| const char* name() const override { return "DIEllipseEdge"; } |
| @@ -406,49 +367,41 @@ public: |
| const Attribute* inColor() const { return fInColor; } |
| const Attribute* inEllipseOffsets0() const { return fInEllipseOffsets0; } |
| const Attribute* inEllipseOffsets1() const { return fInEllipseOffsets1; } |
| - GrColor color() const { return fColor; } |
| - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } |
| const SkMatrix& viewMatrix() const { return fViewMatrix; } |
| - bool usesLocalCoords() const { return fUsesLocalCoords; } |
| - |
| - inline Mode getMode() const { return fMode; } |
| - |
| + |
| class GLSLProcessor : public GrGLSLGeometryProcessor { |
| public: |
| GLSLProcessor() |
| : fViewMatrix(SkMatrix::InvalidMatrix()) {} |
| void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { |
| - const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>(); |
| + const DIEllipseGeometryProcessor& diegp = args.fGP.cast<DIEllipseGeometryProcessor>(); |
| GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
| GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
| GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
| // emit attributes |
| - varyingHandler->emitAttributes(ee); |
| + varyingHandler->emitAttributes(diegp); |
| GrGLSLVertToFrag offsets0(kVec2f_GrSLType); |
| varyingHandler->addVarying("EllipseOffsets0", &offsets0); |
| vertBuilder->codeAppendf("%s = %s;", offsets0.vsOut(), |
| - ee.inEllipseOffsets0()->fName); |
| + diegp.inEllipseOffsets0()->fName); |
| GrGLSLVertToFrag offsets1(kVec2f_GrSLType); |
| varyingHandler->addVarying("EllipseOffsets1", &offsets1); |
| vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), |
| - ee.inEllipseOffsets1()->fName); |
| + diegp.inEllipseOffsets1()->fName); |
| GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; |
| - // setup pass through color |
| - if (!ee.colorIgnored()) { |
| - varyingHandler->addPassThroughAttribute(ee.inColor(), args.fOutputColor); |
| - } |
| + varyingHandler->addPassThroughAttribute(diegp.inColor(), args.fOutputColor); |
| // Setup position |
| this->setupPosition(vertBuilder, |
| uniformHandler, |
| gpArgs, |
| - ee.inPosition()->fName, |
| - ee.viewMatrix(), |
| + diegp.inPosition()->fName, |
| + diegp.viewMatrix(), |
| &fViewMatrixUniform); |
| // emit transforms |
| @@ -456,7 +409,7 @@ public: |
| varyingHandler, |
| uniformHandler, |
| gpArgs->fPositionVar, |
| - ee.inPosition()->fName, |
| + diegp.inPosition()->fName, |
| args.fTransformsIn, |
| args.fTransformsOut); |
| @@ -469,13 +422,14 @@ public: |
| fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn()); |
| fragBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y," |
| " 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);", |
| - offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn()); |
| + offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(), |
| + offsets0.fsIn()); |
| fragBuilder->codeAppend("float grad_dot = dot(grad, grad);"); |
| // avoid calling inversesqrt on zero. |
| fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);"); |
| fragBuilder->codeAppend("float invlen = inversesqrt(grad_dot);"); |
| - if (kHairline == ee.getMode()) { |
| + if (DIEllipseStyle::kHairline == diegp.fStyle) { |
| // can probably do this with one step |
| fragBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);"); |
| fragBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);"); |
| @@ -484,7 +438,7 @@ public: |
| } |
| // for inner curve |
| - if (kStroke == ee.getMode()) { |
| + if (DIEllipseStyle::kStroke == diegp.fStyle) { |
| fragBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn()); |
| fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;"); |
| fragBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn()); |
| @@ -503,19 +457,18 @@ public: |
| static void GenKey(const GrGeometryProcessor& gp, |
| const GrGLSLCaps&, |
| GrProcessorKeyBuilder* b) { |
| - const DIEllipseEdgeEffect& ellipseEffect = gp.cast<DIEllipseEdgeEffect>(); |
| - uint16_t key = ellipseEffect.getMode(); |
| - key |= ellipseEffect.colorIgnored() << 9; |
| - key |= ComputePosKey(ellipseEffect.viewMatrix()) << 10; |
| + const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>(); |
| + uint16_t key = static_cast<uint16_t>(diegp.fStyle); |
| + key |= ComputePosKey(diegp.viewMatrix()) << 10; |
| b->add32(key); |
| } |
| void setData(const GrGLSLProgramDataManager& pdman, |
| const GrPrimitiveProcessor& gp) override { |
| - const DIEllipseEdgeEffect& dee = gp.cast<DIEllipseEdgeEffect>(); |
| + const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>(); |
| - if (!dee.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dee.viewMatrix())) { |
| - fViewMatrix = dee.viewMatrix(); |
| + if (!diegp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(diegp.viewMatrix())) { |
| + fViewMatrix = diegp.viewMatrix(); |
| float viewMatrix[3 * 3]; |
| GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); |
| pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); |
| @@ -538,12 +491,9 @@ public: |
| } |
| private: |
| - DIEllipseEdgeEffect(GrColor color, const SkMatrix& viewMatrix, Mode mode, |
| - bool usesLocalCoords) |
| - : fColor(color) |
| - , fViewMatrix(viewMatrix) |
| - , fUsesLocalCoords(usesLocalCoords) { |
| - this->initClassID<DIEllipseEdgeEffect>(); |
| + DIEllipseGeometryProcessor(const SkMatrix& viewMatrix, DIEllipseStyle style) |
| + : fViewMatrix(viewMatrix) { |
| + this->initClassID<DIEllipseGeometryProcessor>(); |
| fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType, |
| kHigh_GrSLPrecision)); |
| fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); |
| @@ -551,30 +501,26 @@ private: |
| kVec2f_GrVertexAttribType)); |
| fInEllipseOffsets1 = &this->addVertexAttrib(Attribute("inEllipseOffsets1", |
| kVec2f_GrVertexAttribType)); |
| - fMode = mode; |
| + fStyle = style; |
| } |
| const Attribute* fInPosition; |
| const Attribute* fInColor; |
| const Attribute* fInEllipseOffsets0; |
| const Attribute* fInEllipseOffsets1; |
| - GrColor fColor; |
| - SkMatrix fViewMatrix; |
| - Mode fMode; |
| - bool fUsesLocalCoords; |
| + SkMatrix fViewMatrix; |
| + DIEllipseStyle fStyle; |
| GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
| typedef GrGeometryProcessor INHERITED; |
| }; |
| -GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect); |
| +GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseGeometryProcessor); |
| -const GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(GrProcessorTestData* d) { |
| - return DIEllipseEdgeEffect::Create(GrRandomColor(d->fRandom), |
| - GrTest::TestMatrix(d->fRandom), |
| - (Mode)(d->fRandom->nextRangeU(0,2)), |
| - d->fRandom->nextBool()); |
| +const GrGeometryProcessor* DIEllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) { |
| + return DIEllipseGeometryProcessor::Create(GrTest::TestMatrix(d->fRandom), |
| + (DIEllipseStyle)(d->fRandom->nextRangeU(0,2))); |
| } |
| /////////////////////////////////////////////////////////////////////////////// |
| @@ -609,16 +555,19 @@ public: |
| DEFINE_BATCH_CLASS_ID |
| struct Geometry { |
| - SkMatrix fViewMatrix; |
| SkRect fDevBounds; |
| SkScalar fInnerRadius; |
| SkScalar fOuterRadius; |
| GrColor fColor; |
| - bool fStroke; |
| }; |
| - static GrDrawBatch* Create(const Geometry& geometry) { return new CircleBatch(geometry); } |
| - |
| + CircleBatch(const Geometry& geometry, const SkMatrix& viewMatrix, bool stroked) |
| + : INHERITED(ClassID()) |
| + , fStroked(stroked) |
| + , fViewMatrixIfUsingLocalCoords(viewMatrix) { |
| + fGeoData.push_back(geometry); |
| + this->setBounds(geometry.fDevBounds); |
| + } |
| const char* name() const override { return "CircleBatch"; } |
| SkString dumpInfo() const override { |
| @@ -646,31 +595,21 @@ public: |
| private: |
| void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| - // Handle any color overrides |
| - if (!overrides.readsColor()) { |
| - fGeoData[0].fColor = GrColor_ILLEGAL; |
| - } |
| + // Handle any overrides that affect our GP. |
| overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
| - |
| - // setup batch properties |
| - fBatch.fColorIgnored = !overrides.readsColor(); |
| - fBatch.fColor = fGeoData[0].fColor; |
| - fBatch.fStroke = fGeoData[0].fStroke; |
| - fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); |
| - fBatch.fCoverageIgnored = !overrides.readsCoverage(); |
| + if (!overrides.readsLocalCoords()) { |
| + fViewMatrixIfUsingLocalCoords.reset(); |
| + } |
| } |
| void onPrepareDraws(Target* target) const override { |
| - SkMatrix invert; |
| - if (!this->viewMatrix().invert(&invert)) { |
| + SkMatrix localMatrix; |
| + if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { |
| return; |
| } |
| // Setup geometry processor |
| - SkAutoTUnref<GrGeometryProcessor> gp(CircleEdgeEffect::Create(this->color(), |
| - this->stroke(), |
| - invert, |
| - this->usesLocalCoords())); |
| + SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(fStroked, localMatrix)); |
| target->initDraw(gp, this->pipeline()); |
| @@ -724,14 +663,6 @@ private: |
| helper.recordDraw(target); |
| } |
| - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| - |
| - CircleBatch(const Geometry& geometry) : INHERITED(ClassID()) { |
| - fGeoData.push_back(geometry); |
| - |
| - this->setBounds(geometry.fDevBounds); |
| - } |
| - |
| bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| CircleBatch* that = t->cast<CircleBatch>(); |
| if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), |
| @@ -739,34 +670,21 @@ private: |
| return false; |
| } |
| - if (this->stroke() != that->stroke()) { |
| + if (this->fStroked != that->fStroked) { |
| return false; |
| } |
| - SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); |
| - if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
| + if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) { |
| return false; |
| } |
| - 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; |
| } |
| - GrColor color() const { return fBatch.fColor; } |
| - bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| - const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
| - bool stroke() const { return fBatch.fStroke; } |
| - |
| - struct BatchTracker { |
| - GrColor fColor; |
| - bool fStroke; |
| - bool fUsesLocalCoords; |
| - bool fColorIgnored; |
| - bool fCoverageIgnored; |
| - }; |
| - |
| - BatchTracker fBatch; |
| + bool fStroked; |
| + SkMatrix fViewMatrixIfUsingLocalCoords; |
| SkSTArray<1, Geometry, true> fGeoData; |
| typedef GrVertexBatch INHERITED; |
| @@ -810,15 +728,13 @@ static GrDrawBatch* create_circle_batch(GrColor color, |
| innerRadius -= SK_ScalarHalf; |
| CircleBatch::Geometry geometry; |
| - geometry.fViewMatrix = viewMatrix; |
| geometry.fColor = color; |
| geometry.fInnerRadius = innerRadius; |
| geometry.fOuterRadius = outerRadius; |
| - geometry.fStroke = isStrokeOnly && innerRadius > 0; |
| geometry.fDevBounds = SkRect::MakeLTRB(center.fX - outerRadius, center.fY - outerRadius, |
| center.fX + outerRadius, center.fY + outerRadius); |
| - return CircleBatch::Create(geometry); |
| + return new CircleBatch(geometry, viewMatrix, isStrokeOnly && innerRadius > 0); |
| } |
| GrDrawBatch* GrOvalRenderer::CreateCircleBatch(GrColor color, |
| @@ -835,17 +751,21 @@ public: |
| DEFINE_BATCH_CLASS_ID |
| struct Geometry { |
| - SkMatrix fViewMatrix; |
| SkRect fDevBounds; |
| SkScalar fXRadius; |
| SkScalar fYRadius; |
| SkScalar fInnerXRadius; |
| SkScalar fInnerYRadius; |
| GrColor fColor; |
| - bool fStroke; |
| }; |
| - static GrDrawBatch* Create(const Geometry& geometry) { return new EllipseBatch(geometry); } |
| + EllipseBatch(const Geometry& geometry, const SkMatrix& viewMatrix, bool stroked) |
| + : INHERITED(ClassID()) |
| + , fStroked(stroked) |
| + , fViewMatrixIfUsingLocalCoords(viewMatrix) { |
| + fGeoData.push_back(geometry); |
| + this->setBounds(geometry.fDevBounds); |
| + } |
| const char* name() const override { return "EllipseBatch"; } |
| @@ -859,31 +779,23 @@ public: |
| private: |
| void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| - // Handle any color overrides |
| + // Handle any overrides that affect our GP. |
| if (!overrides.readsCoverage()) { |
| fGeoData[0].fColor = GrColor_ILLEGAL; |
| } |
| - overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
| - |
| - // setup batch properties |
| - fBatch.fColorIgnored = !overrides.readsColor(); |
| - fBatch.fColor = fGeoData[0].fColor; |
| - fBatch.fStroke = fGeoData[0].fStroke; |
| - fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); |
| - fBatch.fCoverageIgnored = !overrides.readsCoverage(); |
| + if (!overrides.readsLocalCoords()) { |
| + fViewMatrixIfUsingLocalCoords.reset(); |
| + } |
| } |
| void onPrepareDraws(Target* target) const override { |
| - SkMatrix invert; |
| - if (!this->viewMatrix().invert(&invert)) { |
| + SkMatrix localMatrix; |
| + if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { |
| return; |
| } |
| // Setup geometry processor |
| - SkAutoTUnref<GrGeometryProcessor> gp(EllipseEdgeEffect::Create(this->color(), |
| - this->stroke(), |
| - invert, |
| - this->usesLocalCoords())); |
| + SkAutoTUnref<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix)); |
| target->initDraw(gp, this->pipeline()); |
| @@ -942,14 +854,6 @@ private: |
| helper.recordDraw(target); |
| } |
| - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| - |
| - EllipseBatch(const Geometry& geometry) : INHERITED(ClassID()) { |
| - fGeoData.push_back(geometry); |
| - |
| - this->setBounds(geometry.fDevBounds); |
| - } |
| - |
| bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| EllipseBatch* that = t->cast<EllipseBatch>(); |
| @@ -958,34 +862,22 @@ private: |
| return false; |
| } |
| - if (this->stroke() != that->stroke()) { |
| + if (fStroked != that->fStroked) { |
| return false; |
| } |
| - SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); |
| - if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
| + if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) { |
| return false; |
| } |
| - 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; |
| } |
| - GrColor color() const { return fBatch.fColor; } |
| - bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| - const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
| - bool stroke() const { return fBatch.fStroke; } |
| - |
| - struct BatchTracker { |
| - GrColor fColor; |
| - bool fStroke; |
| - bool fUsesLocalCoords; |
| - bool fColorIgnored; |
| - bool fCoverageIgnored; |
| - }; |
| - BatchTracker fBatch; |
| + bool fStroked; |
| + SkMatrix fViewMatrixIfUsingLocalCoords; |
| SkSTArray<1, Geometry, true> fGeoData; |
| typedef GrVertexBatch INHERITED; |
| @@ -1058,17 +950,16 @@ static GrDrawBatch* create_ellipse_batch(GrColor color, |
| yRadius += SK_ScalarHalf; |
| EllipseBatch::Geometry geometry; |
| - geometry.fViewMatrix = viewMatrix; |
| geometry.fColor = color; |
| geometry.fXRadius = xRadius; |
| geometry.fYRadius = yRadius; |
| geometry.fInnerXRadius = innerXRadius; |
| geometry.fInnerYRadius = innerYRadius; |
| - geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; |
| geometry.fDevBounds = SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRadius, |
| center.fX + xRadius, center.fY + yRadius); |
| - return EllipseBatch::Create(geometry); |
| + return new EllipseBatch(geometry, viewMatrix, |
| + isStrokeOnly && innerXRadius > 0 && innerYRadius > 0); |
| } |
| GrDrawBatch* GrOvalRenderer::CreateEllipseBatch(GrColor color, |
| @@ -1094,7 +985,7 @@ public: |
| SkScalar fGeoDx; |
| SkScalar fGeoDy; |
| GrColor fColor; |
| - DIEllipseEdgeEffect::Mode fMode; |
| + DIEllipseStyle fStyle; |
| }; |
| static GrDrawBatch* Create(const Geometry& geometry, const SkRect& bounds) { |
| @@ -1114,26 +1005,15 @@ public: |
| private: |
| void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| - // Handle any color overrides |
| - if (!overrides.readsColor()) { |
| - fGeoData[0].fColor = GrColor_ILLEGAL; |
| - } |
| + // Handle any overrides that affect our GP. |
| overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
| - |
| - // setup batch properties |
| - fBatch.fColorIgnored = !overrides.readsColor(); |
| - fBatch.fColor = fGeoData[0].fColor; |
| - fBatch.fMode = fGeoData[0].fMode; |
| - fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); |
| - fBatch.fCoverageIgnored = !overrides.readsCoverage(); |
| + fUsesLocalCoords = overrides.readsLocalCoords(); |
| } |
| void onPrepareDraws(Target* target) const override { |
| // Setup geometry processor |
| - SkAutoTUnref<GrGeometryProcessor> gp(DIEllipseEdgeEffect::Create(this->color(), |
| - this->viewMatrix(), |
| - this->mode(), |
| - this->usesLocalCoords())); |
| + SkAutoTUnref<GrGeometryProcessor> gp(DIEllipseGeometryProcessor::Create(this->viewMatrix(), |
| + this->style())); |
| target->initDraw(gp, this->pipeline()); |
| @@ -1187,9 +1067,7 @@ private: |
| } |
| helper.recordDraw(target); |
| } |
| - |
| - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| - |
| + |
| DIEllipseBatch(const Geometry& geometry, const SkRect& bounds) : INHERITED(ClassID()) { |
| fGeoData.push_back(geometry); |
| @@ -1203,7 +1081,7 @@ private: |
| return false; |
| } |
| - if (this->mode() != that->mode()) { |
| + if (this->style() != that->style()) { |
| return false; |
| } |
| @@ -1212,25 +1090,15 @@ private: |
| return false; |
| } |
| - 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; |
| } |
| - GrColor color() const { return fBatch.fColor; } |
| - bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
| - DIEllipseEdgeEffect::Mode mode() const { return fBatch.fMode; } |
| - |
| - struct BatchTracker { |
| - GrColor fColor; |
| - DIEllipseEdgeEffect::Mode fMode; |
| - bool fUsesLocalCoords; |
| - bool fColorIgnored; |
| - bool fCoverageIgnored; |
| - }; |
| + DIEllipseStyle style() const { return fGeoData[0].fStyle; } |
| - BatchTracker fBatch; |
| + bool fUsesLocalCoords; |
| SkSTArray<1, Geometry, true> fGeoData; |
| typedef GrVertexBatch INHERITED; |
| @@ -1245,10 +1113,10 @@ static GrDrawBatch* create_diellipse_batch(GrColor color, |
| SkScalar yRadius = SkScalarHalf(ellipse.height()); |
| SkStrokeRec::Style style = stroke.getStyle(); |
| - DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ? |
| - DIEllipseEdgeEffect::kStroke : |
| - (SkStrokeRec::kHairline_Style == style) ? |
| - DIEllipseEdgeEffect::kHairline : DIEllipseEdgeEffect::kFill; |
| + DIEllipseStyle dieStyle = (SkStrokeRec::kStroke_Style == style) ? |
| + DIEllipseStyle::kStroke : |
| + (SkStrokeRec::kHairline_Style == style) ? |
| + DIEllipseStyle::kHairline : DIEllipseStyle::kFill; |
| SkScalar innerXRadius = 0; |
| SkScalar innerYRadius = 0; |
| @@ -1282,9 +1150,9 @@ static GrDrawBatch* create_diellipse_batch(GrColor color, |
| xRadius += strokeWidth; |
| yRadius += strokeWidth; |
| } |
| - if (DIEllipseEdgeEffect::kStroke == mode) { |
| - mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kStroke : |
| - DIEllipseEdgeEffect::kFill; |
| + if (DIEllipseStyle::kStroke == dieStyle) { |
| + dieStyle = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseStyle ::kStroke : |
| + DIEllipseStyle ::kFill; |
| } |
| // This expands the outer rect so that after CTM we end up with a half-pixel border |
| @@ -1304,7 +1172,7 @@ static GrDrawBatch* create_diellipse_batch(GrColor color, |
| geometry.fInnerYRadius = innerYRadius; |
| geometry.fGeoDx = geoDx; |
| geometry.fGeoDy = geoDy; |
| - geometry.fMode = mode; |
| + geometry.fStyle = dieStyle; |
| geometry.fBounds = SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY - yRadius - geoDy, |
| center.fX + xRadius + geoDx, center.fY + yRadius + geoDy); |
| @@ -1370,16 +1238,19 @@ public: |
| DEFINE_BATCH_CLASS_ID |
| struct Geometry { |
| - SkMatrix fViewMatrix; |
| SkRect fDevBounds; |
| SkScalar fInnerRadius; |
| SkScalar fOuterRadius; |
| - GrColor fColor; |
| - bool fStroke; |
| + GrColor fColor; |
| }; |
| - static GrDrawBatch* Create(const Geometry& geometry) { |
| - return new RRectCircleRendererBatch(geometry); |
| + RRectCircleRendererBatch(const Geometry& geometry, const SkMatrix& viewMatrix, bool stroked) |
| + : INHERITED(ClassID()) |
| + , fStroked(stroked) |
| + , fViewMatrixIfUsingLocalCoords(viewMatrix) { |
| + fGeoData.push_back(geometry); |
| + |
| + this->setBounds(geometry.fDevBounds); |
| } |
| const char* name() const override { return "RRectCircleBatch"; } |
| @@ -1394,33 +1265,22 @@ public: |
| private: |
| void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| - // Handle any color overrides |
| - if (!overrides.readsColor()) { |
| - fGeoData[0].fColor = GrColor_ILLEGAL; |
| - } |
| + // Handle any overrides that affect our GP. |
| overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
| - |
| - // setup batch properties |
| - fBatch.fColorIgnored = !overrides.readsColor(); |
| - fBatch.fColor = fGeoData[0].fColor; |
| - fBatch.fStroke = fGeoData[0].fStroke; |
| - fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); |
| - fBatch.fCoverageIgnored = !overrides.readsCoverage(); |
| + if (!overrides.readsLocalCoords()) { |
| + fViewMatrixIfUsingLocalCoords.reset(); |
| + } |
| } |
| void onPrepareDraws(Target* target) const override { |
| - // reset to device coordinates |
| - SkMatrix invert; |
| - if (!this->viewMatrix().invert(&invert)) { |
| - SkDebugf("Failed to invert\n"); |
| + // Invert the view matrix as a local matrix (if any other processors require coords). |
| + SkMatrix localMatrix; |
| + if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { |
| return; |
| } |
| // Setup geometry processor |
| - SkAutoTUnref<GrGeometryProcessor> gp(CircleEdgeEffect::Create(this->color(), |
| - this->stroke(), |
| - invert, |
| - this->usesLocalCoords())); |
| + SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(fStroked, localMatrix)); |
| target->initDraw(gp, this->pipeline()); |
| @@ -1429,9 +1289,9 @@ private: |
| SkASSERT(vertexStride == sizeof(CircleVertex)); |
| // drop out the middle quad if we're stroked |
| - int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect; |
| + int indicesPerInstance = fStroked ? kIndicesPerStrokeRRect : kIndicesPerRRect; |
| SkAutoTUnref<const GrIndexBuffer> indexBuffer( |
| - ref_rrect_index_buffer(this->stroke(), target->resourceProvider())); |
| + ref_rrect_index_buffer(fStroked, target->resourceProvider())); |
| InstancedHelper helper; |
| CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(target, |
| @@ -1494,14 +1354,6 @@ private: |
| helper.recordDraw(target); |
| } |
| - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| - |
| - RRectCircleRendererBatch(const Geometry& geometry) : INHERITED(ClassID()) { |
| - fGeoData.push_back(geometry); |
| - |
| - this->setBounds(geometry.fDevBounds); |
| - } |
| - |
| bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>(); |
| if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), |
| @@ -1509,34 +1361,21 @@ private: |
| return false; |
| } |
| - if (this->stroke() != that->stroke()) { |
| + if (fStroked != that->fStroked) { |
| return false; |
| } |
| - SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); |
| - if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
| + if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) { |
| return false; |
| } |
| - 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; |
| } |
| - GrColor color() const { return fBatch.fColor; } |
| - bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| - const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
| - bool stroke() const { return fBatch.fStroke; } |
| - |
| - struct BatchTracker { |
| - GrColor fColor; |
| - bool fStroke; |
| - bool fUsesLocalCoords; |
| - bool fColorIgnored; |
| - bool fCoverageIgnored; |
| - }; |
| - |
| - BatchTracker fBatch; |
| + bool fStroked; |
| + SkMatrix fViewMatrixIfUsingLocalCoords; |
| SkSTArray<1, Geometry, true> fGeoData; |
| typedef GrVertexBatch INHERITED; |
| @@ -1547,18 +1386,20 @@ public: |
| DEFINE_BATCH_CLASS_ID |
| struct Geometry { |
| - SkMatrix fViewMatrix; |
| SkRect fDevBounds; |
| SkScalar fXRadius; |
| SkScalar fYRadius; |
| SkScalar fInnerXRadius; |
| SkScalar fInnerYRadius; |
| GrColor fColor; |
| - bool fStroke; |
| }; |
| - static GrDrawBatch* Create(const Geometry& geometry) { |
| - return new RRectEllipseRendererBatch(geometry); |
| + RRectEllipseRendererBatch(const Geometry& geometry, const SkMatrix& viewMatrix, bool stroked) |
| + : INHERITED(ClassID()) |
| + , fStroked(stroked) |
| + , fViewMatrixIfUsingLocalCoords(viewMatrix) { |
| + fGeoData.push_back(geometry); |
| + this->setBounds(geometry.fDevBounds); |
| } |
| const char* name() const override { return "RRectEllipseRendererBatch"; } |
| @@ -1573,33 +1414,21 @@ public: |
| private: |
| void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| - // Handle any color overrides |
| - if (!overrides.readsColor()) { |
| - fGeoData[0].fColor = GrColor_ILLEGAL; |
| - } |
| + // Handle overrides that affect our GP. |
| overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
| - |
| - // setup batch properties |
| - fBatch.fColorIgnored = !overrides.readsColor(); |
| - fBatch.fColor = fGeoData[0].fColor; |
| - fBatch.fStroke = fGeoData[0].fStroke; |
| - fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); |
| - fBatch.fCoverageIgnored = !overrides.readsCoverage(); |
| + if (!overrides.readsLocalCoords()) { |
| + fViewMatrixIfUsingLocalCoords.reset(); |
| + } |
| } |
| void onPrepareDraws(Target* target) const override { |
| - // reset to device coordinates |
| - SkMatrix invert; |
| - if (!this->viewMatrix().invert(&invert)) { |
| - SkDebugf("Failed to invert\n"); |
| + SkMatrix localMatrix; |
| + if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { |
| return; |
| } |
| // Setup geometry processor |
| - SkAutoTUnref<GrGeometryProcessor> gp(EllipseEdgeEffect::Create(this->color(), |
| - this->stroke(), |
| - invert, |
| - this->usesLocalCoords())); |
| + SkAutoTUnref<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix)); |
| target->initDraw(gp, this->pipeline()); |
| @@ -1608,9 +1437,9 @@ private: |
| SkASSERT(vertexStride == sizeof(EllipseVertex)); |
| // drop out the middle quad if we're stroked |
| - int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect; |
| + int indicesPerInstance = fStroked ? kIndicesPerStrokeRRect : kIndicesPerRRect; |
| SkAutoTUnref<const GrIndexBuffer> indexBuffer( |
| - ref_rrect_index_buffer(this->stroke(), target->resourceProvider())); |
| + ref_rrect_index_buffer(fStroked, target->resourceProvider())); |
| InstancedHelper helper; |
| EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( |
| @@ -1684,14 +1513,6 @@ private: |
| helper.recordDraw(target); |
| } |
| - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| - |
| - RRectEllipseRendererBatch(const Geometry& geometry) : INHERITED(ClassID()) { |
| - fGeoData.push_back(geometry); |
| - |
| - this->setBounds(geometry.fDevBounds); |
| - } |
| - |
| bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| RRectEllipseRendererBatch* that = t->cast<RRectEllipseRendererBatch>(); |
| @@ -1700,35 +1521,22 @@ private: |
| return false; |
| } |
| - if (this->stroke() != that->stroke()) { |
| + if (fStroked != that->fStroked) { |
| return false; |
| } |
| - SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); |
| - if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
| + if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) { |
| return false; |
| } |
| - 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; |
| } |
| - GrColor color() const { return fBatch.fColor; } |
| - bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| - const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
| - bool stroke() const { return fBatch.fStroke; } |
| - |
| - struct BatchTracker { |
| - GrColor fColor; |
| - bool fStroke; |
| - bool fUsesLocalCoords; |
| - bool fColorIgnored; |
| - bool fCoverageIgnored; |
| - }; |
| - |
| - BatchTracker fBatch; |
| - SkSTArray<1, Geometry, true> fGeoData; |
| + bool fStroked; |
| + SkMatrix fViewMatrixIfUsingLocalCoords; |
| + SkSTArray<1, Geometry, true> fGeoData; |
| typedef GrVertexBatch INHERITED; |
| }; |
| @@ -1821,14 +1629,12 @@ static GrDrawBatch* create_rrect_batch(GrColor color, |
| bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
| RRectCircleRendererBatch::Geometry geometry; |
| - geometry.fViewMatrix = viewMatrix; |
| geometry.fColor = color; |
| geometry.fInnerRadius = innerRadius; |
| geometry.fOuterRadius = outerRadius; |
| - geometry.fStroke = isStrokeOnly; |
| geometry.fDevBounds = bounds; |
| - return RRectCircleRendererBatch::Create(geometry); |
| + return new RRectCircleRendererBatch(geometry, viewMatrix, isStrokeOnly); |
| // otherwise we use the ellipse renderer |
| } else { |
| SkScalar innerXRadius = 0.0f; |
| @@ -1869,16 +1675,14 @@ static GrDrawBatch* create_rrect_batch(GrColor color, |
| bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
| RRectEllipseRendererBatch::Geometry geometry; |
| - geometry.fViewMatrix = viewMatrix; |
| geometry.fColor = color; |
| geometry.fXRadius = xRadius; |
| geometry.fYRadius = yRadius; |
| geometry.fInnerXRadius = innerXRadius; |
| geometry.fInnerYRadius = innerYRadius; |
| - geometry.fStroke = isStrokeOnly; |
| geometry.fDevBounds = bounds; |
| - return RRectEllipseRendererBatch::Create(geometry); |
| + return new RRectEllipseRendererBatch(geometry, viewMatrix, isStrokeOnly); |
| } |
| } |