| Index: src/gpu/GrOvalRenderer.cpp
 | 
| diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
 | 
| index 7dd5c8a555f2ebea2875c5071dc73eda86073dbc..128894c30514b1dd1fc1d166983b27ff77f3786b 100644
 | 
| --- a/src/gpu/GrOvalRenderer.cpp
 | 
| +++ b/src/gpu/GrOvalRenderer.cpp
 | 
| @@ -98,37 +98,43 @@ public:
 | 
|          void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
 | 
|              const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>();
 | 
|              GrGLSLGPBuilder* pb = args.fPB;
 | 
| -            GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
 | 
| +            GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
 | 
|  
 | 
|              // emit attributes
 | 
| -            vsBuilder->emitAttributes(ce);
 | 
| +            vertBuilder->emitAttributes(ce);
 | 
|  
 | 
|              GrGLSLVertToFrag v(kVec4f_GrSLType);
 | 
|              args.fPB->addVarying("CircleEdge", &v);
 | 
| -            vsBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName);
 | 
| +            vertBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName);
 | 
|  
 | 
| +            GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
 | 
|              // setup pass through color
 | 
|              if (!ce.colorIgnored()) {
 | 
| -                this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
 | 
| +                this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
 | 
|              }
 | 
|  
 | 
|              // Setup position
 | 
| -            this->setupPosition(pb, gpArgs, ce.inPosition()->fName);
 | 
| +            this->setupPosition(pb, vertBuilder, gpArgs, ce.inPosition()->fName);
 | 
|  
 | 
|              // emit transforms
 | 
| -            this->emitTransforms(args.fPB, gpArgs->fPositionVar, ce.inPosition()->fName,
 | 
| -                                 ce.localMatrix(), args.fTransformsIn, args.fTransformsOut);
 | 
| -
 | 
| -            GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
 | 
| -            fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
 | 
| -            fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z * (1.0 - d), 0.0, 1.0);", v.fsIn());
 | 
| +            this->emitTransforms(args.fPB,
 | 
| +                                 vertBuilder,
 | 
| +                                 gpArgs->fPositionVar,
 | 
| +                                 ce.inPosition()->fName,
 | 
| +                                 ce.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()) {
 | 
| -                fsBuilder->codeAppendf("float innerAlpha = clamp(%s.z * (d - %s.w), 0.0, 1.0);",
 | 
| -                                       v.fsIn(), v.fsIn());
 | 
| -                fsBuilder->codeAppend("edgeAlpha *= innerAlpha;");
 | 
| +                fragBuilder->codeAppendf("float innerAlpha = clamp(%s.z * (d - %s.w), 0.0, 1.0);",
 | 
| +                                         v.fsIn(), v.fsIn());
 | 
| +                fragBuilder->codeAppend("edgeAlpha *= innerAlpha;");
 | 
|              }
 | 
|  
 | 
| -            fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
 | 
| +            fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
 | 
|          }
 | 
|  
 | 
|          static void GenKey(const GrGeometryProcessor& gp,
 | 
| @@ -246,58 +252,63 @@ public:
 | 
|          void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
 | 
|              const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>();
 | 
|              GrGLSLGPBuilder* pb = args.fPB;
 | 
| -            GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
 | 
| +            GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
 | 
|  
 | 
|              // emit attributes
 | 
| -            vsBuilder->emitAttributes(ee);
 | 
| +            vertBuilder->emitAttributes(ee);
 | 
|  
 | 
|              GrGLSLVertToFrag ellipseOffsets(kVec2f_GrSLType);
 | 
|              args.fPB->addVarying("EllipseOffsets", &ellipseOffsets);
 | 
| -            vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(),
 | 
| +            vertBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(),
 | 
|                                     ee.inEllipseOffset()->fName);
 | 
|  
 | 
|              GrGLSLVertToFrag ellipseRadii(kVec4f_GrSLType);
 | 
|              args.fPB->addVarying("EllipseRadii", &ellipseRadii);
 | 
| -            vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
 | 
| +            vertBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
 | 
|                                     ee.inEllipseRadii()->fName);
 | 
|  
 | 
| +            GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
 | 
|              // setup pass through color
 | 
|              if (!ee.colorIgnored()) {
 | 
| -                this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
 | 
| +                this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
 | 
|              }
 | 
|  
 | 
|              // Setup position
 | 
| -            this->setupPosition(pb, gpArgs, ee.inPosition()->fName);
 | 
| +            this->setupPosition(pb, vertBuilder, gpArgs, ee.inPosition()->fName);
 | 
|  
 | 
|              // emit transforms
 | 
| -            this->emitTransforms(args.fPB, gpArgs->fPositionVar, ee.inPosition()->fName,
 | 
| -                                 ee.localMatrix(), args.fTransformsIn, args.fTransformsOut);
 | 
| +            this->emitTransforms(args.fPB,
 | 
| +                                 vertBuilder,
 | 
| +                                 gpArgs->fPositionVar,
 | 
| +                                 ee.inPosition()->fName,
 | 
| +                                 ee.localMatrix(),
 | 
| +                                 args.fTransformsIn,
 | 
| +                                 args.fTransformsOut);
 | 
|  
 | 
|              // for outer curve
 | 
| -            GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
 | 
| -            fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
 | 
| -                                   ellipseRadii.fsIn());
 | 
| -            fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
 | 
| -            fsBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellipseRadii.fsIn());
 | 
| -            fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
 | 
| +            fragBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
 | 
| +                                     ellipseRadii.fsIn());
 | 
| +            fragBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
 | 
| +            fragBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellipseRadii.fsIn());
 | 
| +            fragBuilder->codeAppend("float grad_dot = dot(grad, grad);");
 | 
|  
 | 
|              // avoid calling inversesqrt on zero.
 | 
| -            fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
 | 
| -            fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
 | 
| -            fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
 | 
| +            fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
 | 
| +            fragBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
 | 
| +            fragBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
 | 
|  
 | 
|              // for inner curve
 | 
|              if (ee.isStroked()) {
 | 
| -                fsBuilder->codeAppendf("scaledOffset = %s*%s.zw;",
 | 
| -                                       ellipseOffsets.fsIn(), ellipseRadii.fsIn());
 | 
| -                fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
 | 
| -                fsBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;",
 | 
| -                                       ellipseRadii.fsIn());
 | 
| -                fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
 | 
| -                fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
 | 
| +                fragBuilder->codeAppendf("scaledOffset = %s*%s.zw;",
 | 
| +                                         ellipseOffsets.fsIn(), ellipseRadii.fsIn());
 | 
| +                fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
 | 
| +                fragBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;",
 | 
| +                                         ellipseRadii.fsIn());
 | 
| +                fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
 | 
| +                fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
 | 
|              }
 | 
|  
 | 
| -            fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
 | 
| +            fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
 | 
|          }
 | 
|  
 | 
|          static void GenKey(const GrGeometryProcessor& gp,
 | 
| @@ -421,73 +432,81 @@ public:
 | 
|          void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
 | 
|              const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>();
 | 
|              GrGLSLGPBuilder* pb = args.fPB;
 | 
| -            GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
 | 
| +            GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
 | 
|  
 | 
|              // emit attributes
 | 
| -            vsBuilder->emitAttributes(ee);
 | 
| +            vertBuilder->emitAttributes(ee);
 | 
|  
 | 
|              GrGLSLVertToFrag offsets0(kVec2f_GrSLType);
 | 
|              args.fPB->addVarying("EllipseOffsets0", &offsets0);
 | 
| -            vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
 | 
| +            vertBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
 | 
|                                     ee.inEllipseOffsets0()->fName);
 | 
|  
 | 
|              GrGLSLVertToFrag offsets1(kVec2f_GrSLType);
 | 
|              args.fPB->addVarying("EllipseOffsets1", &offsets1);
 | 
| -            vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
 | 
| +            vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
 | 
|                                     ee.inEllipseOffsets1()->fName);
 | 
|  
 | 
| +            GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
 | 
|              // setup pass through color
 | 
|              if (!ee.colorIgnored()) {
 | 
| -                this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
 | 
| +                this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
 | 
|              }
 | 
|  
 | 
|              // Setup position
 | 
| -            this->setupPosition(pb, gpArgs, ee.inPosition()->fName, ee.viewMatrix(),
 | 
| +            this->setupPosition(pb,
 | 
| +                                vertBuilder,
 | 
| +                                gpArgs,
 | 
| +                                ee.inPosition()->fName,
 | 
| +                                ee.viewMatrix(),
 | 
|                                  &fViewMatrixUniform);
 | 
|  
 | 
|              // emit transforms
 | 
| -            this->emitTransforms(args.fPB, gpArgs->fPositionVar, ee.inPosition()->fName,
 | 
| -                                 args.fTransformsIn, args.fTransformsOut);
 | 
| -
 | 
| -            GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
 | 
| -            SkAssertResult(fsBuilder->enableFeature(
 | 
| +            this->emitTransforms(args.fPB,
 | 
| +                                 vertBuilder,
 | 
| +                                 gpArgs->fPositionVar,
 | 
| +                                 ee.inPosition()->fName,
 | 
| +                                 args.fTransformsIn,
 | 
| +                                 args.fTransformsOut);
 | 
| +
 | 
| +            SkAssertResult(fragBuilder->enableFeature(
 | 
|                      GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
 | 
|              // for outer curve
 | 
| -            fsBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn());
 | 
| -            fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
 | 
| -            fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn());
 | 
| -            fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn());
 | 
| -            fsBuilder->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());
 | 
| -
 | 
| -            fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
 | 
| +            fragBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn());
 | 
| +            fragBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
 | 
| +            fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn());
 | 
| +            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());
 | 
| +
 | 
| +            fragBuilder->codeAppend("float grad_dot = dot(grad, grad);");
 | 
|              // avoid calling inversesqrt on zero.
 | 
| -            fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
 | 
| -            fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
 | 
| +            fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
 | 
| +            fragBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
 | 
|              if (kHairline == ee.getMode()) {
 | 
|                  // can probably do this with one step
 | 
| -                fsBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);");
 | 
| -                fsBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);");
 | 
| +                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);");
 | 
|              } else {
 | 
| -                fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
 | 
| +                fragBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
 | 
|              }
 | 
|  
 | 
|              // for inner curve
 | 
|              if (kStroke == ee.getMode()) {
 | 
| -                fsBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn());
 | 
| -                fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
 | 
| -                fsBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
 | 
| -                fsBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn());
 | 
| -                fsBuilder->codeAppendf("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);",
 | 
| -                                       offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(),
 | 
| -                                       offsets1.fsIn());
 | 
| -                fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
 | 
| -                fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
 | 
| +                fragBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn());
 | 
| +                fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
 | 
| +                fragBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
 | 
| +                fragBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn());
 | 
| +                fragBuilder->codeAppendf("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);",
 | 
| +                                         offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(),
 | 
| +                                         offsets1.fsIn());
 | 
| +                fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
 | 
| +                fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
 | 
|              }
 | 
|  
 | 
| -            fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
 | 
| +            fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
 | 
|          }
 | 
|  
 | 
|          static void GenKey(const GrGeometryProcessor& gp,
 | 
| 
 |