gfx/skia/trunk/src/gpu/gl/GrGLShaderBuilder.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/gpu/gl/GrGLShaderBuilder.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,475 @@
     1.4 +/*
     1.5 + * Copyright 2012 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#ifndef GrGLShaderBuilder_DEFINED
    1.12 +#define GrGLShaderBuilder_DEFINED
    1.13 +
    1.14 +#include "GrAllocator.h"
    1.15 +#include "GrBackendEffectFactory.h"
    1.16 +#include "GrColor.h"
    1.17 +#include "GrEffect.h"
    1.18 +#include "SkTypes.h"
    1.19 +#include "gl/GrGLProgramEffects.h"
    1.20 +#include "gl/GrGLSL.h"
    1.21 +#include "gl/GrGLUniformManager.h"
    1.22 +
    1.23 +#include <stdarg.h>
    1.24 +
    1.25 +class GrGLContextInfo;
    1.26 +class GrEffectStage;
    1.27 +class GrGLProgramDesc;
    1.28 +
    1.29 +/**
    1.30 +  Contains all the incremental state of a shader as it is being built,as well as helpers to
    1.31 +  manipulate that state.
    1.32 +*/
    1.33 +class GrGLShaderBuilder {
    1.34 +public:
    1.35 +    typedef GrTAllocator<GrGLShaderVar> VarArray;
    1.36 +    typedef GrBackendEffectFactory::EffectKey EffectKey;
    1.37 +    typedef GrGLProgramEffects::TextureSampler TextureSampler;
    1.38 +    typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
    1.39 +    typedef GrGLUniformManager::BuilderUniform BuilderUniform;
    1.40 +
    1.41 +    enum ShaderVisibility {
    1.42 +        kVertex_Visibility   = 0x1,
    1.43 +        kGeometry_Visibility = 0x2,
    1.44 +        kFragment_Visibility = 0x4,
    1.45 +    };
    1.46 +
    1.47 +    GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
    1.48 +    virtual ~GrGLShaderBuilder() {}
    1.49 +
    1.50 +    /**
    1.51 +     * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
    1.52 +     * if code is added that uses one of these features without calling enableFeature()
    1.53 +     */
    1.54 +    enum GLSLFeature {
    1.55 +        kStandardDerivatives_GLSLFeature = 0,
    1.56 +
    1.57 +        kLastGLSLFeature = kStandardDerivatives_GLSLFeature
    1.58 +    };
    1.59 +
    1.60 +    /**
    1.61 +     * If the feature is supported then true is returned and any necessary #extension declarations
    1.62 +     * are added to the shaders. If the feature is not supported then false will be returned.
    1.63 +     */
    1.64 +    bool enableFeature(GLSLFeature);
    1.65 +
    1.66 +    /**
    1.67 +     * Called by GrGLEffects to add code the fragment shader.
    1.68 +     */
    1.69 +    void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
    1.70 +        va_list args;
    1.71 +        va_start(args, format);
    1.72 +        fFSCode.appendVAList(format, args);
    1.73 +        va_end(args);
    1.74 +    }
    1.75 +
    1.76 +    void fsCodeAppend(const char* str) { fFSCode.append(str); }
    1.77 +
    1.78 +    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
    1.79 +        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
    1.80 +        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
    1.81 +    void appendTextureLookup(SkString* out,
    1.82 +                             const TextureSampler&,
    1.83 +                             const char* coordName,
    1.84 +                             GrSLType coordType = kVec2f_GrSLType) const;
    1.85 +
    1.86 +    /** Version of above that appends the result to the fragment shader code instead.*/
    1.87 +    void fsAppendTextureLookup(const TextureSampler&,
    1.88 +                               const char* coordName,
    1.89 +                               GrSLType coordType = kVec2f_GrSLType);
    1.90 +
    1.91 +
    1.92 +    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
    1.93 +        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
    1.94 +        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
    1.95 +        called. */
    1.96 +    void fsAppendTextureLookupAndModulate(const char* modulation,
    1.97 +                                          const TextureSampler&,
    1.98 +                                          const char* coordName,
    1.99 +                                          GrSLType coordType = kVec2f_GrSLType);
   1.100 +
   1.101 +    /** Emits a helper function outside of main() in the fragment shader. */
   1.102 +    void fsEmitFunction(GrSLType returnType,
   1.103 +                        const char* name,
   1.104 +                        int argCnt,
   1.105 +                        const GrGLShaderVar* args,
   1.106 +                        const char* body,
   1.107 +                        SkString* outName);
   1.108 +
   1.109 +    typedef uint8_t DstReadKey;
   1.110 +    typedef uint8_t FragPosKey;
   1.111 +
   1.112 +    /**  Returns a key for adding code to read the copy-of-dst color in service of effects that
   1.113 +         require reading the dst. It must not return 0 because 0 indicates that there is no dst
   1.114 +         copy read at all (in which case this function should not be called). */
   1.115 +    static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
   1.116 +
   1.117 +    /** Returns a key for reading the fragment location. This should only be called if there is an
   1.118 +        effect that will requires the fragment position. If the fragment position is not required,
   1.119 +        the key is 0. */
   1.120 +    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
   1.121 +
   1.122 +    /** If texture swizzling is available using tex parameters then it is preferred over mangling
   1.123 +        the generated shader code. This potentially allows greater reuse of cached shaders. */
   1.124 +    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
   1.125 +
   1.126 +    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
   1.127 +        visibility is a bitfield of ShaderVisibility values indicating from which shaders the
   1.128 +        uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
   1.129 +        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
   1.130 +        it will refer to the final uniform name after return. Use the addUniformArray variant to add
   1.131 +        an array of uniforms.
   1.132 +    */
   1.133 +    GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
   1.134 +                                                 GrSLType type,
   1.135 +                                                 const char* name,
   1.136 +                                                 const char** outName = NULL) {
   1.137 +        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
   1.138 +    }
   1.139 +    GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
   1.140 +                                                      GrSLType type,
   1.141 +                                                      const char* name,
   1.142 +                                                      int arrayCount,
   1.143 +                                                      const char** outName = NULL);
   1.144 +
   1.145 +    const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
   1.146 +        return fUniformManager.getBuilderUniform(fUniforms, u).fVariable;
   1.147 +    }
   1.148 +
   1.149 +    /**
   1.150 +     * Shortcut for getUniformVariable(u).c_str()
   1.151 +     */
   1.152 +    const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
   1.153 +        return this->getUniformVariable(u).c_str();
   1.154 +    }
   1.155 +
   1.156 +    /**
   1.157 +     * This returns a variable name to access the 2D, perspective correct version of the coords in
   1.158 +     * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
   1.159 +     * perspective divide into the fragment shader (xy / z) to convert them to 2D.
   1.160 +     */
   1.161 +    SkString ensureFSCoords2D(const TransformedCoordsArray&, int index);
   1.162 +
   1.163 +    /** Returns a variable name that represents the position of the fragment in the FS. The position
   1.164 +        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
   1.165 +    const char* fragmentPosition();
   1.166 +
   1.167 +    /** Returns the color of the destination pixel. This may be NULL if no effect advertised
   1.168 +        that it will read the destination. */
   1.169 +    const char* dstColor();
   1.170 +
   1.171 +    /**
   1.172 +     * Interfaces used by GrGLProgram.
   1.173 +     */
   1.174 +    const GrGLSLExpr4& getInputColor() const {
   1.175 +        return fInputColor;
   1.176 +    }
   1.177 +    const GrGLSLExpr4& getInputCoverage() const {
   1.178 +        return fInputCoverage;
   1.179 +    }
   1.180 +
   1.181 +    /**
   1.182 +     * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
   1.183 +     * deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key
   1.184 +     * generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and
   1.185 +     * is updated to be the output color of the last stage.
   1.186 +     * The handles to texture samplers for effectStage[i] are added to
   1.187 +     * effectSamplerHandles[i].
   1.188 +     */
   1.189 +    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
   1.190 +                                                     const EffectKey effectKeys[],
   1.191 +                                                     int effectCnt,
   1.192 +                                                     GrGLSLExpr4* inOutFSColor) = 0;
   1.193 +
   1.194 +    const char* getColorOutputName() const;
   1.195 +    const char* enableSecondaryOutput();
   1.196 +
   1.197 +    GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
   1.198 +    GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
   1.199 +        return fDstCopyTopLeftUniform;
   1.200 +    }
   1.201 +    GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
   1.202 +        return fDstCopyScaleUniform;
   1.203 +    }
   1.204 +    GrGLUniformManager::UniformHandle getColorUniform() const { return fColorUniform; }
   1.205 +    GrGLUniformManager::UniformHandle getCoverageUniform() const { return fCoverageUniform; }
   1.206 +    GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
   1.207 +        return fDstCopySamplerUniform;
   1.208 +    }
   1.209 +
   1.210 +    bool finish(GrGLuint* outProgramId);
   1.211 +
   1.212 +    const GrGLContextInfo& ctxInfo() const;
   1.213 +
   1.214 +    /**
   1.215 +     * Helper for begining and ending a block in the fragment code. TODO: Make GrGLShaderBuilder
   1.216 +     * aware of all blocks and turn single \t's into the correct number of tabs (or spaces) so that
   1.217 +     * our shaders print pretty without effect writers tracking indentation.
   1.218 +     */
   1.219 +    class FSBlock {
   1.220 +    public:
   1.221 +        FSBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
   1.222 +            SkASSERT(NULL != builder);
   1.223 +            fBuilder->fsCodeAppend("\t{\n");
   1.224 +        }
   1.225 +
   1.226 +        ~FSBlock() {
   1.227 +            fBuilder->fsCodeAppend("\t}\n");
   1.228 +        }
   1.229 +    private:
   1.230 +        GrGLShaderBuilder* fBuilder;
   1.231 +    };
   1.232 +
   1.233 +protected:
   1.234 +    GrGpuGL* gpu() const { return fGpu; }
   1.235 +
   1.236 +    void setInputColor(const GrGLSLExpr4& inputColor) { fInputColor = inputColor; }
   1.237 +    void setInputCoverage(const GrGLSLExpr4& inputCoverage) { fInputCoverage = inputCoverage; }
   1.238 +
   1.239 +    /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
   1.240 +    GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
   1.241 +
   1.242 +    // Generates a name for a variable. The generated string will be name prefixed by the prefix
   1.243 +    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
   1.244 +    // generating stage code.
   1.245 +    void nameVariable(SkString* out, char prefix, const char* name);
   1.246 +
   1.247 +    // Helper for emitEffects().
   1.248 +    void createAndEmitEffects(GrGLProgramEffectsBuilder*,
   1.249 +                              const GrEffectStage* effectStages[],
   1.250 +                              const EffectKey effectKeys[],
   1.251 +                              int effectCnt,
   1.252 +                              GrGLSLExpr4* inOutFSColor);
   1.253 +
   1.254 +    virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
   1.255 +    virtual void bindProgramLocations(GrGLuint programId) const;
   1.256 +
   1.257 +    void appendDecls(const VarArray&, SkString*) const;
   1.258 +    void appendUniformDecls(ShaderVisibility, SkString*) const;
   1.259 +
   1.260 +private:
   1.261 +    class CodeStage : public SkNoncopyable {
   1.262 +    public:
   1.263 +        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
   1.264 +
   1.265 +        bool inStageCode() const {
   1.266 +            this->validate();
   1.267 +            return NULL != fEffectStage;
   1.268 +        }
   1.269 +
   1.270 +        const GrEffectStage* effectStage() const {
   1.271 +            this->validate();
   1.272 +            return fEffectStage;
   1.273 +        }
   1.274 +
   1.275 +        int stageIndex() const {
   1.276 +            this->validate();
   1.277 +            return fCurrentIndex;
   1.278 +        }
   1.279 +
   1.280 +        class AutoStageRestore : public SkNoncopyable {
   1.281 +        public:
   1.282 +            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
   1.283 +                SkASSERT(NULL != codeStage);
   1.284 +                fSavedIndex = codeStage->fCurrentIndex;
   1.285 +                fSavedEffectStage = codeStage->fEffectStage;
   1.286 +
   1.287 +                if (NULL == newStage) {
   1.288 +                    codeStage->fCurrentIndex = -1;
   1.289 +                } else {
   1.290 +                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
   1.291 +                }
   1.292 +                codeStage->fEffectStage = newStage;
   1.293 +
   1.294 +                fCodeStage = codeStage;
   1.295 +            }
   1.296 +            ~AutoStageRestore() {
   1.297 +                fCodeStage->fCurrentIndex = fSavedIndex;
   1.298 +                fCodeStage->fEffectStage = fSavedEffectStage;
   1.299 +            }
   1.300 +        private:
   1.301 +            CodeStage*              fCodeStage;
   1.302 +            int                     fSavedIndex;
   1.303 +            const GrEffectStage*    fSavedEffectStage;
   1.304 +        };
   1.305 +    private:
   1.306 +        void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
   1.307 +        int                     fNextIndex;
   1.308 +        int                     fCurrentIndex;
   1.309 +        const GrEffectStage*    fEffectStage;
   1.310 +    } fCodeStage;
   1.311 +
   1.312 +    /**
   1.313 +     * Features that should only be enabled by GrGLShaderBuilder itself.
   1.314 +     */
   1.315 +    enum GLSLPrivateFeature {
   1.316 +        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
   1.317 +        kEXTShaderFramebufferFetch_GLSLPrivateFeature,
   1.318 +        kNVShaderFramebufferFetch_GLSLPrivateFeature,
   1.319 +    };
   1.320 +    bool enablePrivateFeature(GLSLPrivateFeature);
   1.321 +
   1.322 +    // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
   1.323 +    // track the enables separately for each shader.
   1.324 +    void addFSFeature(uint32_t featureBit, const char* extensionName);
   1.325 +
   1.326 +    // Interpretation of DstReadKey when generating code
   1.327 +    enum {
   1.328 +        kNoDstRead_DstReadKey         = 0,
   1.329 +        kYesDstRead_DstReadKeyBit     = 0x1, // Set if we do a dst-copy-read.
   1.330 +        kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
   1.331 +        kTopLeftOrigin_DstReadKeyBit  = 0x4, // Set if dst-copy origin is top-left.
   1.332 +    };
   1.333 +
   1.334 +    enum {
   1.335 +        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
   1.336 +        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
   1.337 +        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
   1.338 +    };
   1.339 +
   1.340 +    GrGpuGL*                                fGpu;
   1.341 +    GrGLUniformManager&                     fUniformManager;
   1.342 +    uint32_t                                fFSFeaturesAddedMask;
   1.343 +    SkString                                fFSFunctions;
   1.344 +    SkString                                fFSExtensions;
   1.345 +    VarArray                                fFSInputs;
   1.346 +    VarArray                                fFSOutputs;
   1.347 +    GrGLUniformManager::BuilderUniformArray fUniforms;
   1.348 +
   1.349 +    SkString                                fFSCode;
   1.350 +
   1.351 +    bool                                    fSetupFragPosition;
   1.352 +    GrGLUniformManager::UniformHandle       fDstCopySamplerUniform;
   1.353 +
   1.354 +    GrGLSLExpr4                             fInputColor;
   1.355 +    GrGLSLExpr4                             fInputCoverage;
   1.356 +
   1.357 +    bool                                    fHasCustomColorOutput;
   1.358 +    bool                                    fHasSecondaryOutput;
   1.359 +
   1.360 +    GrGLUniformManager::UniformHandle       fRTHeightUniform;
   1.361 +    GrGLUniformManager::UniformHandle       fDstCopyTopLeftUniform;
   1.362 +    GrGLUniformManager::UniformHandle       fDstCopyScaleUniform;
   1.363 +    GrGLUniformManager::UniformHandle       fColorUniform;
   1.364 +    GrGLUniformManager::UniformHandle       fCoverageUniform;
   1.365 +
   1.366 +    bool                                    fTopLeftFragPosRead;
   1.367 +};
   1.368 +
   1.369 +////////////////////////////////////////////////////////////////////////////////
   1.370 +
   1.371 +class GrGLFullShaderBuilder : public GrGLShaderBuilder {
   1.372 +public:
   1.373 +    GrGLFullShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
   1.374 +
   1.375 +    /**
   1.376 +     * Called by GrGLEffects to add code to one of the shaders.
   1.377 +     */
   1.378 +    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
   1.379 +        va_list args;
   1.380 +        va_start(args, format);
   1.381 +        fVSCode.appendVAList(format, args);
   1.382 +        va_end(args);
   1.383 +    }
   1.384 +
   1.385 +    void vsCodeAppend(const char* str) { fVSCode.append(str); }
   1.386 +
   1.387 +   /** Add a vertex attribute to the current program that is passed in from the vertex data.
   1.388 +       Returns false if the attribute was already there, true otherwise. */
   1.389 +    bool addAttribute(GrSLType type, const char* name);
   1.390 +
   1.391 +   /** Add a varying variable to the current program to pass values between vertex and fragment
   1.392 +        shaders. If the last two parameters are non-NULL, they are filled in with the name
   1.393 +        generated. */
   1.394 +    void addVarying(GrSLType type,
   1.395 +                    const char* name,
   1.396 +                    const char** vsOutName = NULL,
   1.397 +                    const char** fsInName = NULL);
   1.398 +
   1.399 +    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
   1.400 +        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
   1.401 +      */
   1.402 +    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
   1.403 +
   1.404 +    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
   1.405 +        as positionAttribute() or it may not be. It depends upon whether the rendering code
   1.406 +        specified explicit local coords or not in the GrDrawState. */
   1.407 +    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
   1.408 +
   1.409 +    /**
   1.410 +     * Are explicit local coordinates provided as input to the vertex shader.
   1.411 +     */
   1.412 +    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
   1.413 +
   1.414 +    bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
   1.415 +    const SkString* getEffectAttributeName(int attributeIndex) const;
   1.416 +
   1.417 +    virtual GrGLProgramEffects* createAndEmitEffects(
   1.418 +                const GrEffectStage* effectStages[],
   1.419 +                const EffectKey effectKeys[],
   1.420 +                int effectCnt,
   1.421 +                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
   1.422 +
   1.423 +    GrGLUniformManager::UniformHandle getViewMatrixUniform() const {
   1.424 +        return fViewMatrixUniform;
   1.425 +    }
   1.426 +
   1.427 +protected:
   1.428 +    virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE;
   1.429 +    virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE;
   1.430 +
   1.431 +private:
   1.432 +    const GrGLProgramDesc&              fDesc;
   1.433 +    VarArray                            fVSAttrs;
   1.434 +    VarArray                            fVSOutputs;
   1.435 +    VarArray                            fGSInputs;
   1.436 +    VarArray                            fGSOutputs;
   1.437 +
   1.438 +    SkString                            fVSCode;
   1.439 +
   1.440 +    struct AttributePair {
   1.441 +        void set(int index, const SkString& name) {
   1.442 +            fIndex = index; fName = name;
   1.443 +        }
   1.444 +        int      fIndex;
   1.445 +        SkString fName;
   1.446 +    };
   1.447 +    SkSTArray<10, AttributePair, true>  fEffectAttributes;
   1.448 +
   1.449 +    GrGLUniformManager::UniformHandle   fViewMatrixUniform;
   1.450 +
   1.451 +    GrGLShaderVar*                      fPositionVar;
   1.452 +    GrGLShaderVar*                      fLocalCoordsVar;
   1.453 +
   1.454 +    typedef GrGLShaderBuilder INHERITED;
   1.455 +};
   1.456 +
   1.457 +////////////////////////////////////////////////////////////////////////////////
   1.458 +
   1.459 +class GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder {
   1.460 +public:
   1.461 +    GrGLFragmentOnlyShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
   1.462 +
   1.463 +    int getNumTexCoordSets() const { return fNumTexCoordSets; }
   1.464 +    int addTexCoordSets(int count);
   1.465 +
   1.466 +    virtual GrGLProgramEffects* createAndEmitEffects(
   1.467 +                const GrEffectStage* effectStages[],
   1.468 +                const EffectKey effectKeys[],
   1.469 +                int effectCnt,
   1.470 +                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
   1.471 +
   1.472 +private:
   1.473 +    int fNumTexCoordSets;
   1.474 +
   1.475 +    typedef GrGLShaderBuilder INHERITED;
   1.476 +};
   1.477 +
   1.478 +#endif

mercurial