GrGLShaderBuilder.h revision b515881446c303a50d9b2dd38b9163b4e5c625a2
1f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com/*
2f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * Copyright 2012 Google Inc.
3f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com *
4f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be
5f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * found in the LICENSE file.
6f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com */
7f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
8f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#ifndef GrGLShaderBuilder_DEFINED
9f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#define GrGLShaderBuilder_DEFINED
10f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
11f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#include "GrAllocator.h"
122eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com#include "GrBackendEffectFactory.h"
13b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com#include "GrColor.h"
14a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com#include "GrEffect.h"
15f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#include "gl/GrGLSL.h"
16dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#include "gl/GrGLUniformManager.h"
17f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
18f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com#include <stdarg.h>
19f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
20ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comclass GrGLContextInfo;
21c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.comclass GrEffectStage;
2226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.comclass GrGLProgramDesc;
23dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
24f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com/**
25eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com  Contains all the incremental state of a shader as it is being built,as well as helpers to
26eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com  manipulate that state.
27f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com*/
28f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.comclass GrGLShaderBuilder {
29f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.compublic:
30f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com    /**
3134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com     * Passed to GrGLEffects to add texture reads to their shader code.
32f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com     */
33f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com    class TextureSampler {
34f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com    public:
35f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com        TextureSampler()
36b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            : fConfigComponentMask(0)
37b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            , fSamplerUniform(GrGLUniformManager::kInvalidUniformHandle) {
38b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            // we will memcpy the first 4 bytes from passed in swizzle. This ensures the string is
39b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            // terminated.
40b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            fSwizzle[4] = '\0';
41b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        }
42f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
43f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com        TextureSampler(const TextureSampler& other) { *this = other; }
44f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
45f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com        TextureSampler& operator= (const TextureSampler& other) {
46b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            GrAssert(0 == fConfigComponentMask);
47f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com            GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
48f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
49b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            fConfigComponentMask = other.fConfigComponentMask;
50f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com            fSamplerUniform = other.fSamplerUniform;
51f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com            return *this;
52f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com        }
53f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
54b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        // bitfield of GrColorComponentFlags present in the texture's config.
55b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        uint32_t configComponentMask() const { return fConfigComponentMask; }
56b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com
57b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        const char* swizzle() const { return fSwizzle; }
58f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
5926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        bool isInitialized() const { return 0 != fConfigComponentMask; }
6026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
61f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com    private:
6234cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com        // The idx param is used to ensure multiple samplers within a single effect have unique
63b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        // uniform names. swizzle is a four char max string made up of chars 'r', 'g', 'b', and 'a'.
64b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        void init(GrGLShaderBuilder* builder,
65b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com                  uint32_t configComponentMask,
66b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com                  const char* swizzle,
67b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com                  int idx) {
6826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com            GrAssert(!this->isInitialized());
6926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com            GrAssert(0 != configComponentMask);
70f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com            GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
71f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
72f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com            GrAssert(NULL != builder);
7334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com            SkString name;
74504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            name.printf("Sampler%d", idx);
75f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com            fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
76f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                                                  kSampler2D_GrSLType,
7734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com                                                  name.c_str());
78f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com            GrAssert(GrGLUniformManager::kInvalidUniformHandle != fSamplerUniform);
79f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
80b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            fConfigComponentMask = configComponentMask;
81b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            memcpy(fSwizzle, swizzle, 4);
82b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        }
83b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com
84b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int idx) {
85b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            GrAssert(NULL != access);
86b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com            this->init(builder,
87b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com                       GrPixelConfigComponentMask(access->getTexture()->config()),
88b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com                       access->getSwizzle(),
89b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com                       idx);
90f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com        }
91f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
92b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        uint32_t                          fConfigComponentMask;
93b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        char                              fSwizzle[5];
94f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com        GrGLUniformManager::UniformHandle fSamplerUniform;
95f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
96b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com        friend class GrGLShaderBuilder; // to call init().
97f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com    };
98f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
99f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com    typedef SkTArray<TextureSampler> TextureSamplerArray;
100f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
101eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com    enum ShaderType {
102eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com        kVertex_ShaderType   = 0x1,
103eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com        kGeometry_ShaderType = 0x2,
104eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com        kFragment_ShaderType = 0x4,
105eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com    };
106eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com
10726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, const GrGLProgramDesc&);
108f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
109f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    /**
11042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
11142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * if code is added that uses one of these features without calling enableFeature()
11242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
11342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    enum GLSLFeature {
11442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com        kStandardDerivatives_GLSLFeature = 0,
11542eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
11642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com        kLastGLSLFeature = kStandardDerivatives_GLSLFeature
11742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    };
11842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
11942eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
12042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * If the feature is supported then true is returned and any necessary #extension declarations
12142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * are added to the shaders. If the feature is not supported then false will be returned.
12242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
12342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    bool enableFeature(GLSLFeature);
12442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
12542eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
126f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com     * Called by GrGLEffects to add code to one of the shaders.
127f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com     */
128f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
129f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_list args;
130f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_start(args, format);
131f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        this->codeAppendf(kVertex_ShaderType, format, args);
132f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_end(args);
133f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    }
134f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
135f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
136f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_list args;
137f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_start(args, format);
138f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        this->codeAppendf(kGeometry_ShaderType, format, args);
139f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_end(args);
140f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    }
141f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
142f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
143f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_list args;
144f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_start(args, format);
145f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        this->codeAppendf(kFragment_ShaderType, format, args);
146f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_end(args);
147f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    }
148f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
149f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void vsCodeAppend(const char* str) { this->codeAppend(kVertex_ShaderType, str); }
150f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void gsCodeAppend(const char* str) { this->codeAppend(kGeometry_ShaderType, str); }
151f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void fsCodeAppend(const char* str) { this->codeAppend(kFragment_ShaderType, str); }
152f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
153dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
154dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
155dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
156868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com    void appendTextureLookup(SkString* out,
157f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                             const TextureSampler&,
158dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com                             const char* coordName,
159868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com                             GrSLType coordType = kVec2f_GrSLType) const;
160868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com
161f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    /** Version of above that appends the result to the shader code rather than an SkString.
162f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        Currently the shader type must be kFragment */
163f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void appendTextureLookup(ShaderType,
164f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com                             const TextureSampler&,
165f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com                             const char* coordName,
166f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com                             GrSLType coordType = kVec2f_GrSLType);
167f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
168f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
1692d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
1702d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
1712d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
1722d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        called. */
173f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void appendTextureLookupAndModulate(ShaderType,
174868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com                                        const char* modulation,
175f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                                        const TextureSampler&,
176dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com                                        const char* coordName,
177f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com                                        GrSLType coordType = kVec2f_GrSLType);
17834bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com
179a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com    /** Emits a helper function outside of main(). Currently ShaderType must be
180a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com        kFragment_ShaderType. */
181a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com    void emitFunction(ShaderType shader,
182a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com                      GrSLType returnType,
183a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com                      const char* name,
184a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com                      int argCnt,
185a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com                      const GrGLShaderVar* args,
186a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com                      const char* body,
187a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com                      SkString* outName);
188a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com
18946fba0d79335f17429bb71d87a04d93fb2ee992bbsalomon@google.com    /** Generates a EffectKey for the shader code based on the texture access parameters and the
190a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com        capabilities of the GL context.  This is useful for keying the shader programs that may
191a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com        have multiple representations, based on the type/format of textures used. */
1922eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com    static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&,
1932eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com                                                                 const GrGLCaps&);
194a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com
19526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    typedef uint8_t DstReadKey;
196b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    typedef uint8_t FragPosKey;
19726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
19826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    /**  Returns a key for adding code to read the copy-of-dst color in service of effects that
19926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com         require reading the dst. It must not return 0 because 0 indicates that there is no dst
200b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com         copy read at all (in which case this function should not be called). */
20126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
20226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
203b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    /** Returns a key for reading the fragment location. This should only be called if there is an
204b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        effect that will requires the fragment position. If the fragment position is not required,
205b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        the key is 0. */
206b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
207b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
2086d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com    /** If texture swizzling is available using tex parameters then it is preferred over mangling
2096d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com        the generated shader code. This potentially allows greater reuse of cached shaders. */
2106d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
2116d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com
212706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
213777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        visibility is a bitfield of ShaderType values indicating from which shaders the uniform
214777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        should be accessible. At least one bit must be set. Geometry shader uniforms are not
215777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
216777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        it will refer to the final uniform name after return. Use the addUniformArray variant to add
217777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        an array of uniforms.
218242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com    */
219dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
220dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com                                                 GrSLType type,
221dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com                                                 const char* name,
222777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                 const char** outName = NULL) {
223777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
224777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    }
225777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
226777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      GrSLType type,
227777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      const char* name,
228777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      int arrayCount,
229777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      const char** outName = NULL);
230032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
231dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle) const;
232032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
233032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    /**
234706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com     * Shortcut for getUniformVariable(u).c_str()
235032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com     */
236dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
237032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com        return this->getUniformVariable(u).c_str();
238032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    }
239eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com
240ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org   /** Add a vertex attribute to the current program that is passed in from the vertex data.
241ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org       Returns false if the attribute was already there, true otherwise. */
242ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    bool addAttribute(GrSLType type, const char* name);
243ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
244ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org   /** Add a varying variable to the current program to pass values between vertex and fragment
245eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com        shaders. If the last two parameters are non-NULL, they are filled in with the name
246eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com        generated. */
24723cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com    void addVarying(GrSLType type,
24823cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com                    const char* name,
24923cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com                    const char** vsOutName = NULL,
25023cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com                    const char** fsInName = NULL);
25123cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com
252706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    /** Returns a variable name that represents the position of the fragment in the FS. The position
253706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
254706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    const char* fragmentPosition();
255706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com
25617504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
25717504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
25817504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com      */
25917504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
26017504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com
261c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
262c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        as positionAttribute() or it may not be. It depends upon whether the rendering code
263c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        specified explicit local coords or not in the GrDrawState. */
264c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
265c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
26626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    /** Returns the color of the destination pixel. This may be NULL if no effect advertised
26726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        that it will read the destination. */
2686b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com    const char* dstColor();
26926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
270c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    /**
271c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * Are explicit local coordinates provided as input to the vertex shader.
272c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     */
273c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
274c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
275dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    /**
27634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com     * Interfaces used by GrGLProgram.
27734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com     * TODO: Hide these from the GrEffects using friend or splitting this into two related classes.
27834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com     * Also, GrGLProgram's shader string construction should be moved to this class.
279dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com     */
280dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
28134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com    /** Called after building is complete to get the final shader string. */
28234cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com    void getShader(ShaderType, SkString*) const;
28334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com
284504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    /**
285504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     * Adds code for effects. effectStages contains the effects to add. effectKeys[i] is the key
286504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     * generated from effectStages[i]. An entry in effectStages can be NULL, in which case it is
287504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey then it is skipped.
288504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     * inOutFSColor specifies the input color to the first stage and is updated to be the
289504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     * output color of the last stage. fsInOutColorKnownValue specifies whether the input color
290504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     * has a known constant value and is updated to refer to the status of the output color.
291504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     * The handles to texture samplers for effectStage[i] are added to effectSamplerHandles[i]. The
292504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     * glEffects array is updated to contain the GrGLEffect generated for each entry in
293504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     * effectStages.
294504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     */
295504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    void emitEffects(const GrEffectStage* effectStages[],
296504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                     const GrBackendEffectFactory::EffectKey effectKeys[],
297504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                     int effectCnt,
298504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                     SkString*  inOutFSColor,
299504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                     GrSLConstantVec* fsInOutColorKnownValue,
300504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                     SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
301504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                     GrGLEffect* glEffects[]);
30226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
303706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
30426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
30526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return fDstCopyTopLeftUniform;
30626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
30726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
30826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return fDstCopyScaleUniform;
30926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
31026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
31126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return fDstCopySampler.fSamplerUniform;
31226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
313ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
314ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    struct AttributePair {
315ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        void set(int index, const SkString& name) {
316ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org            fIndex = index; fName = name;
317ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        }
318ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        int      fIndex;
319ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        SkString fName;
320ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    };
32126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    const SkTArray<AttributePair, true>& getEffectAttributes() const {
322ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        return fEffectAttributes;
323ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    }
324ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    const SkString* getEffectAttributeName(int attributeIndex) const;
325ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
32634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com    // TODO: Make this do all the compiling, linking, etc.
32734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com    void finished(GrGLuint programID);
328706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com
32913f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com    const GrGLContextInfo& ctxInfo() const { return fCtxInfo; }
33013f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com
331032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.comprivate:
332f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void codeAppendf(ShaderType type, const char format[], va_list args);
333f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void codeAppend(ShaderType type, const char* str);
334f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
335dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    typedef GrTAllocator<GrGLShaderVar> VarArray;
336032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
337032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    void appendDecls(const VarArray&, SkString*) const;
338032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    void appendUniformDecls(ShaderType, SkString*) const;
339032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
340dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    typedef GrGLUniformManager::BuilderUniform BuilderUniform;
341dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    GrGLUniformManager::BuilderUniformArray fUniforms;
342032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
343eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com    // TODO: Everything below here private.
344032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.compublic:
345eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com
346f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com    VarArray    fVSAttrs;
347f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com    VarArray    fVSOutputs;
348f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com    VarArray    fGSInputs;
349f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com    VarArray    fGSOutputs;
350f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com    VarArray    fFSInputs;
351f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com    SkString    fGSHeader; // layout qualifiers specific to GS
352f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com    VarArray    fFSOutputs;
353040c41a97c58b069015be3f5062eeb6ffe5adbfdtomhudson@google.com
354ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comprivate:
355504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    class CodeStage : GrNoncopyable {
356504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    public:
357504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
358504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
359504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        bool inStageCode() const {
360504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            this->validate();
361504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            return NULL != fEffectStage;
362504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
363504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
364504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        const GrEffectStage* effectStage() const {
365504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            this->validate();
366504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            return fEffectStage;
367504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
368504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
369504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        int stageIndex() const {
3700f20a3fc59dee846ca137dd7a263e655550e6cbfskia.committer@gmail.com            this->validate();
371504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            return fCurrentIndex;
372504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
373504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
374504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        class AutoStageRestore : GrNoncopyable {
375504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        public:
376504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
377504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                GrAssert(NULL != codeStage);
378504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fSavedIndex = codeStage->fCurrentIndex;
379504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fSavedEffectStage = codeStage->fEffectStage;
380504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
381504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                if (NULL == newStage) {
382504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                    codeStage->fCurrentIndex = -1;
383504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                } else {
384504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
385504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                }
386504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                codeStage->fEffectStage = newStage;
387504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
388504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fCodeStage = codeStage;
389504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            }
390504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            ~AutoStageRestore() {
391504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fCodeStage->fCurrentIndex = fSavedIndex;
392504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fCodeStage->fEffectStage = fSavedEffectStage;
393504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            }
394504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        private:
395504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            CodeStage*              fCodeStage;
396504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            int                     fSavedIndex;
397504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            const GrEffectStage*    fSavedEffectStage;
398504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        };
399504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    private:
400504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        void validate() const { GrAssert((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
401504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        int                     fNextIndex;
402504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        int                     fCurrentIndex;
403504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        const GrEffectStage*    fEffectStage;
404504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    } fCodeStage;
405777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com
40642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
40742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * Features that should only be enabled by GrGLShaderBuilder itself.
40842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
40942eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    enum GLSLPrivateFeature {
4106b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
4116b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kEXTShaderFramebufferFetch_GLSLPrivateFeature,
4126b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kNVShaderFramebufferFetch_GLSLPrivateFeature,
41342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    };
41442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    bool enablePrivateFeature(GLSLPrivateFeature);
41542eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
41642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    // If we ever have VS/GS features we can expand this to take a bitmask of ShaderType and track
41742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    // the enables separately for each shader.
41842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    void addFSFeature(uint32_t featureBit, const char* extensionName);
41942eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
420504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    // Generates a name for a variable. The generated string will be name prefixed by the prefix
421504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
422504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    // generating stage code.
423504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    void nameVariable(SkString* out, char prefix, const char* name);
424504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
42526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // Interpretation of DstReadKey when generating code
42626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    enum {
42726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kNoDstRead_DstReadKey         = 0,
42826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kYesDstRead_DstReadKeyBit     = 0x1, // Set if we do a dst-copy-read.
42926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
43026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kTopLeftOrigin_DstReadKeyBit  = 0x4, // Set if dst-copy origin is top-left.
43126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    };
43226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
433b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    enum {
434b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
435b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
436b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
437b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    };
438b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
4396177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com    const GrGLContextInfo&              fCtxInfo;
440706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    GrGLUniformManager&                 fUniformManager;
44142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    uint32_t                            fFSFeaturesAddedMask;
442706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    SkString                            fFSFunctions;
44342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    SkString                            fFSExtensions;
444706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com
44526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    bool                                fUsesGS;
44626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
447f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    SkString                            fFSCode;
448f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    SkString                            fVSCode;
449f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    SkString                            fGSCode;
450f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
451706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    bool                                fSetupFragPosition;
45226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    TextureSampler                      fDstCopySampler;
45326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
454706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    GrGLUniformManager::UniformHandle   fRTHeightUniform;
45526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle   fDstCopyTopLeftUniform;
45626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle   fDstCopyScaleUniform;
45734bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com
458b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    bool                                fTopLeftFragPosRead;
459b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
460ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    SkSTArray<10, AttributePair, true>  fEffectAttributes;
461ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
46217504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com    GrGLShaderVar*                      fPositionVar;
463c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    GrGLShaderVar*                      fLocalCoordsVar;
464c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
465f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com};
466f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
467f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#endif
468