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"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLSL.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLUniformManager.h"
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <stdarg.h>
19096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrGLContextInfo;
21e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenbergerclass GrEffectStage;
227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGLProgramDesc;
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  Contains all the incremental state of a shader as it is being built,as well as helpers to
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  manipulate that state.
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrGLShaderBuilder {
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
31d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger     * Passed to GrGLEffects to add texture reads to their shader code.
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    class TextureSampler {
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    public:
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        TextureSampler()
367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            : fConfigComponentMask(0)
377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            , fSamplerUniform(GrGLUniformManager::kInvalidUniformHandle) {
387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // we will memcpy the first 4 bytes from passed in swizzle. This ensures the string is
397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // terminated.
407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSwizzle[4] = '\0';
417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        TextureSampler(const TextureSampler& other) { *this = other; }
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        TextureSampler& operator= (const TextureSampler& other) {
467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            GrAssert(0 == fConfigComponentMask);
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fConfigComponentMask = other.fConfigComponentMask;
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fSamplerUniform = other.fSamplerUniform;
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return *this;
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // bitfield of GrColorComponentFlags present in the texture's config.
557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        uint32_t configComponentMask() const { return fConfigComponentMask; }
567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const char* swizzle() const { return fSwizzle; }
587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        bool isInitialized() const { return 0 != fConfigComponentMask; }
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    private:
62d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        // The idx param is used to ensure multiple samplers within a single effect have unique
637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // uniform names. swizzle is a four char max string made up of chars 'r', 'g', 'b', and 'a'.
647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        void init(GrGLShaderBuilder* builder,
657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                  uint32_t configComponentMask,
667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                  const char* swizzle,
677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                  int idx) {
687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            GrAssert(!this->isInitialized());
697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            GrAssert(0 != configComponentMask);
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(NULL != builder);
73d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            SkString name;
747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            name.printf("Sampler%d", idx);
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                  kSampler2D_GrSLType,
77d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                                  name.c_str());
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(GrGLUniformManager::kInvalidUniformHandle != fSamplerUniform);
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fConfigComponentMask = configComponentMask;
817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            memcpy(fSwizzle, swizzle, 4);
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int idx) {
857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            GrAssert(NULL != access);
867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->init(builder,
877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                       GrPixelConfigComponentMask(access->getTexture()->config()),
887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                       access->getSwizzle(),
897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                       idx);
907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        uint32_t                          fConfigComponentMask;
937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        char                              fSwizzle[5];
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrGLUniformManager::UniformHandle fSamplerUniform;
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        friend class GrGLShaderBuilder; // to call init().
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef SkTArray<TextureSampler> TextureSamplerArray;
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum ShaderType {
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kVertex_ShaderType   = 0x1,
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kGeometry_ShaderType = 0x2,
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kFragment_ShaderType = 0x4,
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, const GrGLProgramDesc&);
1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * if code is added that uses one of these features without calling enableFeature()
1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    enum GLSLFeature {
1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kStandardDerivatives_GLSLFeature = 0,
1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kLastGLSLFeature = kStandardDerivatives_GLSLFeature
1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * If the feature is supported then true is returned and any necessary #extension declarations
1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * are added to the shaders. If the feature is not supported then false will be returned.
1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool enableFeature(GLSLFeature);
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
125096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    /**
126096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger     * Called by GrGLEffects to add code to one of the shaders.
127096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger     */
128096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
129096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_list args;
130096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_start(args, format);
131096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        this->codeAppendf(kVertex_ShaderType, format, args);
132096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_end(args);
133096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
134096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
135096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
136096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_list args;
137096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_start(args, format);
138096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        this->codeAppendf(kGeometry_ShaderType, format, args);
139096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_end(args);
140096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
141096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
142096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
143096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_list args;
144096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_start(args, format);
145096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        this->codeAppendf(kFragment_ShaderType, format, args);
146096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_end(args);
147096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
148096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
149096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void vsCodeAppend(const char* str) { this->codeAppend(kVertex_ShaderType, str); }
150096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void gsCodeAppend(const char* str) { this->codeAppend(kGeometry_ShaderType, str); }
151096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void fsCodeAppend(const char* str) { this->codeAppend(kFragment_ShaderType, str); }
152096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
153363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
154363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
155363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void appendTextureLookup(SkString* out,
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             const TextureSampler&,
158363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                             const char* coordName,
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             GrSLType coordType = kVec2f_GrSLType) const;
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
161096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    /** Version of above that appends the result to the shader code rather than an SkString.
162096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        Currently the shader type must be kFragment */
163096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void appendTextureLookup(ShaderType,
164096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                             const TextureSampler&,
165096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                             const char* coordName,
166096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                             GrSLType coordType = kVec2f_GrSLType);
167096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
168096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        called. */
173096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void appendTextureLookupAndModulate(ShaderType,
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        const char* modulation,
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        const TextureSampler&,
176363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                        const char* coordName,
177096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                        GrSLType coordType = kVec2f_GrSLType);
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Emits a helper function outside of main(). Currently ShaderType must be
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kFragment_ShaderType. */
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void emitFunction(ShaderType shader,
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      GrSLType returnType,
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      const char* name,
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      int argCnt,
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      const GrGLShaderVar* args,
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      const char* body,
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      SkString* outName);
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
189363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Generates a EffectKey for the shader code based on the texture access parameters and the
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        capabilities of the GL context.  This is useful for keying the shader programs that may
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        have multiple representations, based on the type/format of textures used. */
192363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&,
193363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                                 const GrGLCaps&);
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef uint8_t DstReadKey;
1967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef uint8_t FragPosKey;
1977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**  Returns a key for adding code to read the copy-of-dst color in service of effects that
1997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger         require reading the dst. It must not return 0 because 0 indicates that there is no dst
2007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger         copy read at all (in which case this function should not be called). */
2017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
2027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /** Returns a key for reading the fragment location. This should only be called if there is an
2047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        effect that will requires the fragment position. If the fragment position is not required,
2057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        the key is 0. */
2067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
2077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** If texture swizzling is available using tex parameters then it is preferred over mangling
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        the generated shader code. This potentially allows greater reuse of cached shaders. */
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
212363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        visibility is a bitfield of ShaderType values indicating from which shaders the uniform
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        should be accessible. At least one bit must be set. Geometry shader uniforms are not
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        it will refer to the final uniform name after return. Use the addUniformArray variant to add
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        an array of uniforms.
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 GrSLType type,
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 const char* name,
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 const char** outName = NULL) {
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      GrSLType type,
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      const char* name,
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      int arrayCount,
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      const char** outName = NULL);
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle) const;
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
234363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     * Shortcut for getUniformVariable(u).c_str()
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return this->getUniformVariable(u).c_str();
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
240096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger   /** Add a vertex attribute to the current program that is passed in from the vertex data.
241096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger       Returns false if the attribute was already there, true otherwise. */
242096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    bool addAttribute(GrSLType type, const char* name);
243096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
244096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger   /** Add a varying variable to the current program to pass values between vertex and fragment
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        shaders. If the last two parameters are non-NULL, they are filled in with the name
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        generated. */
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void addVarying(GrSLType type,
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    const char* name,
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    const char** vsOutName = NULL,
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    const char** fsInName = NULL);
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
252363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Returns a variable name that represents the position of the fragment in the FS. The position
253363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
254363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    const char* fragmentPosition();
255363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
256363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
257363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
258363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger      */
259363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
260363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
261e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
262e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger        as positionAttribute() or it may not be. It depends upon whether the rendering code
263e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger        specified explicit local coords or not in the GrDrawState. */
264e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
265e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger
2667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /** Returns the color of the destination pixel. This may be NULL if no effect advertised
2677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        that it will read the destination. */
2687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* dstColor();
2697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
270e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    /**
271e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger     * Are explicit local coordinates provided as input to the vertex shader.
272e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger     */
273e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
274e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
276d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger     * Interfaces used by GrGLProgram.
277d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger     * TODO: Hide these from the GrEffects using friend or splitting this into two related classes.
278d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger     * Also, GrGLProgram's shader string construction should be moved to this class.
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
281d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    /** Called after building is complete to get the final shader string. */
282d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    void getShader(ShaderType, SkString*) const;
283d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
2847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
2857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * Adds code for effects. effectStages contains the effects to add. effectKeys[i] is the key
2867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * generated from effectStages[i]. An entry in effectStages can be NULL, in which case it is
2877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey then it is skipped.
2887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * inOutFSColor specifies the input color to the first stage and is updated to be the
2897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * output color of the last stage. fsInOutColorKnownValue specifies whether the input color
2907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * has a known constant value and is updated to refer to the status of the output color.
2917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * The handles to texture samplers for effectStage[i] are added to effectSamplerHandles[i]. The
2927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * glEffects array is updated to contain the GrGLEffect generated for each entry in
2937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * effectStages.
2947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
2957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void emitEffects(const GrEffectStage* effectStages[],
2967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                     const GrBackendEffectFactory::EffectKey effectKeys[],
2977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                     int effectCnt,
2987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                     SkString*  inOutFSColor,
2997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                     GrSLConstantVec* fsInOutColorKnownValue,
3007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                     SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
3017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                     GrGLEffect* glEffects[]);
3027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
303363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
3047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
3057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fDstCopyTopLeftUniform;
3067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
3087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fDstCopyScaleUniform;
3097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
3117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fDstCopySampler.fSamplerUniform;
3127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
313096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
314096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    struct AttributePair {
315096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        void set(int index, const SkString& name) {
316096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            fIndex = index; fName = name;
317096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        }
318096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        int      fIndex;
319096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        SkString fName;
320096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    };
3217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkTArray<AttributePair, true>& getEffectAttributes() const {
322096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return fEffectAttributes;
323096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
324096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const SkString* getEffectAttributeName(int attributeIndex) const;
325096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
326d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // TODO: Make this do all the compiling, linking, etc.
327d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    void finished(GrGLuint programID);
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
329096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const GrGLContextInfo& ctxInfo() const { return fCtxInfo; }
330096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
332096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void codeAppendf(ShaderType type, const char format[], va_list args);
333096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void codeAppend(ShaderType type, const char* str);
334096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef GrTAllocator<GrGLShaderVar> VarArray;
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void appendDecls(const VarArray&, SkString*) const;
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void appendUniformDecls(ShaderType, SkString*) const;
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef GrGLUniformManager::BuilderUniform BuilderUniform;
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLUniformManager::BuilderUniformArray fUniforms;
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // TODO: Everything below here private.
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fVSAttrs;
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fVSOutputs;
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fGSInputs;
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fGSOutputs;
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fFSInputs;
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString    fGSHeader; // layout qualifiers specific to GS
35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fFSOutputs;
35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
3557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    class CodeStage : GrNoncopyable {
3567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    public:
3577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
3587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        bool inStageCode() const {
3607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->validate();
3617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return NULL != fEffectStage;
3627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
3637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrEffectStage* effectStage() const {
3657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->validate();
3667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return fEffectStage;
3677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
3687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int stageIndex() const {
3707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            this->validate();
3717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return fCurrentIndex;
3727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
3737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        class AutoStageRestore : GrNoncopyable {
3757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        public:
3767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
3777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                GrAssert(NULL != codeStage);
3787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fSavedIndex = codeStage->fCurrentIndex;
3797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fSavedEffectStage = codeStage->fEffectStage;
3807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                if (NULL == newStage) {
3827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    codeStage->fCurrentIndex = -1;
3837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                } else {
3847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
3857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                }
3867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                codeStage->fEffectStage = newStage;
3877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fCodeStage = codeStage;
3897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
3907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            ~AutoStageRestore() {
3917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fCodeStage->fCurrentIndex = fSavedIndex;
3927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fCodeStage->fEffectStage = fSavedEffectStage;
3937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
3947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        private:
3957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            CodeStage*              fCodeStage;
3967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            int                     fSavedIndex;
3977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            const GrEffectStage*    fSavedEffectStage;
3987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        };
3997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    private:
4007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        void validate() const { GrAssert((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
4017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int                     fNextIndex;
4027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int                     fCurrentIndex;
4037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrEffectStage*    fEffectStage;
4047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } fCodeStage;
4057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
4077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     * Features that should only be enabled by GrGLShaderBuilder itself.
4087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
4097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    enum GLSLPrivateFeature {
4107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
4117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kEXTShaderFramebufferFetch_GLSLPrivateFeature,
4127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kNVShaderFramebufferFetch_GLSLPrivateFeature,
4137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
4147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool enablePrivateFeature(GLSLPrivateFeature);
4157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // If we ever have VS/GS features we can expand this to take a bitmask of ShaderType and track
4177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // the enables separately for each shader.
4187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void addFSFeature(uint32_t featureBit, const char* extensionName);
4197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Generates a name for a variable. The generated string will be name prefixed by the prefix
4217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
4227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // generating stage code.
4237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void nameVariable(SkString* out, char prefix, const char* name);
4247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Interpretation of DstReadKey when generating code
42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum {
4277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kNoDstRead_DstReadKey         = 0,
4287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kYesDstRead_DstReadKeyBit     = 0x1, // Set if we do a dst-copy-read.
4297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
4307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kTopLeftOrigin_DstReadKeyBit  = 0x4, // Set if dst-copy origin is top-left.
4317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
4327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    enum {
4347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
4357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
4367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
439096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const GrGLContextInfo&              fCtxInfo;
440363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLUniformManager&                 fUniformManager;
4417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint32_t                            fFSFeaturesAddedMask;
442363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkString                            fFSFunctions;
4437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkString                            fFSExtensions;
4447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool                                fUsesGS;
44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
447096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkString                            fFSCode;
448096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkString                            fVSCode;
449096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkString                            fGSCode;
450096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
451363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    bool                                fSetupFragPosition;
4527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    TextureSampler                      fDstCopySampler;
4537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
454363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLUniformManager::UniformHandle   fRTHeightUniform;
4557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle   fDstCopyTopLeftUniform;
4567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle   fDstCopyScaleUniform;
4577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool                                fTopLeftFragPosRead;
45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
460096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkSTArray<10, AttributePair, true>  fEffectAttributes;
461096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
462363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLShaderVar*                      fPositionVar;
463e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    GrGLShaderVar*                      fLocalCoordsVar;
464e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger
46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
468