| Index: src/gpu/GrOvalRenderer.cpp
|
| diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
|
| index 1fb214a260ed432a0e1824e2e576f79b6e5fb310..d1b8a6b1fb42e122057a36fc2271e052b2f6cbf9 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,25 @@ const GrGeometryProcessor* EllipseEdgeEffect::TestCreate(GrProcessorTestData* d)
|
| * The result is device-independent and can be used with any affine matrix.
|
| */
|
|
|
| -class DIEllipseEdgeEffect : public GrGeometryProcessor {
|
| -public:
|
| - enum Mode { kStroke = 0, kHairline, kFill };
|
| +enum class DIEllipseStyle { kStroke = 0, kHairline, kFill };
|
|
|
| - static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, Mode mode,
|
| - bool usesLocalCoords) {
|
| - return new DIEllipseEdgeEffect(color, viewMatrix, mode, usesLocalCoords);
|
| +class DIEllipseGeometryProcessor : public GrGeometryProcessor {
|
| +public:
|
| + 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));
|
| + fInEllipseOffsets0 = &this->addVertexAttrib(Attribute("inEllipseOffsets0",
|
| + kVec2f_GrVertexAttribType));
|
| + fInEllipseOffsets1 = &this->addVertexAttrib(Attribute("inEllipseOffsets1",
|
| + kVec2f_GrVertexAttribType));
|
| + fStyle = style;
|
| }
|
|
|
| - virtual ~DIEllipseEdgeEffect() {}
|
| +
|
| + virtual ~DIEllipseGeometryProcessor() {}
|
|
|
| const char* name() const override { return "DIEllipseEdge"; }
|
|
|
| @@ -406,49 +376,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 +418,7 @@ public:
|
| varyingHandler,
|
| uniformHandler,
|
| gpArgs->fPositionVar,
|
| - ee.inPosition()->fName,
|
| + diegp.inPosition()->fName,
|
| args.fTransformsIn,
|
| args.fTransformsOut);
|
|
|
| @@ -469,13 +431,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 +447,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 +466,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,43 +500,23 @@ public:
|
| }
|
|
|
| private:
|
| - DIEllipseEdgeEffect(GrColor color, const SkMatrix& viewMatrix, Mode mode,
|
| - bool usesLocalCoords)
|
| - : fColor(color)
|
| - , fViewMatrix(viewMatrix)
|
| - , fUsesLocalCoords(usesLocalCoords) {
|
| - this->initClassID<DIEllipseEdgeEffect>();
|
| - fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType,
|
| - kHigh_GrSLPrecision));
|
| - fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
|
| - fInEllipseOffsets0 = &this->addVertexAttrib(Attribute("inEllipseOffsets0",
|
| - kVec2f_GrVertexAttribType));
|
| - fInEllipseOffsets1 = &this->addVertexAttrib(Attribute("inEllipseOffsets1",
|
| - kVec2f_GrVertexAttribType));
|
| - fMode = mode;
|
| - }
|
| -
|
| 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 new DIEllipseGeometryProcessor(GrTest::TestMatrix(d->fRandom),
|
| + (DIEllipseStyle)(d->fRandom->nextRangeU(0,2)));
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| @@ -609,16 +551,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 +591,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 +659,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 +666,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 +724,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 +747,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 +775,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 +850,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 +858,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 +946,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 +981,7 @@ public:
|
| SkScalar fGeoDx;
|
| SkScalar fGeoDy;
|
| GrColor fColor;
|
| - DIEllipseEdgeEffect::Mode fMode;
|
| + DIEllipseStyle fStyle;
|
| };
|
|
|
| static GrDrawBatch* Create(const Geometry& geometry, const SkRect& bounds) {
|
| @@ -1114,26 +1001,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(new DIEllipseGeometryProcessor(this->viewMatrix(),
|
| + this->style()));
|
|
|
| target->initDraw(gp, this->pipeline());
|
|
|
| @@ -1187,9 +1063,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 +1077,7 @@ private:
|
| return false;
|
| }
|
|
|
| - if (this->mode() != that->mode()) {
|
| + if (this->style() != that->style()) {
|
| return false;
|
| }
|
|
|
| @@ -1212,25 +1086,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; }
|
| + DIEllipseStyle style() const { return fGeoData[0].fStyle; }
|
|
|
| - struct BatchTracker {
|
| - GrColor fColor;
|
| - DIEllipseEdgeEffect::Mode fMode;
|
| - bool fUsesLocalCoords;
|
| - bool fColorIgnored;
|
| - bool fCoverageIgnored;
|
| - };
|
| -
|
| - BatchTracker fBatch;
|
| + bool fUsesLocalCoords;
|
| SkSTArray<1, Geometry, true> fGeoData;
|
|
|
| typedef GrVertexBatch INHERITED;
|
| @@ -1245,10 +1109,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 +1146,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 +1168,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 +1234,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 +1261,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 +1285,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 +1350,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 +1357,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 +1382,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 +1410,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 +1433,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 +1509,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 +1517,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 +1625,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 +1671,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);
|
| }
|
| }
|
|
|
|
|