GrGLShaderBuilder.h revision 0a657bbc2c6fc9daf699942e023050536d5ec95f
180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef GrGLShaderBuilder_DEFINED
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GrGLShaderBuilder_DEFINED
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrAllocator.h"
12363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrBackendEffectFactory.h"
137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrColor.h"
14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrEffect.h"
150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkTypes.h"
160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "gl/GrGLProgramEffects.h"
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLSL.h"
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLUniformManager.h"
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <stdarg.h>
21096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrGLContextInfo;
23e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenbergerclass GrEffectStage;
247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGLProgramDesc;
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  Contains all the incremental state of a shader as it is being built,as well as helpers to
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  manipulate that state.
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrGLShaderBuilder {
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GrTAllocator<GrGLShaderVar> VarArray;
330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GrBackendEffectFactory::EffectKey EffectKey;
340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GrGLProgramEffects::TextureSampler TextureSampler;
350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GrGLUniformManager::BuilderUniform BuilderUniform;
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    enum ShaderVisibility {
390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        kVertex_Visibility   = 0x1,
400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        kGeometry_Visibility = 0x2,
410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        kFragment_Visibility = 0x4,
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual ~GrGLShaderBuilder() {}
467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * if code is added that uses one of these features without calling enableFeature()
507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    enum GLSLFeature {
527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kStandardDerivatives_GLSLFeature = 0,
537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kLastGLSLFeature = kStandardDerivatives_GLSLFeature
557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * If the feature is supported then true is returned and any necessary #extension declarations
597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * are added to the shaders. If the feature is not supported then false will be returned.
607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool enableFeature(GLSLFeature);
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
63096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    /**
640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * Called by GrGLEffects to add code the fragment shader.
65096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger     */
66096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
67096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_list args;
68096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_start(args, format);
690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fFSCode.appendf(format, args);
70096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_end(args);
71096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
72096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void fsCodeAppend(const char* str) { fFSCode.append(str); }
74096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
75363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
76363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
77363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void appendTextureLookup(SkString* out,
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             const TextureSampler&,
80363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                             const char* coordName,
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             GrSLType coordType = kVec2f_GrSLType) const;
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /** Version of above that appends the result to the fragment shader code instead.*/
840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void fsAppendTextureLookup(const TextureSampler&,
850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                               const char* coordName,
860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                               GrSLType coordType = kVec2f_GrSLType);
87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
88096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        called. */
930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void fsAppendTextureLookupAndModulate(const char* modulation,
940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                          const TextureSampler&,
950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                          const char* coordName,
960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                          GrSLType coordType = kVec2f_GrSLType);
970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /** Emits a helper function outside of main() in the fragment shader. */
990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void fsEmitFunction(GrSLType returnType,
1000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                        const char* name,
1010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                        int argCnt,
1020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                        const GrGLShaderVar* args,
1030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                        const char* body,
1040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                        SkString* outName);
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef uint8_t DstReadKey;
1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef uint8_t FragPosKey;
1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**  Returns a key for adding code to read the copy-of-dst color in service of effects that
1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger         require reading the dst. It must not return 0 because 0 indicates that there is no dst
1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger         copy read at all (in which case this function should not be called). */
1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /** Returns a key for reading the fragment location. This should only be called if there is an
1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        effect that will requires the fragment position. If the fragment position is not required,
1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        the key is 0. */
1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** If texture swizzling is available using tex parameters then it is preferred over mangling
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        the generated shader code. This potentially allows greater reuse of cached shaders. */
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
123363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
1240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        visibility is a bitfield of ShaderVisibility values indicating from which shaders the
1250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        it will refer to the final uniform name after return. Use the addUniformArray variant to add
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        an array of uniforms.
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 GrSLType type,
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 const char* name,
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 const char** outName = NULL) {
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      GrSLType type,
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      const char* name,
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      int arrayCount,
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      const char** outName = NULL);
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
1430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return fUniformManager.getBuilderUniform(fUniforms, u).fVariable;
1440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
147363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     * Shortcut for getUniformVariable(u).c_str()
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return this->getUniformVariable(u).c_str();
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /**
1540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * This returns a variable name to access the 2D, perspective correct version of the coords in
1550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
1560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * perspective divide into the fragment shader (xy / z) to convert them to 2D.
1570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     */
1580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString ensureFSCoords2D(const TransformedCoordsArray&, int index);
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
160363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Returns a variable name that represents the position of the fragment in the FS. The position
161363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
162363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    const char* fragmentPosition();
163363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
1647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /** Returns the color of the destination pixel. This may be NULL if no effect advertised
1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        that it will read the destination. */
1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* dstColor();
1677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
168e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    /**
169d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger     * Interfaces used by GrGLProgram.
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
1710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLSLExpr4& getInputColor() const {
1720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return fInputColor;
1730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLSLExpr4& getInputCoverage() const {
1750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return fInputCoverage;
1760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
177d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
1787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
1790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
1800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key
1810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and
1820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * is updated to be the output color of the last stage.
1830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * The handles to texture samplers for effectStage[i] are added to
1840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * effectSamplerHandles[i].
1857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
1860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
1870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                                     const EffectKey effectKeys[],
1880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                                     int effectCnt,
1890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                                     GrGLSLExpr4* inOutFSColor) = 0;
1900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const char* getColorOutputName() const;
1920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const char* enableSecondaryOutput();
1937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
194363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
1957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
1967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fDstCopyTopLeftUniform;
1977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
1997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fDstCopyScaleUniform;
2007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle getColorUniform() const { return fColorUniform; }
2020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle getCoverageUniform() const { return fCoverageUniform; }
2037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
2040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return fDstCopySamplerUniform;
2057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
206096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
2070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool finish(GrGLuint* outProgramId);
208096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
2090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLContextInfo& ctxInfo() const;
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprotected:
2120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGpuGL* gpu() const { return fGpu; }
213096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
2140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void setInputColor(const GrGLSLExpr4& inputColor) { fInputColor = inputColor; }
2150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void setInputCoverage(const GrGLSLExpr4& inputCoverage) { fInputCoverage = inputCoverage; }
216096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
2170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
2180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // Generates a name for a variable. The generated string will be name prefixed by the prefix
2210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
2220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // generating stage code.
2230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void nameVariable(SkString* out, char prefix, const char* name);
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // Helper for emitEffects().
2260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void createAndEmitEffects(GrGLProgramEffectsBuilder*,
2270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                              const GrEffectStage* effectStages[],
2280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                              const EffectKey effectKeys[],
2290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                              int effectCnt,
2300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                              GrGLSLExpr4* inOutFSColor);
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual bool compileAndAttachShaders(GrGLuint programId) const;
2330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual void bindProgramLocations(GrGLuint programId) const;
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void appendDecls(const VarArray&, SkString*) const;
2360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void appendUniformDecls(ShaderVisibility, SkString*) const;
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
2390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    class CodeStage : public SkNoncopyable {
2407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    public:
2417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
2427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        bool inStageCode() const {
2447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->validate();
2457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return NULL != fEffectStage;
2467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrEffectStage* effectStage() const {
2497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->validate();
2507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return fEffectStage;
2517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int stageIndex() const {
2547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->validate();
2557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return fCurrentIndex;
2567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        class AutoStageRestore : public SkNoncopyable {
2597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        public:
2607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
2610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                SkASSERT(NULL != codeStage);
2627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fSavedIndex = codeStage->fCurrentIndex;
2637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fSavedEffectStage = codeStage->fEffectStage;
2647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                if (NULL == newStage) {
2667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    codeStage->fCurrentIndex = -1;
2677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                } else {
2687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
2697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                }
2707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                codeStage->fEffectStage = newStage;
2717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fCodeStage = codeStage;
2737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
2747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            ~AutoStageRestore() {
2757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fCodeStage->fCurrentIndex = fSavedIndex;
2767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fCodeStage->fEffectStage = fSavedEffectStage;
2777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
2787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        private:
2797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            CodeStage*              fCodeStage;
2807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            int                     fSavedIndex;
2817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            const GrEffectStage*    fSavedEffectStage;
2827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        };
2837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    private:
2840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
2857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int                     fNextIndex;
2867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int                     fCurrentIndex;
2877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrEffectStage*    fEffectStage;
2887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } fCodeStage;
2897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
2917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * Features that should only be enabled by GrGLShaderBuilder itself.
2927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
2937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    enum GLSLPrivateFeature {
2947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
2957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kEXTShaderFramebufferFetch_GLSLPrivateFeature,
2967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kNVShaderFramebufferFetch_GLSLPrivateFeature,
2977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
2987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool enablePrivateFeature(GLSLPrivateFeature);
2997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
3010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // track the enables separately for each shader.
3027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void addFSFeature(uint32_t featureBit, const char* extensionName);
3037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Interpretation of DstReadKey when generating code
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum {
3067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kNoDstRead_DstReadKey         = 0,
3077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kYesDstRead_DstReadKeyBit     = 0x1, // Set if we do a dst-copy-read.
3087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
3097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kTopLeftOrigin_DstReadKeyBit  = 0x4, // Set if dst-copy origin is top-left.
3107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
3117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    enum {
3137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
3147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
3157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGpuGL*                                fGpu;
3190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager&                     fUniformManager;
3200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    uint32_t                                fFSFeaturesAddedMask;
3210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString                                fFSFunctions;
3220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString                                fFSExtensions;
3230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                                fFSInputs;
3240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                                fFSOutputs;
3250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::BuilderUniformArray fUniforms;
3267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString                                fFSCode;
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool                                    fSetupFragPosition;
3300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fDstCopySamplerUniform;
3310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLSLExpr4                             fInputColor;
3330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLSLExpr4                             fInputCoverage;
3340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool                                    fHasCustomColorOutput;
3360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool                                    fHasSecondaryOutput;
3370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fRTHeightUniform;
3390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fDstCopyTopLeftUniform;
3400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fDstCopyScaleUniform;
3410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fColorUniform;
3420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fCoverageUniform;
3430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool                                    fTopLeftFragPosRead;
3450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
3460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger////////////////////////////////////////////////////////////////////////////////
3480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass GrGLFullShaderBuilder : public GrGLShaderBuilder {
3500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerpublic:
3510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLFullShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
3520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /**
3540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * Called by GrGLEffects to add code to one of the shaders.
3550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     */
3560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
3570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        va_list args;
3580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        va_start(args, format);
3590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fVSCode.appendf(format, args);
3600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        va_end(args);
3610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
3620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void vsCodeAppend(const char* str) { fVSCode.append(str); }
3640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger   /** Add a vertex attribute to the current program that is passed in from the vertex data.
3660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger       Returns false if the attribute was already there, true otherwise. */
3670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool addAttribute(GrSLType type, const char* name);
3680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger   /** Add a varying variable to the current program to pass values between vertex and fragment
3700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        shaders. If the last two parameters are non-NULL, they are filled in with the name
3710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        generated. */
3720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void addVarying(GrSLType type,
3730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    const char* name,
3740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    const char** vsOutName = NULL,
3750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    const char** fsInName = NULL);
376096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
3770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
3780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
3790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger      */
3800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
3817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
3830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        as positionAttribute() or it may not be. It depends upon whether the rendering code
3840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        specified explicit local coords or not in the GrDrawState. */
3850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
3867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /**
3880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * Are explicit local coordinates provided as input to the vertex shader.
3890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     */
3900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
3910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
3930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const SkString* getEffectAttributeName(int attributeIndex) const;
39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual GrGLProgramEffects* createAndEmitEffects(
3960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                const GrEffectStage* effectStages[],
3970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                const EffectKey effectKeys[],
3980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                int effectCnt,
3990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
4000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle getViewMatrixUniform() const {
4020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return fViewMatrixUniform;
4030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
4040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprotected:
4060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual bool compileAndAttachShaders(GrGLuint programId) const SK_OVERRIDE;
4070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE;
4080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprivate:
4100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLProgramDesc&              fDesc;
4110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                            fVSAttrs;
4120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                            fVSOutputs;
4130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                            fGSInputs;
4140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                            fGSOutputs;
4150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString                            fVSCode;
4170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    struct AttributePair {
4190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        void set(int index, const SkString& name) {
4200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fIndex = index; fName = name;
4210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
4220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int      fIndex;
4230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkString fName;
4240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    };
425096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkSTArray<10, AttributePair, true>  fEffectAttributes;
426096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
4270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle   fViewMatrixUniform;
4280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
429363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLShaderVar*                      fPositionVar;
430e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    GrGLShaderVar*                      fLocalCoordsVar;
431e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger
4320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GrGLShaderBuilder INHERITED;
4330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
4340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger////////////////////////////////////////////////////////////////////////////////
4360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder {
4380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerpublic:
4390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLFragmentOnlyShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
4400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int getNumTexCoordSets() const { return fNumTexCoordSets; }
4420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int addTexCoordSets(int count);
4430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual GrGLProgramEffects* createAndEmitEffects(
4450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                const GrEffectStage* effectStages[],
4460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                const EffectKey effectKeys[],
4470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                int effectCnt,
4480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
4490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprivate:
4510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fNumTexCoordSets;
4520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GrGLShaderBuilder INHERITED;
45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
457