GrGLShaderBuilder.h revision e3beb6bd7de7fa211681abbb0be58e80b19885e0
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"
15a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org#include "SkTypes.h"
163390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org#include "gl/GrGLProgramEffects.h"
17f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#include "gl/GrGLSL.h"
18dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#include "gl/GrGLUniformManager.h"
19f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
20f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com#include <stdarg.h>
21f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
22ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comclass GrGLContextInfo;
23c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.comclass GrEffectStage;
2426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.comclass GrGLProgramDesc;
25dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
26f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com/**
27eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com  Contains all the incremental state of a shader as it is being built,as well as helpers to
28eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com  manipulate that state.
29f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com*/
30f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.comclass GrGLShaderBuilder {
31f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.compublic:
325a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org    typedef GrTAllocator<GrGLShaderVar> VarArray;
3377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    typedef GrBackendEffectFactory::EffectKey EffectKey;
343390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org    typedef GrGLProgramEffects::TextureSampler TextureSampler;
353390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org    typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
36261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    typedef GrGLUniformManager::BuilderUniform BuilderUniform;
37f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com
3874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    enum ShaderVisibility {
3974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org        kVertex_Visibility   = 0x1,
4074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org        kGeometry_Visibility = 0x2,
4174a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org        kFragment_Visibility = 0x4,
42eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com    };
43eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com
44261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
45261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual ~GrGLShaderBuilder() {}
46f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
47f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    /**
4842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
4942eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * if code is added that uses one of these features without calling enableFeature()
5042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
5142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    enum GLSLFeature {
5242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com        kStandardDerivatives_GLSLFeature = 0,
5342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
5442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com        kLastGLSLFeature = kStandardDerivatives_GLSLFeature
5542eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    };
5642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
5742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
5842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * If the feature is supported then true is returned and any necessary #extension declarations
5942eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * are added to the shaders. If the feature is not supported then false will be returned.
6042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
6142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    bool enableFeature(GLSLFeature);
6242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
6342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
645a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org     * Called by GrGLEffects to add code the fragment shader.
65f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com     */
66f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
67f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_list args;
68f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_start(args, format);
69ce0e4efabd00b38aaaeb33457dcdb6c98e6eec12commit-bot@chromium.org        fFSCode.appendVAList(format, args);
70f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_end(args);
71f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    }
72f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
7374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsCodeAppend(const char* str) { fFSCode.append(str); }
74f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
75dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
76dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
77dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
78868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com    void appendTextureLookup(SkString* out,
79f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                             const TextureSampler&,
80dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com                             const char* coordName,
81868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com                             GrSLType coordType = kVec2f_GrSLType) const;
82868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com
8374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    /** Version of above that appends the result to the fragment shader code instead.*/
8474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsAppendTextureLookup(const TextureSampler&,
8574a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                               const char* coordName,
8674a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                               GrSLType coordType = kVec2f_GrSLType);
87f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
88f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
892d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
902d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
912d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
922d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        called. */
9374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsAppendTextureLookupAndModulate(const char* modulation,
9474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                                          const TextureSampler&,
9574a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                                          const char* coordName,
9674a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                                          GrSLType coordType = kVec2f_GrSLType);
9774a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org
9874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    /** Emits a helper function outside of main() in the fragment shader. */
9974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsEmitFunction(GrSLType returnType,
10074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        const char* name,
10174a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        int argCnt,
10274a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        const GrGLShaderVar* args,
10374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        const char* body,
10474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        SkString* outName);
105a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com
10626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    typedef uint8_t DstReadKey;
107b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    typedef uint8_t FragPosKey;
10826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
10926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    /**  Returns a key for adding code to read the copy-of-dst color in service of effects that
11026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com         require reading the dst. It must not return 0 because 0 indicates that there is no dst
111b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com         copy read at all (in which case this function should not be called). */
11226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
11326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
114b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    /** Returns a key for reading the fragment location. This should only be called if there is an
115b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        effect that will requires the fragment position. If the fragment position is not required,
116b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        the key is 0. */
117b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
118b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
1196d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com    /** If texture swizzling is available using tex parameters then it is preferred over mangling
1206d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com        the generated shader code. This potentially allows greater reuse of cached shaders. */
1216d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
1226d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com
123706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
12474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org        visibility is a bitfield of ShaderVisibility values indicating from which shaders the
12574a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org        uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
126777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
127777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        it will refer to the final uniform name after return. Use the addUniformArray variant to add
128777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        an array of uniforms.
129242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com    */
130dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
131dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com                                                 GrSLType type,
132dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com                                                 const char* name,
133777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                 const char** outName = NULL) {
134777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
135777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    }
136777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
137777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      GrSLType type,
138777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      const char* name,
139777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      int arrayCount,
140777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      const char** outName = NULL);
141032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
1427425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
1437425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        return fUniformManager.getBuilderUniform(fUniforms, u).fVariable;
1447425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    }
145032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
146032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    /**
147706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com     * Shortcut for getUniformVariable(u).c_str()
148032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com     */
149dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
150032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com        return this->getUniformVariable(u).c_str();
151032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    }
152eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com
15377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    /**
15477af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     * This returns a variable name to access the 2D, perspective correct version of the coords in
15577af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
15677af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     * perspective divide into the fragment shader (xy / z) to convert them to 2D.
15777af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     */
15877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    SkString ensureFSCoords2D(const TransformedCoordsArray&, int index);
15977af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com
160706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    /** Returns a variable name that represents the position of the fragment in the FS. The position
161706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
162706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    const char* fragmentPosition();
163706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com
16426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    /** Returns the color of the destination pixel. This may be NULL if no effect advertised
16526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        that it will read the destination. */
1666b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com    const char* dstColor();
16726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
168c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    /**
16934cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com     * Interfaces used by GrGLProgram.
170dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com     */
171a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    const GrGLSLExpr4& getInputColor() const {
172261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        return fInputColor;
173261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
174a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    const GrGLSLExpr4& getInputCoverage() const {
175261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        return fInputCoverage;
176261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
17734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com
178504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    /**
1793390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org     * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
1803390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org     * deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key
1813390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org     * generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and
182824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org     * is updated to be the output color of the last stage.
183824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org     * The handles to texture samplers for effectStage[i] are added to
1843390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org     * effectSamplerHandles[i].
185504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     */
186261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
187261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                                                     const EffectKey effectKeys[],
188261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                                                     int effectCnt,
189a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                                                     GrGLSLExpr4* inOutFSColor) = 0;
19026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
191410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org    const char* getColorOutputName() const;
192410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org    const char* enableSecondaryOutput();
193410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org
194706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
19526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
19626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return fDstCopyTopLeftUniform;
19726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
19826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
19926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return fDstCopyScaleUniform;
20026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
201410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org    GrGLUniformManager::UniformHandle getColorUniform() const { return fColorUniform; }
202410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org    GrGLUniformManager::UniformHandle getCoverageUniform() const { return fCoverageUniform; }
20326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
2043390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org        return fDstCopySamplerUniform;
20526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
206ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
207261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool finish(GrGLuint* outProgramId);
2085a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
209261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLContextInfo& ctxInfo() const;
2105a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
211907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    /**
212907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * Helper for begining and ending a block in the fragment code. TODO: Make GrGLShaderBuilder
213907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * aware of all blocks and turn single \t's into the correct number of tabs (or spaces) so that
214907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * our shaders print pretty without effect writers tracking indentation.
215907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     */
216907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    class FSBlock {
217907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    public:
218907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        FSBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
219907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkASSERT(NULL != builder);
220907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            fBuilder->fsCodeAppend("\t{\n");
221907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
222907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
223907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        ~FSBlock() {
224907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            fBuilder->fsCodeAppend("\t}\n");
225907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
226907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    private:
227907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        GrGLShaderBuilder* fBuilder;
228907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    };
229907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
230261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgprotected:
231261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGpuGL* gpu() const { return fGpu; }
2325a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
233a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    void setInputColor(const GrGLSLExpr4& inputColor) { fInputColor = inputColor; }
234a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    void setInputCoverage(const GrGLSLExpr4& inputCoverage) { fInputCoverage = inputCoverage; }
235410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org
236261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
237261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
2385a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
239261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    // Generates a name for a variable. The generated string will be name prefixed by the prefix
240261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
241261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    // generating stage code.
242261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void nameVariable(SkString* out, char prefix, const char* name);
243ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
244261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    // Helper for emitEffects().
245261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void createAndEmitEffects(GrGLProgramEffectsBuilder*,
246261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                              const GrEffectStage* effectStages[],
247261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                              const EffectKey effectKeys[],
248261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                              int effectCnt,
249a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                              GrGLSLExpr4* inOutFSColor);
250706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com
251d328fb62938b1d7e43b07c619756dfdc781453b3commit-bot@chromium.org    virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
252261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual void bindProgramLocations(GrGLuint programId) const;
25313f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com
254032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    void appendDecls(const VarArray&, SkString*) const;
25574a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void appendUniformDecls(ShaderVisibility, SkString*) const;
256032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
257ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comprivate:
258e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.org    class CodeStage : SkNoncopyable {
259504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    public:
260a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
261504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
262504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        bool inStageCode() const {
263504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            this->validate();
264a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            return NULL != fEffectStage;
265504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
266504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
267a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        const GrEffectStage* effectStage() const {
268504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            this->validate();
269a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            return fEffectStage;
270504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
271504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
272504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        int stageIndex() const {
2730f20a3fc59dee846ca137dd7a263e655550e6cbfskia.committer@gmail.com            this->validate();
274504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            return fCurrentIndex;
275504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
276504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
277e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.org        class AutoStageRestore : SkNoncopyable {
278504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        public:
279a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
280f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org                SkASSERT(NULL != codeStage);
281504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fSavedIndex = codeStage->fCurrentIndex;
282a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                fSavedEffectStage = codeStage->fEffectStage;
283504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
284a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                if (NULL == newStage) {
285504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                    codeStage->fCurrentIndex = -1;
286504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                } else {
287504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
288504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                }
289a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                codeStage->fEffectStage = newStage;
290504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
291504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fCodeStage = codeStage;
292504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            }
293504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            ~AutoStageRestore() {
294504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fCodeStage->fCurrentIndex = fSavedIndex;
295a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                fCodeStage->fEffectStage = fSavedEffectStage;
296504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            }
297504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        private:
298a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            CodeStage*              fCodeStage;
299a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            int                     fSavedIndex;
300a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            const GrEffectStage*    fSavedEffectStage;
301504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        };
302504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    private:
303a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
304a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        int                     fNextIndex;
305a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        int                     fCurrentIndex;
306a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        const GrEffectStage*    fEffectStage;
307504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    } fCodeStage;
308777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com
30942eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
31042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * Features that should only be enabled by GrGLShaderBuilder itself.
31142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
31242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    enum GLSLPrivateFeature {
3136b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
3146b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kEXTShaderFramebufferFetch_GLSLPrivateFeature,
3156b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kNVShaderFramebufferFetch_GLSLPrivateFeature,
31642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    };
31742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    bool enablePrivateFeature(GLSLPrivateFeature);
31842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
31974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
32074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    // track the enables separately for each shader.
32142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    void addFSFeature(uint32_t featureBit, const char* extensionName);
32242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
32326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // Interpretation of DstReadKey when generating code
32426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    enum {
32526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kNoDstRead_DstReadKey         = 0,
32626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kYesDstRead_DstReadKeyBit     = 0x1, // Set if we do a dst-copy-read.
32726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
32826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kTopLeftOrigin_DstReadKeyBit  = 0x4, // Set if dst-copy origin is top-left.
32926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    };
33026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
331b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    enum {
332b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
333b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
334b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
335b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    };
336b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
337261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGpuGL*                                fGpu;
338261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager&                     fUniformManager;
339261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    uint32_t                                fFSFeaturesAddedMask;
340261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                                fFSFunctions;
341261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                                fFSExtensions;
342261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                                fFSInputs;
343261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                                fFSOutputs;
344261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::BuilderUniformArray fUniforms;
345261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
346261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                                fFSCode;
347261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
348261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fSetupFragPosition;
349261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fDstCopySamplerUniform;
350261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
351a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    GrGLSLExpr4                             fInputColor;
352a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    GrGLSLExpr4                             fInputCoverage;
353261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
354261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fHasCustomColorOutput;
355261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fHasSecondaryOutput;
356261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
357261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fRTHeightUniform;
358261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fDstCopyTopLeftUniform;
359261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fDstCopyScaleUniform;
360261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fColorUniform;
361261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fCoverageUniform;
362261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
363261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fTopLeftFragPosRead;
364261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org};
365261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
366261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////////
367261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
368261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgclass GrGLFullShaderBuilder : public GrGLShaderBuilder {
369261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgpublic:
370261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLFullShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
371261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
372261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /**
373261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     * Called by GrGLEffects to add code to one of the shaders.
374261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     */
375261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
376261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        va_list args;
377261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        va_start(args, format);
378ce0e4efabd00b38aaaeb33457dcdb6c98e6eec12commit-bot@chromium.org        fVSCode.appendVAList(format, args);
379261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        va_end(args);
380261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
381261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
382261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void vsCodeAppend(const char* str) { fVSCode.append(str); }
38326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
384261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org   /** Add a vertex attribute to the current program that is passed in from the vertex data.
385261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org       Returns false if the attribute was already there, true otherwise. */
386261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool addAttribute(GrSLType type, const char* name);
387f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
388261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org   /** Add a varying variable to the current program to pass values between vertex and fragment
389261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        shaders. If the last two parameters are non-NULL, they are filled in with the name
390261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        generated. */
391261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void addVarying(GrSLType type,
392261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                    const char* name,
393261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                    const char** vsOutName = NULL,
394261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                    const char** fsInName = NULL);
395261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
396261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
397261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
398261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org      */
399261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
400261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
401261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
402261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        as positionAttribute() or it may not be. It depends upon whether the rendering code
403261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        specified explicit local coords or not in the GrDrawState. */
404261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
405261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
406261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /**
407261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     * Are explicit local coordinates provided as input to the vertex shader.
408261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     */
409261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
41026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
411261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
412261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const SkString* getEffectAttributeName(int attributeIndex) const;
413410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org
414261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual GrGLProgramEffects* createAndEmitEffects(
415261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                const GrEffectStage* effectStages[],
416261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                const EffectKey effectKeys[],
417261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                int effectCnt,
418a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
419261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
420261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle getViewMatrixUniform() const {
421261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        return fViewMatrixUniform;
422261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
423261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
424261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgprotected:
425d328fb62938b1d7e43b07c619756dfdc781453b3commit-bot@chromium.org    virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE;
426261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE;
427261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
428261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgprivate:
429261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLProgramDesc&              fDesc;
430261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                            fVSAttrs;
431261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                            fVSOutputs;
432261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                            fGSInputs;
433261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                            fGSOutputs;
434261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
435261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                            fVSCode;
436261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
437261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    struct AttributePair {
438261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        void set(int index, const SkString& name) {
439261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            fIndex = index; fName = name;
440261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        }
441261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        int      fIndex;
442261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        SkString fName;
443261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    };
444261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkSTArray<10, AttributePair, true>  fEffectAttributes;
445410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org
446261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle   fViewMatrixUniform;
44734bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com
448261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLShaderVar*                      fPositionVar;
449261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLShaderVar*                      fLocalCoordsVar;
450b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
451261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    typedef GrGLShaderBuilder INHERITED;
452f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com};
453f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
4546b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////////
4556b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
4566b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.orgclass GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder {
4576b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.orgpublic:
4586b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    GrGLFragmentOnlyShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
4596b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
4606b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    int getNumTexCoordSets() const { return fNumTexCoordSets; }
4618e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org    int addTexCoordSets(int count);
4626b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
4636b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    virtual GrGLProgramEffects* createAndEmitEffects(
4646b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org                const GrEffectStage* effectStages[],
4656b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org                const EffectKey effectKeys[],
4666b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org                int effectCnt,
467a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
4686b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
4696b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.orgprivate:
4706b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    int fNumTexCoordSets;
4716b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
4726b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    typedef GrGLShaderBuilder INHERITED;
4736b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org};
4746b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
475f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#endif
476