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 {
64facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org        GenProgramOutput()
65facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org            : fColorEffects(NULL)
66facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org            , fCoverageEffects(NULL)
67facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org            , fHasVertexShader(false)
68facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org            , fTexCoordSetCnt(0)
69facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org            , fProgramID(0) {}
70facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org
71a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        GenProgramOutput(const GenProgramOutput& other) {
72a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org            *this = other;
73a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        }
74a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org
75a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        GenProgramOutput& operator=(const GenProgramOutput& other) {
76a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org            fColorEffects.reset(SkRef(other.fColorEffects.get()));
77a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org            fCoverageEffects.reset(SkRef(other.fCoverageEffects.get()));
78a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org            fUniformHandles = other.fUniformHandles;
79a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org            fHasVertexShader = other.fHasVertexShader;
80a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org            fTexCoordSetCnt = other.fTexCoordSetCnt;
81a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org            fProgramID = other.fProgramID;
82a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org            return *this;
83a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        }
84a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org
85a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        SkAutoTUnref<GrGLProgramEffects> fColorEffects;
86a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        SkAutoTUnref<GrGLProgramEffects> fCoverageEffects;
87a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        UniformHandles                   fUniformHandles;
88a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        bool                             fHasVertexShader;
89a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        int                              fTexCoordSetCnt;
90a05fa0669bac20e521ac3c1905fe8391fd659e60commit-bot@chromium.org        GrGLuint                         fProgramID;
910365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    };
920365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
930365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    static bool GenProgram(GrGpuGL* gpu,
946eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                           GrGLUniformManager* uman,
950365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                           const GrGLProgramDesc& desc,
960365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                           const GrEffectStage* inColorStages[],
970365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                           const GrEffectStage* inCoverageStages[],
980365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org                           GenProgramOutput* output);
990365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
100261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual ~GrGLShaderBuilder() {}
101f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
102f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    /**
10342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
10442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * if code is added that uses one of these features without calling enableFeature()
10542eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
10642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    enum GLSLFeature {
10742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com        kStandardDerivatives_GLSLFeature = 0,
10842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
10942eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com        kLastGLSLFeature = kStandardDerivatives_GLSLFeature
11042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    };
11142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
11242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
11342eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * If the feature is supported then true is returned and any necessary #extension declarations
11442eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * are added to the shaders. If the feature is not supported then false will be returned.
11542eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
11642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    bool enableFeature(GLSLFeature);
11742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
11842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
1195a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org     * Called by GrGLEffects to add code the fragment shader.
120f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com     */
121f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
122f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_list args;
123f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_start(args, format);
124ce0e4efabd00b38aaaeb33457dcdb6c98e6eec12commit-bot@chromium.org        fFSCode.appendVAList(format, args);
125f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        va_end(args);
126f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com    }
127f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
12874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsCodeAppend(const char* str) { fFSCode.append(str); }
129f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
130dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
131dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
132dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
133868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com    void appendTextureLookup(SkString* out,
134f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                             const TextureSampler&,
135dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com                             const char* coordName,
136868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com                             GrSLType coordType = kVec2f_GrSLType) const;
137868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com
13874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    /** Version of above that appends the result to the fragment shader code instead.*/
13974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsAppendTextureLookup(const TextureSampler&,
14074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                               const char* coordName,
14174a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                               GrSLType coordType = kVec2f_GrSLType);
142f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
143f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
1442d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
1452d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
1462d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
1472d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com        called. */
14874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsAppendTextureLookupAndModulate(const char* modulation,
14974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                                          const TextureSampler&,
15074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                                          const char* coordName,
15174a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                                          GrSLType coordType = kVec2f_GrSLType);
15274a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org
15374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    /** Emits a helper function outside of main() in the fragment shader. */
15474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void fsEmitFunction(GrSLType returnType,
15574a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        const char* name,
15674a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        int argCnt,
15774a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        const GrGLShaderVar* args,
15874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        const char* body,
15974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org                        SkString* outName);
160a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com
16126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    typedef uint8_t DstReadKey;
162b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    typedef uint8_t FragPosKey;
16326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
16426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    /**  Returns a key for adding code to read the copy-of-dst color in service of effects that
16526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com         require reading the dst. It must not return 0 because 0 indicates that there is no dst
166b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com         copy read at all (in which case this function should not be called). */
16726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
16826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
169b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    /** Returns a key for reading the fragment location. This should only be called if there is an
170b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        effect that will requires the fragment position. If the fragment position is not required,
171b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        the key is 0. */
172b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
173b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
1746d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com    /** If texture swizzling is available using tex parameters then it is preferred over mangling
1756d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com        the generated shader code. This potentially allows greater reuse of cached shaders. */
1766d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
1776d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com
178706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
17974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org        visibility is a bitfield of ShaderVisibility values indicating from which shaders the
18074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org        uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
181777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
182777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        it will refer to the final uniform name after return. Use the addUniformArray variant to add
183facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org        an array of uniforms. */
184dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
185dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com                                                 GrSLType type,
186dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com                                                 const char* name,
187777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                 const char** outName = NULL) {
188777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
189777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    }
190777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
191777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      GrSLType type,
192777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      const char* name,
193777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      int arrayCount,
194777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                                      const char** outName = NULL);
195032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
1967425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
1976eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org        return fUniformManager->getBuilderUniform(fUniforms, u).fVariable;
1987425c124f685978a0a6f0a1f79e89154019e7c99commit-bot@chromium.org    }
199032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
200032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    /**
201706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com     * Shortcut for getUniformVariable(u).c_str()
202032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com     */
203dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
204032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com        return this->getUniformVariable(u).c_str();
205032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    }
206eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com
20777af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    /**
20877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     * This returns a variable name to access the 2D, perspective correct version of the coords in
20977af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
21077af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     * perspective divide into the fragment shader (xy / z) to convert them to 2D.
21177af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com     */
21277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    SkString ensureFSCoords2D(const TransformedCoordsArray&, int index);
21377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com
214706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    /** Returns a variable name that represents the position of the fragment in the FS. The position
215706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
216706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com    const char* fragmentPosition();
217706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com
2186eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    /** Returns the variable name that holds the color of the destination pixel. This may be NULL if
2196eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org        no effect advertised that it will read the destination. */
2206b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com    const char* dstColor();
22126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
222261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLContextInfo& ctxInfo() const;
2235a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
224907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    /**
225907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * Helper for begining and ending a block in the fragment code. TODO: Make GrGLShaderBuilder
226907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * aware of all blocks and turn single \t's into the correct number of tabs (or spaces) so that
227907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * our shaders print pretty without effect writers tracking indentation.
228907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     */
229907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    class FSBlock {
230907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    public:
231907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        FSBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
232907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkASSERT(NULL != builder);
233907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            fBuilder->fsCodeAppend("\t{\n");
234907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
235907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
236907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        ~FSBlock() {
237907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            fBuilder->fsCodeAppend("\t}\n");
238907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
239907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    private:
240907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        GrGLShaderBuilder* fBuilder;
241907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    };
242907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
243261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgprotected:
2446eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager*, const GrGLProgramDesc&);
2450365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
246261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGpuGL* gpu() const { return fGpu; }
2475a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
2480365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    const GrGLProgramDesc& desc() const { return fDesc; }
2490365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
250261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
251261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
2525a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org
253261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    // Helper for emitEffects().
254261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void createAndEmitEffects(GrGLProgramEffectsBuilder*,
255261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                              const GrEffectStage* effectStages[],
256261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                              const EffectKey effectKeys[],
257261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                              int effectCnt,
258a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                              GrGLSLExpr4* inOutFSColor);
259706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com
2606eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    // Generates a name for a variable. The generated string will be name prefixed by the prefix
2616eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
2626eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    // generating stage code.
2636eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    void nameVariable(SkString* out, char prefix, const char* name);
2646eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
265d328fb62938b1d7e43b07c619756dfdc781453b3commit-bot@chromium.org    virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
2666eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
267261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual void bindProgramLocations(GrGLuint programId) const;
26813f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com
269032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com    void appendDecls(const VarArray&, SkString*) const;
27074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    void appendUniformDecls(ShaderVisibility, SkString*) const;
271032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com
272facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org    const GenProgramOutput& getOutput() const { return fOutput; }
273facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org
274facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org    GenProgramOutput fOutput;
275facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org
276ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comprivate:
277e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.org    class CodeStage : SkNoncopyable {
278504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    public:
279a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
280504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
281504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        bool inStageCode() const {
282504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            this->validate();
283a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            return NULL != fEffectStage;
284504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
285504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
286a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        const GrEffectStage* effectStage() const {
287504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            this->validate();
288a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            return fEffectStage;
289504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
290504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
291504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        int stageIndex() const {
2920f20a3fc59dee846ca137dd7a263e655550e6cbfskia.committer@gmail.com            this->validate();
293504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            return fCurrentIndex;
294504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        }
295504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
296e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.org        class AutoStageRestore : SkNoncopyable {
297504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        public:
298a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
299f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org                SkASSERT(NULL != codeStage);
300504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fSavedIndex = codeStage->fCurrentIndex;
301a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                fSavedEffectStage = codeStage->fEffectStage;
302504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
303a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                if (NULL == newStage) {
304504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                    codeStage->fCurrentIndex = -1;
305504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                } else {
306504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
307504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                }
308a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                codeStage->fEffectStage = newStage;
309504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com
310504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fCodeStage = codeStage;
311504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            }
312504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            ~AutoStageRestore() {
313504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com                fCodeStage->fCurrentIndex = fSavedIndex;
314a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org                fCodeStage->fEffectStage = fSavedEffectStage;
315504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com            }
316504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        private:
317a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            CodeStage*              fCodeStage;
318a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            int                     fSavedIndex;
319a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org            const GrEffectStage*    fSavedEffectStage;
320504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com        };
321504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    private:
322a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
323a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        int                     fNextIndex;
324a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        int                     fCurrentIndex;
325a4acf12a9353ffc834d2c6ee673be447487963c9commit-bot@chromium.org        const GrEffectStage*    fEffectStage;
326504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com    } fCodeStage;
327777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com
328facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org    bool genProgram(const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[]);
3290365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org
33042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    /**
331f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org     * The base class will emit the fragment code that precedes the per-effect code and then call
332f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org     * this function. The subclass can use it to insert additional fragment code that should
333f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org     * execute before the effects' code and/or emit other shaders (e.g. geometry, vertex).
334f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org     *
335f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org     * The subclass can modify the initial color or coverage
336f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org     */
337f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org    virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) = 0;
338f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org
339f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org    /**
3406eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
3416eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    * deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key
3426eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    * generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and
3436eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    * is updated to be the output color of the last stage.
3446eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    * The handles to texture samplers for effectStage[i] are added to
3456eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    * effectSamplerHandles[i].
3466eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    */
3476eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
3486eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                                     const EffectKey effectKeys[],
3496eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                                     int effectCnt,
3506eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                                     GrGLSLExpr4* inOutFSColor) = 0;
3516eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
352f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org    /**
353f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org     * Similar to emitCodeBeforeEffects() but called after per-effect code is emitted.
354f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org     */
355f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org    virtual void emitCodeAfterEffects() = 0;
356f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org
3576eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    /** Enables using the secondary color output and returns the name of the var in which it is
3586eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org        to be stored */
3596eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    const char* enableSecondaryOutput();
3606eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    /** Gets the name of the primary color output. */
3616eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    const char* getColorOutputName() const;
3626eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
363facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org    /**
364facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org     * Compiles all the shaders, links them into a program, and writes the program id to the output
365facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org     * struct.
366facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org     **/
367facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org    bool finish();
3686eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
3696eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    /**
37042eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     * Features that should only be enabled by GrGLShaderBuilder itself.
37142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com     */
37242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    enum GLSLPrivateFeature {
3736b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
3746b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kEXTShaderFramebufferFetch_GLSLPrivateFeature,
3756b0cf0273fdffbbdf69235b57b5b5a311e7f1ca6bsalomon@google.com        kNVShaderFramebufferFetch_GLSLPrivateFeature,
37642eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    };
37742eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    bool enablePrivateFeature(GLSLPrivateFeature);
37842eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
37974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
38074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org    // track the enables separately for each shader.
38142eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com    void addFSFeature(uint32_t featureBit, const char* extensionName);
38242eff161a2acdbf03a71666b3fc31079a1bba86fbsalomon@google.com
38326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // Interpretation of DstReadKey when generating code
38426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    enum {
385facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org        kNoDstRead_DstReadKey           = 0,
386facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org        kYesDstRead_DstReadKeyBit       = 0x1, // Set if we do a dst-copy-read.
387facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org        kUseAlphaConfig_DstReadKeyBit   = 0x2, // Set if dst-copy config is alpha only.
388facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org        kTopLeftOrigin_DstReadKeyBit    = 0x4, // Set if dst-copy origin is top-left.
38926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    };
39026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
391b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    enum {
392b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
393b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
394b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
395b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    };
396b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
3970365261597f73c049f2d8c117c8c87ef2fb2c9abcommit-bot@chromium.org    const GrGLProgramDesc&                  fDesc;
398261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGpuGL*                                fGpu;
3996eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    SkAutoTUnref<GrGLUniformManager>        fUniformManager;
400261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    uint32_t                                fFSFeaturesAddedMask;
401261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                                fFSFunctions;
402261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                                fFSExtensions;
403261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                                fFSInputs;
404261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    VarArray                                fFSOutputs;
405261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLUniformManager::BuilderUniformArray fUniforms;
406261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
407261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    SkString                                fFSCode;
408261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
409261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fSetupFragPosition;
410facad13fa840d362a8ea40161916fe609cb52657commit-bot@chromium.org    bool                                    fTopLeftFragPosRead;
411261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
412261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fHasCustomColorOutput;
413261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool                                    fHasSecondaryOutput;
414261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org};
415261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
416261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////////
417261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
418261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgclass GrGLFullShaderBuilder : public GrGLShaderBuilder {
419261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.orgpublic:
4206eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    GrGLFullShaderBuilder(GrGpuGL*, GrGLUniformManager*, const GrGLProgramDesc&);
421261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
422261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /**
423261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     * Called by GrGLEffects to add code to one of the shaders.
424261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     */
425261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
426261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        va_list args;
427261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        va_start(args, format);
428ce0e4efabd00b38aaaeb33457dcdb6c98e6eec12commit-bot@chromium.org        fVSCode.appendVAList(format, args);
429261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        va_end(args);
430261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    }
431261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
432261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void vsCodeAppend(const char* str) { fVSCode.append(str); }
43326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
434261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org   /** Add a vertex attribute to the current program that is passed in from the vertex data.
435261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org       Returns false if the attribute was already there, true otherwise. */
436261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool addAttribute(GrSLType type, const char* name);
437f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com
438261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org   /** Add a varying variable to the current program to pass values between vertex and fragment
439261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        shaders. If the last two parameters are non-NULL, they are filled in with the name
440261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        generated. */
441261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    void addVarying(GrSLType type,
442261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                    const char* name,
443261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                    const char** vsOutName = NULL,
444261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                    const char** fsInName = NULL);
445261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
446261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
447261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
448261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org      */
449261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
450261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
451261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
452261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        as positionAttribute() or it may not be. It depends upon whether the rendering code
453261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        specified explicit local coords or not in the GrDrawState. */
454261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
455261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
456261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    /**
457261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     * Are explicit local coordinates provided as input to the vertex shader.
458261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org     */
459261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
46026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
461261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
462261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    const SkString* getEffectAttributeName(int attributeIndex) const;
463410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org
4646eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.orgprivate:
465f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org    virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) SK_OVERRIDE;
466f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org
4676eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
4686eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                                     const EffectKey effectKeys[],
4696eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                                     int effectCnt,
4706eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                                     GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
471f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org
472f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org    virtual void emitCodeAfterEffects() SK_OVERRIDE;
473f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org
4746eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    virtual bool compileAndAttachShaders(GrGLuint programId,
4756eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                         SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE;
4766eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
477261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE;
478261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org
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    GrGLShaderVar*                      fPositionVar;
496261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    GrGLShaderVar*                      fLocalCoordsVar;
497b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com
498261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    typedef GrGLShaderBuilder INHERITED;
499f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com};
500f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com
5016b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////////
5026b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
5036b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.orgclass GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder {
5046b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.orgpublic:
5056eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    GrGLFragmentOnlyShaderBuilder(GrGpuGL*, GrGLUniformManager*, const GrGLProgramDesc&);
5066b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
5078e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org    int addTexCoordSets(int count);
5086b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
5096b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.orgprivate:
510f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org    virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) SK_OVERRIDE {}
5116eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
5126eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
5136eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                                     const EffectKey effectKeys[],
5146eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                                     int effectCnt,
5156eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org                                                     GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
5166eac42e3ab68b085117d7f91621276a722b5a3a7commit-bot@chromium.org
517f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org    virtual void emitCodeAfterEffects() SK_OVERRIDE {}
518f7f9aa0e4721624395d247ffa1f0128cfac95341commit-bot@chromium.org
5196b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    typedef GrGLShaderBuilder INHERITED;
5206b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org};
5216b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org
522f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#endif
523