| Index: src/gpu/GrOvalRenderer.cpp
 | 
| diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
 | 
| index e1a29f5e5d5fa7c67ab045a9d022e8e2030ec8dd..659857a9b2fba69bdaf676ad6cc3b0bbd049078a 100644
 | 
| --- a/src/gpu/GrOvalRenderer.cpp
 | 
| +++ b/src/gpu/GrOvalRenderer.cpp
 | 
| @@ -80,16 +80,23 @@ public:
 | 
|      class GLProcessor : public GrGLGeometryProcessor {
 | 
|      public:
 | 
|          GLProcessor(const GrGeometryProcessor&,
 | 
| -                    const GrBatchTracker&) {}
 | 
| +                    const GrBatchTracker&)
 | 
| +            : fColor(GrColor_ILLEGAL) {}
 | 
|  
 | 
|          virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
 | 
|              const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>();
 | 
| +            GrGLGPBuilder* pb = args.fPB;
 | 
| +            const BatchTracker& local = args.fBT.cast<BatchTracker>();
 | 
|              GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
 | 
|  
 | 
|              GrGLVertToFrag v(kVec4f_GrSLType);
 | 
|              args.fPB->addVarying("CircleEdge", &v);
 | 
|              vsBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName);
 | 
|  
 | 
| +            // Setup pass through color
 | 
| +            this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL,
 | 
| +                                        &fColorUniform);
 | 
| +
 | 
|              // setup coord outputs
 | 
|              vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ce.inPosition()->fName);
 | 
|              vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ce.inPosition()->fName);
 | 
| @@ -111,18 +118,29 @@ public:
 | 
|          }
 | 
|  
 | 
|          static void GenKey(const GrGeometryProcessor& processor,
 | 
| -                           const GrBatchTracker&,
 | 
| +                           const GrBatchTracker& bt,
 | 
|                             const GrGLCaps&,
 | 
|                             GrProcessorKeyBuilder* b) {
 | 
| +            const BatchTracker& local = bt.cast<BatchTracker>();
 | 
|              const CircleEdgeEffect& circleEffect = processor.cast<CircleEdgeEffect>();
 | 
| -            b->add32(circleEffect.isStroked());
 | 
| +            b->add32(circleEffect.isStroked() << 16 | local.fInputColorType);
 | 
|          }
 | 
|  
 | 
| -        virtual void setData(const GrGLProgramDataManager&,
 | 
| -                             const GrGeometryProcessor&,
 | 
| -                             const GrBatchTracker&) SK_OVERRIDE {}
 | 
| +        virtual void setData(const GrGLProgramDataManager& pdman,
 | 
| +                             const GrPrimitiveProcessor& gp,
 | 
| +                             const GrBatchTracker& bt) SK_OVERRIDE {
 | 
| +            const BatchTracker& local = bt.cast<BatchTracker>();
 | 
| +            if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
 | 
| +                GrGLfloat c[4];
 | 
| +                GrColorToRGBAFloat(local.fColor, c);
 | 
| +                pdman.set4fv(fColorUniform, 1, c);
 | 
| +                fColor = local.fColor;
 | 
| +            }
 | 
| +        }
 | 
|  
 | 
|      private:
 | 
| +        GrColor fColor;
 | 
| +        UniformHandle fColorUniform;
 | 
|          typedef GrGLGeometryProcessor INHERITED;
 | 
|      };
 | 
|  
 | 
| @@ -136,6 +154,19 @@ public:
 | 
|          return SkNEW_ARGS(GLProcessor, (*this, bt));
 | 
|      }
 | 
|  
 | 
| +    void initBatchTracker(GrBatchTracker* bt, const InitBT& init) const SK_OVERRIDE {
 | 
| +        BatchTracker* local = bt->cast<BatchTracker>();
 | 
| +        local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
 | 
| +
 | 
| +    }
 | 
| +
 | 
| +    bool onCanMakeEqual(const GrBatchTracker& m, const GrBatchTracker& t) const SK_OVERRIDE {
 | 
| +        const BatchTracker& mine = m.cast<BatchTracker>();
 | 
| +        const BatchTracker& theirs = t.cast<BatchTracker>();
 | 
| +        return CanCombineOutput(mine.fInputColorType, mine.fColor,
 | 
| +                                theirs.fInputColorType, theirs.fColor);
 | 
| +    }
 | 
| +
 | 
|  private:
 | 
|      CircleEdgeEffect(GrColor color, bool stroke) : INHERITED(color) {
 | 
|          this->initClassID<CircleEdgeEffect>();
 | 
| @@ -154,6 +185,11 @@ private:
 | 
|          out->setUnknownSingleComponent();
 | 
|      }
 | 
|  
 | 
| +    struct BatchTracker {
 | 
| +        GrGPInput fInputColorType;
 | 
| +        GrColor fColor;
 | 
| +    };
 | 
| +
 | 
|      const GrAttribute* fInPosition;
 | 
|      const GrAttribute* fInCircleEdge;
 | 
|      bool fStroke;
 | 
| @@ -201,11 +237,13 @@ public:
 | 
|      class GLProcessor : public GrGLGeometryProcessor {
 | 
|      public:
 | 
|          GLProcessor(const GrGeometryProcessor&,
 | 
| -                    const GrBatchTracker&) {}
 | 
| +                    const GrBatchTracker&)
 | 
| +            : fColor(GrColor_ILLEGAL) {}
 | 
|  
 | 
|          virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
 | 
|              const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>();
 | 
| -
 | 
| +            GrGLGPBuilder* pb = args.fPB;
 | 
| +            const BatchTracker& local = args.fBT.cast<BatchTracker>();
 | 
|              GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
 | 
|  
 | 
|              GrGLVertToFrag ellipseOffsets(kVec2f_GrSLType);
 | 
| @@ -218,6 +256,10 @@ public:
 | 
|              vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
 | 
|                                     ee.inEllipseRadii()->fName);
 | 
|  
 | 
| +            // Setup pass through color
 | 
| +            this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL,
 | 
| +                                        &fColorUniform);
 | 
| +
 | 
|              // setup coord outputs
 | 
|              vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.inPosition()->fName);
 | 
|              vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPosition()->fName);
 | 
| @@ -254,19 +296,30 @@ public:
 | 
|          }
 | 
|  
 | 
|          static void GenKey(const GrGeometryProcessor& processor,
 | 
| -                           const GrBatchTracker&,
 | 
| +                           const GrBatchTracker& bt,
 | 
|                             const GrGLCaps&,
 | 
|                             GrProcessorKeyBuilder* b) {
 | 
| +            const BatchTracker& local = bt.cast<BatchTracker>();
 | 
|              const EllipseEdgeEffect& ellipseEffect = processor.cast<EllipseEdgeEffect>();
 | 
| -            b->add32(ellipseEffect.isStroked());
 | 
| +            b->add32(ellipseEffect.isStroked() << 16 | local.fInputColorType);
 | 
|          }
 | 
|  
 | 
| -        virtual void setData(const GrGLProgramDataManager&,
 | 
| -                             const GrGeometryProcessor&,
 | 
| -                             const GrBatchTracker&) SK_OVERRIDE {
 | 
| +        virtual void setData(const GrGLProgramDataManager& pdman,
 | 
| +                             const GrPrimitiveProcessor& gp,
 | 
| +                             const GrBatchTracker& bt) SK_OVERRIDE {
 | 
| +            const BatchTracker& local = bt.cast<BatchTracker>();
 | 
| +            if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
 | 
| +                GrGLfloat c[4];
 | 
| +                GrColorToRGBAFloat(local.fColor, c);
 | 
| +                pdman.set4fv(fColorUniform, 1, c);
 | 
| +                fColor = local.fColor;
 | 
| +            }
 | 
|          }
 | 
|  
 | 
|      private:
 | 
| +        GrColor fColor;
 | 
| +        UniformHandle fColorUniform;
 | 
| +
 | 
|          typedef GrGLGeometryProcessor INHERITED;
 | 
|      };
 | 
|  
 | 
| @@ -280,6 +333,18 @@ public:
 | 
|          return SkNEW_ARGS(GLProcessor, (*this, bt));
 | 
|      }
 | 
|  
 | 
| +    void initBatchTracker(GrBatchTracker* bt, const InitBT& init) const SK_OVERRIDE {
 | 
| +        BatchTracker* local = bt->cast<BatchTracker>();
 | 
| +        local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
 | 
| +    }
 | 
| +
 | 
| +    bool onCanMakeEqual(const GrBatchTracker& m, const GrBatchTracker& t) const SK_OVERRIDE {
 | 
| +        const BatchTracker& mine = m.cast<BatchTracker>();
 | 
| +        const BatchTracker& theirs = t.cast<BatchTracker>();
 | 
| +        return CanCombineOutput(mine.fInputColorType, mine.fColor,
 | 
| +                                theirs.fInputColorType, theirs.fColor);
 | 
| +    }
 | 
| +
 | 
|  private:
 | 
|      EllipseEdgeEffect(GrColor color, bool stroke) : INHERITED(color) {
 | 
|          this->initClassID<EllipseEdgeEffect>();
 | 
| @@ -300,6 +365,11 @@ private:
 | 
|          out->setUnknownSingleComponent();
 | 
|      }
 | 
|  
 | 
| +    struct BatchTracker {
 | 
| +        GrGPInput fInputColorType;
 | 
| +        GrColor fColor;
 | 
| +    };
 | 
| +
 | 
|      const GrAttribute* fInPosition;
 | 
|      const GrAttribute* fInEllipseOffset;
 | 
|      const GrAttribute* fInEllipseRadii;
 | 
| @@ -351,11 +421,13 @@ public:
 | 
|      class GLProcessor : public GrGLGeometryProcessor {
 | 
|      public:
 | 
|          GLProcessor(const GrGeometryProcessor&,
 | 
| -                    const GrBatchTracker&) {}
 | 
| +                    const GrBatchTracker&)
 | 
| +            : fColor(GrColor_ILLEGAL) {}
 | 
|  
 | 
|          virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
 | 
|              const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>();
 | 
| -
 | 
| +            GrGLGPBuilder* pb = args.fPB;
 | 
| +            const BatchTracker& local = args.fBT.cast<BatchTracker>();
 | 
|              GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
 | 
|  
 | 
|              GrGLVertToFrag offsets0(kVec2f_GrSLType);
 | 
| @@ -368,6 +440,10 @@ public:
 | 
|              vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
 | 
|                                     ee.inEllipseOffsets1()->fName);
 | 
|  
 | 
| +            // Setup pass through color
 | 
| +            this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL,
 | 
| +                                        &fColorUniform);
 | 
| +
 | 
|              // setup coord outputs
 | 
|              vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.inPosition()->fName);
 | 
|              vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPosition()->fName);
 | 
| @@ -418,20 +494,30 @@ public:
 | 
|          }
 | 
|  
 | 
|          static void GenKey(const GrGeometryProcessor& processor,
 | 
| -                           const GrBatchTracker&,
 | 
| +                           const GrBatchTracker& bt,
 | 
|                             const GrGLCaps&,
 | 
|                             GrProcessorKeyBuilder* b) {
 | 
| +            const BatchTracker& local = bt.cast<BatchTracker>();
 | 
|              const DIEllipseEdgeEffect& ellipseEffect = processor.cast<DIEllipseEdgeEffect>();
 | 
| -
 | 
| -            b->add32(ellipseEffect.getMode());
 | 
| +            b->add32(ellipseEffect.getMode() << 16 | local.fInputColorType);
 | 
|          }
 | 
|  
 | 
| -        virtual void setData(const GrGLProgramDataManager&,
 | 
| -                             const GrGeometryProcessor&,
 | 
| -                             const GrBatchTracker&) SK_OVERRIDE {
 | 
| +        virtual void setData(const GrGLProgramDataManager& pdman,
 | 
| +                             const GrPrimitiveProcessor& gp,
 | 
| +                             const GrBatchTracker& bt) SK_OVERRIDE {
 | 
| +            const BatchTracker& local = bt.cast<BatchTracker>();
 | 
| +            if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
 | 
| +                GrGLfloat c[4];
 | 
| +                GrColorToRGBAFloat(local.fColor, c);
 | 
| +                pdman.set4fv(fColorUniform, 1, c);
 | 
| +                fColor = local.fColor;
 | 
| +            }
 | 
|          }
 | 
|  
 | 
|      private:
 | 
| +        GrColor fColor;
 | 
| +        UniformHandle fColorUniform;
 | 
| +
 | 
|          typedef GrGLGeometryProcessor INHERITED;
 | 
|      };
 | 
|  
 | 
| @@ -445,6 +531,18 @@ public:
 | 
|          return SkNEW_ARGS(GLProcessor, (*this, bt));
 | 
|      }
 | 
|  
 | 
| +    void initBatchTracker(GrBatchTracker* bt, const InitBT& init) const SK_OVERRIDE {
 | 
| +        BatchTracker* local = bt->cast<BatchTracker>();
 | 
| +        local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
 | 
| +    }
 | 
| +
 | 
| +    bool onCanMakeEqual(const GrBatchTracker& m, const GrBatchTracker& t) const SK_OVERRIDE {
 | 
| +        const BatchTracker& mine = m.cast<BatchTracker>();
 | 
| +        const BatchTracker& theirs = t.cast<BatchTracker>();
 | 
| +        return CanCombineOutput(mine.fInputColorType, mine.fColor,
 | 
| +                                theirs.fInputColorType, theirs.fColor);
 | 
| +    }
 | 
| +
 | 
|  private:
 | 
|      DIEllipseEdgeEffect(GrColor color, Mode mode) : INHERITED(color) {
 | 
|          this->initClassID<DIEllipseEdgeEffect>();
 | 
| @@ -465,6 +563,11 @@ private:
 | 
|          out->setUnknownSingleComponent();
 | 
|      }
 | 
|  
 | 
| +    struct BatchTracker {
 | 
| +        GrGPInput fInputColorType;
 | 
| +        GrColor fColor;
 | 
| +    };
 | 
| +
 | 
|      const GrAttribute* fInPosition;
 | 
|      const GrAttribute* fInEllipseOffsets0;
 | 
|      const GrAttribute* fInEllipseOffsets1;
 | 
| 
 |