GrGLShaderBuilder.h revision 0365261597f73c049f2d8c117c8c87ef2fb2c9ab
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
440365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    typedef GrGLUniformManager::UniformHandle UniformHandle;
450365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
460365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    // Handles for program uniforms (other than per-effect uniforms)
470365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    struct UniformHandles {
480365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        UniformHandle       fViewMatrixUni;
490365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        UniformHandle       fRTAdjustmentUni;
500365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        UniformHandle       fColorUni;
510365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        UniformHandle       fCoverageUni;
520365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
530365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        // We use the render target height to provide a y-down frag coord when specifying
540365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        // origin_upper_left is not supported.
550365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        UniformHandle       fRTHeightUni;
560365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
570365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        // Uniforms for computing texture coords to do the dst-copy lookup
580365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        UniformHandle       fDstCopyTopLeftUni;
590365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        UniformHandle       fDstCopyScaleUni;
600365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        UniformHandle       fDstCopySamplerUni;
610365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    };
620365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
630365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    struct GenProgramOutput {
640365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        GrGLProgramEffects* fColorEffects;
650365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        GrGLProgramEffects* fCoverageEffects;
660365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        UniformHandles fUniformHandles;
670365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        bool fHasVS;
680365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        int fNumTexCoordSets;
690365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org        GrGLuint fProgramID;
700365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    };
710365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
720365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    static bool GenProgram(GrGpuGL* gpu,
730365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                           GrGLUniformManager& uman,
740365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                           const GrGLProgramDesc& desc,
750365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                           const GrEffectStage* inColorStages[],
760365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                           const GrEffectStage* inCoverageStages[],
770365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                           GenProgramOutput* output);
780365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
79261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual ~GrGLShaderBuilder() {}
80f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
81f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    /**
8242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
8342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * if code is added that uses one of these features without calling enableFeature()
8442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
8542eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    enum GLSLFeature {
8642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com        kStandardDerivatives_GLSLFeature = 0,
8742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
8842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com        kLastGLSLFeature = kStandardDerivatives_GLSLFeature
8942eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    };
9042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
9142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
9242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * If the feature is supported then true is returned and any necessary #extension declarations
9342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * are added to the shaders. If the feature is not supported then false will be returned.
9442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
9542eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    bool enableFeature(GLSLFeature);
9642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
9742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
985a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org     * Called by GrGLEffects to add code the fragment shader.
99f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com     */
100f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
101f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_list args;
102f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_start(args, format);
103ce0e4efabd00b38aaaeb33457dcdb6c98e6eec12commit-bot@chromium.org        fFSCode.appendVAList(format, args);
104f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_end(args);
105f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    }
106f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
10774a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsCodeAppend(const char* str) { fFSCode.append(str); }
108f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
109dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
110dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
111dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
112868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com    void appendTextureLookup(SkString* out,
113f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                             const TextureSampler&,
114dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com                             const char* coordName,
115868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com                             GrSLType coordType = kVec2f_GrSLType) const;
116868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com
11774a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    /** Version of above that appends the result to the fragment shader code instead.*/
11874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsAppendTextureLookup(const TextureSampler&,
11974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                               const char* coordName,
12074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                               GrSLType coordType = kVec2f_GrSLType);
121f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
122f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
1232d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
1242d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
1252d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
1262d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        called. */
12774a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsAppendTextureLookupAndModulate(const char* modulation,
12874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                                          const TextureSampler&,
12974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                                          const char* coordName,
13074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                                          GrSLType coordType = kVec2f_GrSLType);
13174a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org
13274a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    /** Emits a helper function outside of main() in the fragment shader. */
13374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsEmitFunction(GrSLType returnType,
13474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        const char* name,
13574a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        int argCnt,
13674a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        const GrGLShaderVar* args,
13774a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        const char* body,
13874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        SkString* outName);
139a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com
14026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    typedef uint8_t DstReadKey;
141b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    typedef uint8_t FragPosKey;
14226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
14326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    /**  Returns a key for adding code to read the copy-of-dst color in service of effects that
14426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com         require reading the dst. It must not return 0 because 0 indicates that there is no dst
145b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com         copy read at all (in which case this function should not be called). */
14626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
14726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
148b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    /** Returns a key for reading the fragment location. This should only be called if there is an
149b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        effect that will requires the fragment position. If the fragment position is not required,
150b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        the key is 0. */
151b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
152b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
1536d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com    /** If texture swizzling is available using tex parameters then it is preferred over mangling
1546d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com        the generated shader code. This potentially allows greater reuse of cached shaders. */
1556d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
1566d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com
157706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
15874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org        visibility is a bitfield of ShaderVisibility values indicating from which shaders the
15974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org        uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
160777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
161777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        it will refer to the final uniform name after return. Use the addUniformArray variant to add
162777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        an array of uniforms.
163242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com    */
164dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
165dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com                                                 GrSLType type,
166dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com                                                 const char* name,
167777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                 const char** outName = NULL) {
168777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
169777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    }
170777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
171777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      GrSLType type,
172777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      const char* name,
173777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      int arrayCount,
174777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      const char** outName = NULL);
175032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
1767425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
1777425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org        return fUniformManager.getBuilderUniform(fUniforms, u).fVariable;
1787425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    }
179032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
180032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    /**
181706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com     * Shortcut for getUniformVariable(u).c_str()
182032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com     */
183dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
184032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com        return this->getUniformVariable(u).c_str();
185032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    }
186eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com
18777af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    /**
18877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     * This returns a variable name to access the 2D, perspective correct version of the coords in
18977af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
19077af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     * perspective divide into the fragment shader (xy / z) to convert them to 2D.
19177af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     */
19277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    SkString ensureFSCoords2D(const TransformedCoordsArray&, int index);
19377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com
194706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    /** Returns a variable name that represents the position of the fragment in the FS. The position
195706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
196706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    const char* fragmentPosition();
197706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com
19826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    /** Returns the color of the destination pixel. This may be NULL if no effect advertised
19926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        that it will read the destination. */
2006b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com    const char* dstColor();
20126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
202c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    /**
20334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com     * Interfaces used by GrGLProgram.
204dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com     */
205a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    const GrGLSLExpr4& getInputColor() const {
206261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        return fInputColor;
207261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
208a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    const GrGLSLExpr4& getInputCoverage() const {
209261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        return fInputCoverage;
210261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
21134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com
212504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    /**
2133390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org     * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
2143390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org     * deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key
2153390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org     * generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and
216824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org     * is updated to be the output color of the last stage.
217824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org     * The handles to texture samplers for effectStage[i] are added to
2183390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org     * effectSamplerHandles[i].
219504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com     */
220261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
221261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                                                     const EffectKey effectKeys[],
222261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                                                     int effectCnt,
223a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                                                     GrGLSLExpr4* inOutFSColor) = 0;
22426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
225410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org    const char* getColorOutputName() const;
226410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org    const char* enableSecondaryOutput();
227410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org
228706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
22926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
23026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return fDstCopyTopLeftUniform;
23126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
23226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
23326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return fDstCopyScaleUniform;
23426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
235410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org    GrGLUniformManager::UniformHandle getColorUniform() const { return fColorUniform; }
236410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org    GrGLUniformManager::UniformHandle getCoverageUniform() const { return fCoverageUniform; }
23726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
2383390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org        return fDstCopySamplerUniform;
23926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
240ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
241261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool finish(GrGLuint* outProgramId);
2425a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
243261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLContextInfo& ctxInfo() const;
2445a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
245907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    /**
246907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * Helper for begining and ending a block in the fragment code. TODO: Make GrGLShaderBuilder
247907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * aware of all blocks and turn single \t's into the correct number of tabs (or spaces) so that
248907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * our shaders print pretty without effect writers tracking indentation.
249907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     */
250907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    class FSBlock {
251907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    public:
252907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        FSBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
253907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkASSERT(NULL != builder);
254907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            fBuilder->fsCodeAppend("\t{\n");
255907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
256907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
257907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        ~FSBlock() {
258907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            fBuilder->fsCodeAppend("\t}\n");
259907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
260907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    private:
261907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        GrGLShaderBuilder* fBuilder;
262907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    };
263907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
264261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgprotected:
2650365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
2660365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
267261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGpuGL* gpu() const { return fGpu; }
2685a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
2690365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    const GrGLProgramDesc& desc() const { return fDesc; }
2700365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
271a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    void setInputColor(const GrGLSLExpr4& inputColor) { fInputColor = inputColor; }
272a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    void setInputCoverage(const GrGLSLExpr4& inputCoverage) { fInputCoverage = inputCoverage; }
273410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org
274261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
275261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
2765a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
277261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    // Generates a name for a variable. The generated string will be name prefixed by the prefix
278261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
279261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    // generating stage code.
280261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void nameVariable(SkString* out, char prefix, const char* name);
281ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
282261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    // Helper for emitEffects().
283261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void createAndEmitEffects(GrGLProgramEffectsBuilder*,
284261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                              const GrEffectStage* effectStages[],
285261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                              const EffectKey effectKeys[],
286261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                              int effectCnt,
287a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                              GrGLSLExpr4* inOutFSColor);
288706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com
289d328fb62938b1d7e43b07c619756dfdc781453b3commit-bot@chromium.org    virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
290261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual void bindProgramLocations(GrGLuint programId) const;
29113f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com
292032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    void appendDecls(const VarArray&, SkString*) const;
29374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void appendUniformDecls(ShaderVisibility, SkString*) const;
294032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
295ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comprivate:
296e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.org    class CodeStage : SkNoncopyable {
297504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    public:
298a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
299504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
300504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        bool inStageCode() const {
301504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            this->validate();
302a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            return NULL != fEffectStage;
303504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
304504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
305a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        const GrEffectStage* effectStage() const {
306504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            this->validate();
307a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            return fEffectStage;
308504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
309504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
310504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        int stageIndex() const {
3110f20a3fc59dee846ca137dd7a263e655550e6cbfskia.committer@gmail.com            this->validate();
312504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            return fCurrentIndex;
313504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
314504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
315e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.org        class AutoStageRestore : SkNoncopyable {
316504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        public:
317a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
318f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org                SkASSERT(NULL != codeStage);
319504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fSavedIndex = codeStage->fCurrentIndex;
320a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                fSavedEffectStage = codeStage->fEffectStage;
321504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
322a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                if (NULL == newStage) {
323504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                    codeStage->fCurrentIndex = -1;
324504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                } else {
325504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
326504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                }
327a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                codeStage->fEffectStage = newStage;
328504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
329504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fCodeStage = codeStage;
330504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            }
331504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            ~AutoStageRestore() {
332504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fCodeStage->fCurrentIndex = fSavedIndex;
333a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                fCodeStage->fEffectStage = fSavedEffectStage;
334504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            }
335504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        private:
336a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            CodeStage*              fCodeStage;
337a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            int                     fSavedIndex;
338a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            const GrEffectStage*    fSavedEffectStage;
339504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        };
340504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    private:
341a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
342a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        int                     fNextIndex;
343a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        int                     fCurrentIndex;
344a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        const GrEffectStage*    fEffectStage;
345504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    } fCodeStage;
346777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com
3470365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    bool genProgram(const GrEffectStage* colorStages[],
3480365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                    const GrEffectStage* coverageStages[],
3490365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                    GenProgramOutput* output);
3500365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
35142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
35242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * Features that should only be enabled by GrGLShaderBuilder itself.
35342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
35442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    enum GLSLPrivateFeature {
3556b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
3566b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kEXTShaderFramebufferFetch_GLSLPrivateFeature,
3576b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kNVShaderFramebufferFetch_GLSLPrivateFeature,
35842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    };
35942eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    bool enablePrivateFeature(GLSLPrivateFeature);
36042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
36174a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
36274a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    // track the enables separately for each shader.
36342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    void addFSFeature(uint32_t featureBit, const char* extensionName);
36442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
36526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // Interpretation of DstReadKey when generating code
36626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    enum {
36726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kNoDstRead_DstReadKey         = 0,
36826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kYesDstRead_DstReadKeyBit     = 0x1, // Set if we do a dst-copy-read.
36926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
37026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        kTopLeftOrigin_DstReadKeyBit  = 0x4, // Set if dst-copy origin is top-left.
37126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    };
37226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
373b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    enum {
374b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
375b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
376b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
377b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    };
378b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
3790365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    const GrGLProgramDesc&                  fDesc;
380261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGpuGL*                                fGpu;
381261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager&                     fUniformManager;
382261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    uint32_t                                fFSFeaturesAddedMask;
383261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                                fFSFunctions;
384261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                                fFSExtensions;
385261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                                fFSInputs;
386261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                                fFSOutputs;
387261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::BuilderUniformArray fUniforms;
388261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
389261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                                fFSCode;
390261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
391261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fSetupFragPosition;
392261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fDstCopySamplerUniform;
393261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
394a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    GrGLSLExpr4                             fInputColor;
395a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org    GrGLSLExpr4                             fInputCoverage;
396261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
397261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fHasCustomColorOutput;
398261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fHasSecondaryOutput;
399261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
400261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fRTHeightUniform;
401261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fDstCopyTopLeftUniform;
402261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fDstCopyScaleUniform;
403261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fColorUniform;
404261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle       fCoverageUniform;
405261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
406261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fTopLeftFragPosRead;
407261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org};
408261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
409261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////////
410261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
411261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgclass GrGLFullShaderBuilder : public GrGLShaderBuilder {
412261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgpublic:
413261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLFullShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
414261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
415261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /**
416261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     * Called by GrGLEffects to add code to one of the shaders.
417261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     */
418261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
419261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        va_list args;
420261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        va_start(args, format);
421ce0e4efabd00b38aaaeb33457dcdb6c98e6eec12commit-bot@chromium.org        fVSCode.appendVAList(format, args);
422261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        va_end(args);
423261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
424261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
425261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void vsCodeAppend(const char* str) { fVSCode.append(str); }
42626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
427261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org   /** Add a vertex attribute to the current program that is passed in from the vertex data.
428261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org       Returns false if the attribute was already there, true otherwise. */
429261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool addAttribute(GrSLType type, const char* name);
430f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
431261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org   /** Add a varying variable to the current program to pass values between vertex and fragment
432261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        shaders. If the last two parameters are non-NULL, they are filled in with the name
433261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        generated. */
434261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void addVarying(GrSLType type,
435261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                    const char* name,
436261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                    const char** vsOutName = NULL,
437261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                    const char** fsInName = NULL);
438261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
439261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
440261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
441261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org      */
442261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
443261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
444261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
445261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        as positionAttribute() or it may not be. It depends upon whether the rendering code
446261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        specified explicit local coords or not in the GrDrawState. */
447261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
448261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
449261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /**
450261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     * Are explicit local coordinates provided as input to the vertex shader.
451261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     */
452261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
45326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
454261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
455261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const SkString* getEffectAttributeName(int attributeIndex) const;
456410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org
457261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual GrGLProgramEffects* createAndEmitEffects(
458261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                const GrEffectStage* effectStages[],
459261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                const EffectKey effectKeys[],
460261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                int effectCnt,
461a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
462261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
46347c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org    /**
46447c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org     * The view matrix uniform is only valid in the VS. It is always mat33.
46547c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org     */
466261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle getViewMatrixUniform() const {
467261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        return fViewMatrixUniform;
468261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
469261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
47047c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org    GrGLUniformManager::UniformHandle getRTAdjustmentVecUniform() const {
47147c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org        return fRTAdustmentVecUniform;
47247c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org    }
47347c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org
474261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgprotected:
475d328fb62938b1d7e43b07c619756dfdc781453b3commit-bot@chromium.org    virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE;
476261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE;
477261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
478261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgprivate:
479261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                            fVSAttrs;
480261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                            fVSOutputs;
481261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                            fGSInputs;
482261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                            fGSOutputs;
483261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
484261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                            fVSCode;
485261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
486261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    struct AttributePair {
487261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        void set(int index, const SkString& name) {
488261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            fIndex = index; fName = name;
489261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        }
490261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        int      fIndex;
491261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        SkString fName;
492261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    };
493261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkSTArray<10, AttributePair, true>  fEffectAttributes;
494410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org
495261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::UniformHandle   fViewMatrixUniform;
49647c66ddaeb48faf963a2ef3f508a7d816e4168cccommit-bot@chromium.org    GrGLUniformManager::UniformHandle   fRTAdustmentVecUniform;
497261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLShaderVar*                      fPositionVar;
498261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLShaderVar*                      fLocalCoordsVar;
499b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
500261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    typedef GrGLShaderBuilder INHERITED;
501f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com};
502f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
5036b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////////
5046b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
5056b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.orgclass GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder {
5066b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.orgpublic:
5076b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    GrGLFragmentOnlyShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
5086b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
5096b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    int getNumTexCoordSets() const { return fNumTexCoordSets; }
5108e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org    int addTexCoordSets(int count);
5116b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
5126b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    virtual GrGLProgramEffects* createAndEmitEffects(
5136b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org                const GrEffectStage* effectStages[],
5146b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org                const EffectKey effectKeys[],
5156b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org                int effectCnt,
516a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
5176b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
5186b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.orgprivate:
5196b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    int fNumTexCoordSets;
5206b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
5216b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    typedef GrGLShaderBuilder INHERITED;
5226b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org};
5236b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
524f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#endif
525