| Index: src/gpu/GrPipelineBuilder.h | 
| diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h | 
| index af98c3676f13d1374c76e46000b54db7b44dc111..60fcea86c8a233ef37a7c68f2f3993403583d125 100644 | 
| --- a/src/gpu/GrPipelineBuilder.h | 
| +++ b/src/gpu/GrPipelineBuilder.h | 
| @@ -110,6 +110,8 @@ public: | 
| /** | 
| * When this object is destroyed it will remove any color/coverage FPs from the pipeline builder | 
| * that were added after its constructor. | 
| +     * This class can transiently modify its "const" GrPipelineBuilder object but will restore it | 
| +     * when done - so it is notionally "const" correct. | 
| */ | 
| class AutoRestoreFragmentProcessors : public ::SkNoncopyable { | 
| public: | 
| @@ -127,14 +129,20 @@ public: | 
|  | 
| ~AutoRestoreFragmentProcessors() { this->set(NULL); } | 
|  | 
| -        void set(GrPipelineBuilder* ds); | 
| +        void set(const GrPipelineBuilder* ds); | 
|  | 
| bool isSet() const { return SkToBool(fPipelineBuilder); } | 
|  | 
| +        const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* processor) { | 
| +            SkASSERT(this->isSet()); | 
| +            return fPipelineBuilder->addCoverageProcessor(processor); | 
| +        } | 
| + | 
| private: | 
| +        // notionally const (as marginalia) | 
| GrPipelineBuilder*    fPipelineBuilder; | 
| -        int             fColorEffectCnt; | 
| -        int             fCoverageEffectCnt; | 
| +        int                   fColorEffectCnt; | 
| +        int                   fCoverageEffectCnt; | 
| }; | 
|  | 
| /// @} | 
| @@ -246,20 +254,22 @@ public: | 
| * AutoRestoreStencil | 
| * | 
| * This simple struct saves and restores the stencil settings | 
| +     * This class can transiently modify its "const" GrPipelineBuilder object but will restore it | 
| +     * when done - so it is notionally "const" correct. | 
| */ | 
| class AutoRestoreStencil : public ::SkNoncopyable { | 
| public: | 
| AutoRestoreStencil() : fPipelineBuilder(NULL) {} | 
|  | 
| -        AutoRestoreStencil(GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); } | 
| +        AutoRestoreStencil(const GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); } | 
|  | 
| ~AutoRestoreStencil() { this->set(NULL); } | 
|  | 
| -        void set(GrPipelineBuilder* ds) { | 
| +        void set(const GrPipelineBuilder* ds) { | 
| if (fPipelineBuilder) { | 
| fPipelineBuilder->setStencil(fStencilSettings); | 
| } | 
| -            fPipelineBuilder = ds; | 
| +            fPipelineBuilder = const_cast<GrPipelineBuilder*>(ds); | 
| if (ds) { | 
| fStencilSettings = ds->getStencil(); | 
| } | 
| @@ -267,7 +277,13 @@ public: | 
|  | 
| bool isSet() const { return SkToBool(fPipelineBuilder); } | 
|  | 
| +        void setStencil(const GrStencilSettings& settings) { | 
| +            SkASSERT(this->isSet()); | 
| +            fPipelineBuilder->setStencil(settings); | 
| +        } | 
| + | 
| private: | 
| +        // notionally const (as marginalia) | 
| GrPipelineBuilder*  fPipelineBuilder; | 
| GrStencilSettings   fStencilSettings; | 
| }; | 
| @@ -399,6 +415,48 @@ public: | 
| GrProcessorDataManager* getProcessorDataManager() { return fProcDataManager.get(); } | 
| const GrProcessorDataManager* processorDataManager() const { return fProcDataManager.get(); } | 
|  | 
| +    /** | 
| +     * When this object is destroyed it will remove any additions to the GrProcessorDataManager | 
| +     * owned by the GrPipelineBuilder | 
| +     * This class can transiently modify its "const" GrPipelineBuilder object but will restore it | 
| +     * when done - so it is notionally "const" correct. | 
| +     */ | 
| +    class AutoRestoreProcessorDataManager : public ::SkNoncopyable { | 
| +    public: | 
| +        AutoRestoreProcessorDataManager() : fPipelineBuilder(NULL), fSaveMarker(0) {} | 
| + | 
| +        AutoRestoreProcessorDataManager(GrPipelineBuilder* ds) | 
| +            : fPipelineBuilder(NULL) | 
| +            , fSaveMarker(0) { | 
| +            this->set(ds); | 
| +        } | 
| + | 
| +        ~AutoRestoreProcessorDataManager() { this->set(NULL); } | 
| + | 
| +        void set(const GrPipelineBuilder* ds) { | 
| +            if (fPipelineBuilder) { | 
| +                fPipelineBuilder->getProcessorDataManager()->restoreToSaveMarker(/*fSaveMarker*/); | 
| +            } | 
| +            fPipelineBuilder = const_cast<GrPipelineBuilder*>(ds); | 
| +            if (ds) { | 
| +                fSaveMarker = ds->processorDataManager()->currentSaveMarker(); | 
| +            } | 
| +        } | 
| + | 
| +        bool isSet() const { return SkToBool(fPipelineBuilder); } | 
| + | 
| +        GrProcessorDataManager* getProcessorDataManager() { | 
| +            SkASSERT(this->isSet()); | 
| +            return fPipelineBuilder->getProcessorDataManager(); | 
| +        } | 
| + | 
| +    private: | 
| +        // notionally const (as marginalia) | 
| +        GrPipelineBuilder* fPipelineBuilder; | 
| +        uint32_t fSaveMarker; | 
| +    }; | 
| + | 
| + | 
| private: | 
| // Calculating invariant color / coverage information is expensive, so we partially cache the | 
| // results. | 
| @@ -435,7 +493,7 @@ private: | 
|  | 
| // Some of the auto restore objects assume that no effects are removed during their lifetime. | 
| // This is used to assert that this condition holds. | 
| -    SkDEBUGCODE(int fBlockEffectRemovalCnt;) | 
| +    SkDEBUGCODE(mutable int fBlockEffectRemovalCnt;) | 
|  | 
| typedef SkSTArray<4, GrFragmentStage> FragmentStageArray; | 
|  | 
|  |