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);
69910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        fFSCode.appendVAList(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
211910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    /**
212910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     * Helper for begining and ending a block in the fragment code. TODO: Make GrGLShaderBuilder
213910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     * aware of all blocks and turn single \t's into the correct number of tabs (or spaces) so that
214910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     * our shaders print pretty without effect writers tracking indentation.
215910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     */
216910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    class FSBlock {
217910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    public:
218910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        FSBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
219910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger            SkASSERT(NULL != builder);
220910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger            fBuilder->fsCodeAppend("\t{\n");
221910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        }
222910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
223910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        ~FSBlock() {
224910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger            fBuilder->fsCodeAppend("\t}\n");
225910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        }
226910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    private:
227910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        GrGLShaderBuilder* fBuilder;
228910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    };
229910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
2300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprotected:
2310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGpuGL* gpu() const { return fGpu; }
232096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
2330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void setInputColor(const GrGLSLExpr4& inputColor) { fInputColor = inputColor; }
2340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void setInputCoverage(const GrGLSLExpr4& inputCoverage) { fInputCoverage = inputCoverage; }
235096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
2360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
2370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // Generates a name for a variable. The generated string will be name prefixed by the prefix
2400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
2410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // generating stage code.
2420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void nameVariable(SkString* out, char prefix, const char* name);
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // Helper for emitEffects().
2450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void createAndEmitEffects(GrGLProgramEffectsBuilder*,
2460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                              const GrEffectStage* effectStages[],
2470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                              const EffectKey effectKeys[],
2480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                              int effectCnt,
2490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                              GrGLSLExpr4* inOutFSColor);
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual bool compileAndAttachShaders(GrGLuint programId) const;
2520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual void bindProgramLocations(GrGLuint programId) const;
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void appendDecls(const VarArray&, SkString*) const;
2550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void appendUniformDecls(ShaderVisibility, SkString*) const;
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
2580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    class CodeStage : public SkNoncopyable {
2597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    public:
2607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
2617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        bool inStageCode() const {
2637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->validate();
2647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return NULL != fEffectStage;
2657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrEffectStage* effectStage() const {
2687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->validate();
2697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return fEffectStage;
2707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int stageIndex() const {
2737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->validate();
2747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return fCurrentIndex;
2757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        class AutoStageRestore : public SkNoncopyable {
2787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        public:
2797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
2800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                SkASSERT(NULL != codeStage);
2817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fSavedIndex = codeStage->fCurrentIndex;
2827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fSavedEffectStage = codeStage->fEffectStage;
2837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                if (NULL == newStage) {
2857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    codeStage->fCurrentIndex = -1;
2867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                } else {
2877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
2887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                }
2897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                codeStage->fEffectStage = newStage;
2907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fCodeStage = codeStage;
2927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
2937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            ~AutoStageRestore() {
2947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fCodeStage->fCurrentIndex = fSavedIndex;
2957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fCodeStage->fEffectStage = fSavedEffectStage;
2967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
2977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        private:
2987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            CodeStage*              fCodeStage;
2997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            int                     fSavedIndex;
3007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            const GrEffectStage*    fSavedEffectStage;
3017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        };
3027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    private:
3030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
3047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int                     fNextIndex;
3057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int                     fCurrentIndex;
3067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrEffectStage*    fEffectStage;
3077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } fCodeStage;
3087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
3107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * Features that should only be enabled by GrGLShaderBuilder itself.
3117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
3127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    enum GLSLPrivateFeature {
3137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
3147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kEXTShaderFramebufferFetch_GLSLPrivateFeature,
3157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kNVShaderFramebufferFetch_GLSLPrivateFeature,
3167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
3177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool enablePrivateFeature(GLSLPrivateFeature);
3187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
3200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // track the enables separately for each shader.
3217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void addFSFeature(uint32_t featureBit, const char* extensionName);
3227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Interpretation of DstReadKey when generating code
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum {
3257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kNoDstRead_DstReadKey         = 0,
3267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kYesDstRead_DstReadKeyBit     = 0x1, // Set if we do a dst-copy-read.
3277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
3287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kTopLeftOrigin_DstReadKeyBit  = 0x4, // Set if dst-copy origin is top-left.
3297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
3307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    enum {
3327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
3337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
3347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGpuGL*                                fGpu;
3380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager&                     fUniformManager;
3390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    uint32_t                                fFSFeaturesAddedMask;
3400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString                                fFSFunctions;
3410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString                                fFSExtensions;
3420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                                fFSInputs;
3430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                                fFSOutputs;
3440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::BuilderUniformArray fUniforms;
3457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString                                fFSCode;
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool                                    fSetupFragPosition;
3490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fDstCopySamplerUniform;
3500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLSLExpr4                             fInputColor;
3520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLSLExpr4                             fInputCoverage;
3530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool                                    fHasCustomColorOutput;
3550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool                                    fHasSecondaryOutput;
3560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fRTHeightUniform;
3580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fDstCopyTopLeftUniform;
3590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fDstCopyScaleUniform;
3600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fColorUniform;
3610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle       fCoverageUniform;
3620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool                                    fTopLeftFragPosRead;
3640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
3650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger////////////////////////////////////////////////////////////////////////////////
3670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass GrGLFullShaderBuilder : public GrGLShaderBuilder {
3690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerpublic:
3700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLFullShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
3710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /**
3730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * Called by GrGLEffects to add code to one of the shaders.
3740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     */
3750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
3760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        va_list args;
3770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        va_start(args, format);
378910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        fVSCode.appendVAList(format, args);
3790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        va_end(args);
3800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
3810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void vsCodeAppend(const char* str) { fVSCode.append(str); }
3830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger   /** Add a vertex attribute to the current program that is passed in from the vertex data.
3850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger       Returns false if the attribute was already there, true otherwise. */
3860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool addAttribute(GrSLType type, const char* name);
3870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger   /** Add a varying variable to the current program to pass values between vertex and fragment
3890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        shaders. If the last two parameters are non-NULL, they are filled in with the name
3900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        generated. */
3910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void addVarying(GrSLType type,
3920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    const char* name,
3930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    const char** vsOutName = NULL,
3940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    const char** fsInName = NULL);
395096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
3960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
3970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
3980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger      */
3990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
4007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
4020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        as positionAttribute() or it may not be. It depends upon whether the rendering code
4030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        specified explicit local coords or not in the GrDrawState. */
4040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
4057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /**
4070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     * Are explicit local coordinates provided as input to the vertex shader.
4080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     */
4090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
4100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
4120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const SkString* getEffectAttributeName(int attributeIndex) const;
41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual GrGLProgramEffects* createAndEmitEffects(
4150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                const GrEffectStage* effectStages[],
4160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                const EffectKey effectKeys[],
4170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                int effectCnt,
4180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
4190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle getViewMatrixUniform() const {
4210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return fViewMatrixUniform;
4220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
4230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprotected:
4250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual bool compileAndAttachShaders(GrGLuint programId) const SK_OVERRIDE;
4260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE;
4270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprivate:
4290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const GrGLProgramDesc&              fDesc;
4300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                            fVSAttrs;
4310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                            fVSOutputs;
4320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                            fGSInputs;
4330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    VarArray                            fGSOutputs;
4340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString                            fVSCode;
4360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    struct AttributePair {
4380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        void set(int index, const SkString& name) {
4390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fIndex = index; fName = name;
4400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
4410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int      fIndex;
4420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkString fName;
4430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    };
444096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkSTArray<10, AttributePair, true>  fEffectAttributes;
445096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
4460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLUniformManager::UniformHandle   fViewMatrixUniform;
4470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
448363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLShaderVar*                      fPositionVar;
449e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    GrGLShaderVar*                      fLocalCoordsVar;
450e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger
4510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GrGLShaderBuilder INHERITED;
4520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
4530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger////////////////////////////////////////////////////////////////////////////////
4550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder {
4570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerpublic:
4580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrGLFragmentOnlyShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
4590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int getNumTexCoordSets() const { return fNumTexCoordSets; }
4610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int addTexCoordSets(int count);
4620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual GrGLProgramEffects* createAndEmitEffects(
4640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                const GrEffectStage* effectStages[],
4650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                const EffectKey effectKeys[],
4660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                int effectCnt,
4670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
4680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprivate:
4700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fNumTexCoordSets;
4710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GrGLShaderBuilder INHERITED;
47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
476