GrGLShaderBuilder.h revision e2022cc36e47b9f0d219eb5cd24be61772c28d3b
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"
13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrEffect.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLSL.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLUniformManager.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <stdarg.h>
18096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrGLContextInfo;
20e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenbergerclass GrEffectStage;
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  Contains all the incremental state of a shader as it is being built,as well as helpers to
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  manipulate that state.
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrGLShaderBuilder {
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
29d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger     * Passed to GrGLEffects to add texture reads to their shader code.
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    class TextureSampler {
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    public:
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        TextureSampler()
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            : fTextureAccess(NULL)
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            , fSamplerUniform(GrGLUniformManager::kInvalidUniformHandle) {}
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        TextureSampler(const TextureSampler& other) { *this = other; }
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        TextureSampler& operator= (const TextureSampler& other) {
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(NULL == fTextureAccess);
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fTextureAccess = other.fTextureAccess;
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fSamplerUniform = other.fSamplerUniform;
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return *this;
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const GrTextureAccess* textureAccess() const { return fTextureAccess; }
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    private:
51d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        // The idx param is used to ensure multiple samplers within a single effect have unique
52d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        // uniform names.
53d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int idx) {
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(NULL == fTextureAccess);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(NULL != builder);
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(NULL != access);
59d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            SkString name;
60d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            name.printf("Sampler%d_", idx);
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                  kSampler2D_GrSLType,
63d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                                  name.c_str());
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(GrGLUniformManager::kInvalidUniformHandle != fSamplerUniform);
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fTextureAccess = access;
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const GrTextureAccess*            fTextureAccess;
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrGLUniformManager::UniformHandle fSamplerUniform;
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        friend class GrGLShaderBuilder; // to access fSamplerUniform
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        friend class GrGLProgram;       // to construct these and access fSamplerUniform.
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef SkTArray<TextureSampler> TextureSamplerArray;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum ShaderType {
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kVertex_ShaderType   = 0x1,
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kGeometry_ShaderType = 0x2,
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kFragment_ShaderType = 0x4,
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
84e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, bool explicitLocalCoords);
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
86096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    /**
87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger     * Called by GrGLEffects to add code to one of the shaders.
88096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger     */
89096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
90096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_list args;
91096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_start(args, format);
92096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        this->codeAppendf(kVertex_ShaderType, format, args);
93096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_end(args);
94096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
95096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
96096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
97096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_list args;
98096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_start(args, format);
99096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        this->codeAppendf(kGeometry_ShaderType, format, args);
100096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_end(args);
101096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
102096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
103096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
104096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_list args;
105096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_start(args, format);
106096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        this->codeAppendf(kFragment_ShaderType, format, args);
107096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        va_end(args);
108096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
109096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
110096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void vsCodeAppend(const char* str) { this->codeAppend(kVertex_ShaderType, str); }
111096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void gsCodeAppend(const char* str) { this->codeAppend(kGeometry_ShaderType, str); }
112096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void fsCodeAppend(const char* str) { this->codeAppend(kFragment_ShaderType, str); }
113096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
114363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
115363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
116363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void appendTextureLookup(SkString* out,
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             const TextureSampler&,
119363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                             const char* coordName,
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             GrSLType coordType = kVec2f_GrSLType) const;
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
122096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    /** Version of above that appends the result to the shader code rather than an SkString.
123096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        Currently the shader type must be kFragment */
124096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void appendTextureLookup(ShaderType,
125096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                             const TextureSampler&,
126096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                             const char* coordName,
127096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                             GrSLType coordType = kVec2f_GrSLType);
128096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
129096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        called. */
134096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void appendTextureLookupAndModulate(ShaderType,
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        const char* modulation,
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        const TextureSampler&,
137363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                        const char* coordName,
138096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                        GrSLType coordType = kVec2f_GrSLType);
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Emits a helper function outside of main(). Currently ShaderType must be
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kFragment_ShaderType. */
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void emitFunction(ShaderType shader,
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      GrSLType returnType,
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      const char* name,
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      int argCnt,
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      const GrGLShaderVar* args,
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      const char* body,
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      SkString* outName);
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
150363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Generates a EffectKey for the shader code based on the texture access parameters and the
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        capabilities of the GL context.  This is useful for keying the shader programs that may
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        have multiple representations, based on the type/format of textures used. */
153363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&,
154363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                                 const GrGLCaps&);
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** If texture swizzling is available using tex parameters then it is preferred over mangling
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        the generated shader code. This potentially allows greater reuse of cached shaders. */
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
160363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        visibility is a bitfield of ShaderType values indicating from which shaders the uniform
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        should be accessible. At least one bit must be set. Geometry shader uniforms are not
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        it will refer to the final uniform name after return. Use the addUniformArray variant to add
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        an array of uniforms.
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 GrSLType type,
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 const char* name,
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 const char** outName = NULL) {
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      GrSLType type,
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      const char* name,
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      int arrayCount,
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      const char** outName = NULL);
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle) const;
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
182363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     * Shortcut for getUniformVariable(u).c_str()
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return this->getUniformVariable(u).c_str();
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
188096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger   /** Add a vertex attribute to the current program that is passed in from the vertex data.
189096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger       Returns false if the attribute was already there, true otherwise. */
190096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    bool addAttribute(GrSLType type, const char* name);
191096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
192096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger   /** Add a varying variable to the current program to pass values between vertex and fragment
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        shaders. If the last two parameters are non-NULL, they are filled in with the name
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        generated. */
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void addVarying(GrSLType type,
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    const char* name,
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    const char** vsOutName = NULL,
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    const char** fsInName = NULL);
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
200363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Returns a variable name that represents the position of the fragment in the FS. The position
201363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
202363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    const char* fragmentPosition();
203363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
204363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
205363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
206363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger      */
207363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
208363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
209e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
210e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger        as positionAttribute() or it may not be. It depends upon whether the rendering code
211e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger        specified explicit local coords or not in the GrDrawState. */
212e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
213e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger
214e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    /**
215e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger     * Are explicit local coordinates provided as input to the vertex shader.
216e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger     */
217e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
218e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
220d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger     * Interfaces used by GrGLProgram.
221d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger     * TODO: Hide these from the GrEffects using friend or splitting this into two related classes.
222d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger     * Also, GrGLProgram's shader string construction should be moved to this class.
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
225d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    /** Called after building is complete to get the final shader string. */
226d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    void getShader(ShaderType, SkString*) const;
227d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
228363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    void setCurrentStage(int stageIdx) { fCurrentStageIdx = stageIdx; }
229363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    void setNonStage() { fCurrentStageIdx = kNonStageIdx; }
230d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // TODO: move remainder of shader code generation to this class and call this privately
231d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Handles of sampler uniforms generated for the effect are appended to samplerHandles.
232d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    GrGLEffect* createAndEmitGLEffect(
233d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                const GrEffectStage& stage,
234d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                GrBackendEffectFactory::EffectKey key,
235d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                const char* fsInColor, // NULL means no incoming color
236d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                const char* fsOutColor,
237d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles);
238363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
239096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
240096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    struct AttributePair {
241096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        void set(int index, const SkString& name) {
242096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            fIndex = index; fName = name;
243096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        }
244096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        int      fIndex;
245096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        SkString fName;
246096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    };
247096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const SkSTArray<10, AttributePair, true>& getEffectAttributes() const {
248096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return fEffectAttributes;
249096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
250096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const SkString* getEffectAttributeName(int attributeIndex) const;
251096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
252d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // TODO: Make this do all the compiling, linking, etc.
253d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    void finished(GrGLuint programID);
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
255096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const GrGLContextInfo& ctxInfo() const { return fCtxInfo; }
256096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
258096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void codeAppendf(ShaderType type, const char format[], va_list args);
259096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    void codeAppend(ShaderType type, const char* str);
260096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef GrTAllocator<GrGLShaderVar> VarArray;
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void appendDecls(const VarArray&, SkString*) const;
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void appendUniformDecls(ShaderType, SkString*) const;
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef GrGLUniformManager::BuilderUniform BuilderUniform;
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLUniformManager::BuilderUniformArray fUniforms;
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // TODO: Everything below here private.
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString    fHeader; // VS+FS, GLSL version, etc
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fVSAttrs;
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fVSOutputs;
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fGSInputs;
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fGSOutputs;
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fFSInputs;
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString    fGSHeader; // layout qualifiers specific to GS
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    VarArray    fFSOutputs;
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool        fUsesGS;
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum {
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kNonStageIdx = -1,
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
287096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const GrGLContextInfo&              fCtxInfo;
288363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLUniformManager&                 fUniformManager;
289363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    int                                 fCurrentStageIdx;
290363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkString                            fFSFunctions;
291363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkString                            fFSHeader;
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
293096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkString                            fFSCode;
294096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkString                            fVSCode;
295096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkString                            fGSCode;
296096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
297363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    bool                                fSetupFragPosition;
298363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLUniformManager::UniformHandle   fRTHeightUniform;
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
300096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkSTArray<10, AttributePair, true>  fEffectAttributes;
301096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
302363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLShaderVar*                      fPositionVar;
303e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    GrGLShaderVar*                      fLocalCoordsVar;
304e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
308