| Index: src/gpu/gl/GrGLShaderBuilder.h | 
| diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h | 
| index 9021a0dee10474e88e57e8c4067d090dd08be017..765a2edf8dbdbbe312e364136274ddcad332fe6d 100644 | 
| --- a/src/gpu/gl/GrGLShaderBuilder.h | 
| +++ b/src/gpu/gl/GrGLShaderBuilder.h | 
| @@ -71,7 +71,7 @@ public: | 
|  | 
| GrAssert(NULL != builder); | 
| SkString name; | 
| -            name.printf("Sampler%d_", idx); | 
| +            name.printf("Sampler%d", idx); | 
| fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, | 
| kSampler2D_GrSLType, | 
| name.c_str()); | 
| @@ -275,16 +275,24 @@ public: | 
| /** Called after building is complete to get the final shader string. */ | 
| void getShader(ShaderType, SkString*) const; | 
|  | 
| -    void setCurrentStage(int stageIdx) { fCurrentStageIdx = stageIdx; } | 
| -    void setNonStage() { fCurrentStageIdx = kNonStageIdx; } | 
| -    // TODO: move remainder of shader code generation to this class and call this privately | 
| -    // Handles of sampler uniforms generated for the effect are appended to samplerHandles. | 
| -    GrGLEffect* createAndEmitGLEffect( | 
| -                                const GrEffectStage& stage, | 
| -                                GrBackendEffectFactory::EffectKey key, | 
| -                                const char* fsInColor, // NULL means no incoming color | 
| -                                const char* fsOutColor, | 
| -                                SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles); | 
| +    /** | 
| +     * Adds code for effects. effectStages contains the effects to add. effectKeys[i] is the key | 
| +     * generated from effectStages[i]. An entry in effectStages can be NULL, in which case it is | 
| +     * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey then it is skipped. | 
| +     * inOutFSColor specifies the input color to the first stage and is updated to be the | 
| +     * output color of the last stage. fsInOutColorKnownValue specifies whether the input color | 
| +     * has a known constant value and is updated to refer to the status of the output color. | 
| +     * The handles to texture samplers for effectStage[i] are added to effectSamplerHandles[i]. The | 
| +     * glEffects array is updated to contain the GrGLEffect generated for each entry in | 
| +     * effectStages. | 
| +     */ | 
| +    void emitEffects(const GrEffectStage* effectStages[], | 
| +                     const GrBackendEffectFactory::EffectKey effectKeys[], | 
| +                     int effectCnt, | 
| +                     SkString*  inOutFSColor, | 
| +                     GrSLConstantVec* fsInOutColorKnownValue, | 
| +                     SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[], | 
| +                     GrGLEffect* glEffects[]); | 
|  | 
| GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; } | 
| GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const { | 
| @@ -338,9 +346,56 @@ public: | 
| VarArray    fFSOutputs; | 
|  | 
| private: | 
| -    enum { | 
| -        kNonStageIdx = -1, | 
| -    }; | 
| +    class CodeStage : GrNoncopyable { | 
| +    public: | 
| +        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} | 
| + | 
| +        bool inStageCode() const { | 
| +            this->validate(); | 
| +            return NULL != fEffectStage; | 
| +        } | 
| + | 
| +        const GrEffectStage* effectStage() const { | 
| +            this->validate(); | 
| +            return fEffectStage; | 
| +        } | 
| + | 
| +        int stageIndex() const { | 
| +            this->validate(); | 
| +            return fCurrentIndex; | 
| +        } | 
| + | 
| +        class AutoStageRestore : GrNoncopyable { | 
| +        public: | 
| +            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) { | 
| +                GrAssert(NULL != codeStage); | 
| +                fSavedIndex = codeStage->fCurrentIndex; | 
| +                fSavedEffectStage = codeStage->fEffectStage; | 
| + | 
| +                if (NULL == newStage) { | 
| +                    codeStage->fCurrentIndex = -1; | 
| +                } else { | 
| +                    codeStage->fCurrentIndex = codeStage->fNextIndex++; | 
| +                } | 
| +                codeStage->fEffectStage = newStage; | 
| + | 
| +                fCodeStage = codeStage; | 
| +            } | 
| +            ~AutoStageRestore() { | 
| +                fCodeStage->fCurrentIndex = fSavedIndex; | 
| +                fCodeStage->fEffectStage = fSavedEffectStage; | 
| +            } | 
| +        private: | 
| +            CodeStage*              fCodeStage; | 
| +            int                     fSavedIndex; | 
| +            const GrEffectStage*    fSavedEffectStage; | 
| +        }; | 
| +    private: | 
| +        void validate() const { GrAssert((NULL == fEffectStage) == (-1 == fCurrentIndex)); } | 
| +        int                     fNextIndex; | 
| +        int                     fCurrentIndex; | 
| +        const GrEffectStage*    fEffectStage; | 
| +    } fCodeStage; | 
|  | 
| /** | 
| * Features that should only be enabled by GrGLShaderBuilder itself. | 
| @@ -356,6 +411,11 @@ private: | 
| // the enables separately for each shader. | 
| void addFSFeature(uint32_t featureBit, const char* extensionName); | 
|  | 
| +    // Generates a name for a variable. The generated string will be name prefixed by the prefix | 
| +    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're | 
| +    // generating stage code. | 
| +    void nameVariable(SkString* out, char prefix, const char* name); | 
| + | 
| // Interpretation of DstReadKey when generating code | 
| enum { | 
| kNoDstRead_DstReadKey         = 0, | 
| @@ -366,7 +426,6 @@ private: | 
|  | 
| const GrGLContextInfo&              fCtxInfo; | 
| GrGLUniformManager&                 fUniformManager; | 
| -    int                                 fCurrentStageIdx; | 
| uint32_t                            fFSFeaturesAddedMask; | 
| SkString                            fFSFunctions; | 
| SkString                            fFSExtensions; | 
|  |