131ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com/*
231ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com * Copyright 2013 Google Inc.
331ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com *
431ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
531ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com * found in the LICENSE file.
631ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com */
731ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
831ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com#ifndef GrGLProgramDesc_DEFINED
931ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com#define GrGLProgramDesc_DEFINED
1031ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
1131ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com#include "GrGLEffect.h"
12798c8c4fe61f2172ae52cb626843a64069e18882bsalomon@google.com#include "GrDrawState.h"
1326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com#include "GrGLShaderBuilder.h"
140a6fe71f1bc0e601b41b7ae6d28b8c96a2c41116commit-bot@chromium.org#include "GrGpu.h"
1531ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
1631ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.comclass GrGpuGL;
1731ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
18515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
19515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org  // Optionally compile the experimental GS code. Set to SK_DEBUG so that debug build bots will
20515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org  // execute the code.
21515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org  #define GR_GL_EXPERIMENTAL_GS 1
22515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#else
23515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org  #define GR_GL_EXPERIMENTAL_GS 0
24515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#endif
2531ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
2631ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
2726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com/** This class describes a program to generate. It also serves as a program cache key. Very little
2826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    of this is GL-specific. There is the generation of GrGLEffect::EffectKeys and the dst-read part
2926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    of the key set by GrGLShaderBuilder. If the interfaces that set those portions were abstracted
3026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    to be API-neutral then so could this class. */
3131ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.comclass GrGLProgramDesc {
3231ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.compublic:
332db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    GrGLProgramDesc() : fInitialized(false) {}
342db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    GrGLProgramDesc(const GrGLProgramDesc& desc) { *this = desc; }
3531ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
362d816ad36e806e5b1cf3c447e547829bbbe74fd1skia.committer@gmail.com    // Returns this as a uint32_t array to be used as a key in the program cache.
3731ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    const uint32_t* asKey() const {
38f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fInitialized);
392db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        return reinterpret_cast<const uint32_t*>(fKey.get());
4031ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    }
4131ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
422db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. When comparing two
432db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    // keys the size of either key can be used with memcmp() since the lengths themselves begin the
442db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    // keys and thus the memcmp will exit early if the keys are of different lengths.
452db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    uint32_t keyLength() const { return *this->atOffset<uint32_t, kLengthOffset>(); }
462db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
472db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    // Gets the a checksum of the key. Can be used as a hash value for a fast lookup in a cache.
482db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    uint32_t getChecksum() const { return *this->atOffset<uint32_t, kChecksumOffset>(); }
492db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
5031ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    // For unit testing.
51e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    void setRandom(SkRandom*,
5231ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com                   const GrGpuGL* gpu,
532db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com                   const GrRenderTarget* dummyDstRenderTarget,
542db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com                   const GrTexture* dummyDstCopyTexture,
552db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com                   const GrEffectStage* stages[],
562db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com                   int numColorStages,
572db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com                   int numCoverageStages,
58054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                   int currAttribIndex);
5931ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
6031ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    /**
6131ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com     * Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the
622db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com     * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs. It also
632c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com     * outputs the color and coverage stages referenced by the generated descriptor. This may
642c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com     * not contain all stages from the draw state and coverage stages from the drawState may
652c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com     * be treated as color stages in the output.
6631ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com     */
6731ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    static void Build(const GrDrawState&,
680a6fe71f1bc0e601b41b7ae6d28b8c96a2c41116commit-bot@chromium.org                      GrGpu::DrawType drawType,
6931ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com                      GrDrawState::BlendOptFlags,
7031ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com                      GrBlendCoeff srcCoeff,
7131ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com                      GrBlendCoeff dstCoeff,
7231ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com                      const GrGpuGL* gpu,
7326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com                      const GrDeviceCoordTexture* dstCopy,
742c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com                      SkTArray<const GrEffectStage*, true>* outColorStages,
752c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com                      SkTArray<const GrEffectStage*, true>* outCoverageStages,
7631ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com                      GrGLProgramDesc* outDesc);
7731ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
782db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    int numColorEffects() const {
79f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fInitialized);
802db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        return this->getHeader().fColorEffectCnt;
812db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
822db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
832db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    int numCoverageEffects() const {
84f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fInitialized);
852db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        return this->getHeader().fCoverageEffectCnt;
862db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
872db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
882db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    int numTotalEffects() const { return this->numColorEffects() + this->numCoverageEffects(); }
892db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
902db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    GrGLProgramDesc& operator= (const GrGLProgramDesc& other);
912db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
922db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    bool operator== (const GrGLProgramDesc& other) const {
93f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fInitialized && other.fInitialized);
942db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        // The length is masked as a hint to the compiler that the address will be 4 byte aligned.
952db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x3);
962db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
972db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
982db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    bool operator!= (const GrGLProgramDesc& other) const {
992db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        return !(*this == other);
1002db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
1012db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1022db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    static bool Less(const GrGLProgramDesc& a, const GrGLProgramDesc& b) {
1032db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0;
1042db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
1052db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
10631ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.comprivate:
10731ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    // Specifies where the initial color comes from before the stages are applied.
10831ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    enum ColorInput {
10931ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com        kSolidWhite_ColorInput,
11031ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com        kTransBlack_ColorInput,
11131ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com        kAttribute_ColorInput,
11231ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com        kUniform_ColorInput,
11331ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
11431ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com        kColorInputCnt
11531ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    };
1165920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com
1175920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com    enum CoverageOutput {
1185920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        // modulate color and coverage, write result as the color output.
1195920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        kModulate_CoverageOutput,
1205920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        // Writes color*coverage as the primary color output and also writes coverage as the
1215920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        // secondary output. Only set if dual source blending is supported.
1225920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        kSecondaryCoverage_CoverageOutput,
1235920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        // Writes color*coverage as the primary color output and also writes coverage * (1 - colorA)
1245920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        // as the secondary output. Only set if dual source blending is supported.
1255920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        kSecondaryCoverageISA_CoverageOutput,
1265920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        // Writes color*coverage as the primary color output and also writes coverage *
1275920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        // (1 - colorRGB) as the secondary output. Only set if dual source blending is supported.
1285920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        kSecondaryCoverageISC_CoverageOutput,
1295920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
130b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com        // can only be set if fDstReadKey is non-zero.
1315920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        kCombineWithDst_CoverageOutput,
1325920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com
1335920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        kCoverageOutputCnt
13431ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    };
13531ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
1365920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com    static bool CoverageOutputUsesSecondaryOutput(CoverageOutput co) {
1375920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        switch (co) {
1385920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com            case kSecondaryCoverage_CoverageOutput: //  fallthru
1395920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com            case kSecondaryCoverageISA_CoverageOutput:
1405920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com            case kSecondaryCoverageISC_CoverageOutput:
1415920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com                return true;
1425920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com            default:
1435920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com                return false;
1445920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com        }
1455920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com    }
1465920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com
1472db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    struct KeyHeader {
1482db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        GrGLShaderBuilder::DstReadKey fDstReadKey;      // set by GrGLShaderBuilder if there
14926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com                                                        // are effects that must read the dst.
15026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com                                                        // Otherwise, 0.
1512db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        GrGLShaderBuilder::FragPosKey fFragPosKey;      // set by GrGLShaderBuilder if there are
152b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com                                                        // effects that read the fragment position.
153b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com                                                        // Otherwise, 0.
15426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
155949eef0af2f5b47000e637347801cf2970092a38commit-bot@chromium.org        ColorInput                  fColorInput : 8;
156949eef0af2f5b47000e637347801cf2970092a38commit-bot@chromium.org        ColorInput                  fCoverageInput : 8;
157949eef0af2f5b47000e637347801cf2970092a38commit-bot@chromium.org        CoverageOutput              fCoverageOutput : 8;
158054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com
159234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org        SkBool8                     fHasVertexCode;
1602db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        SkBool8                     fEmitsPointSize;
1612db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1622db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        // To enable experimental geometry shader code (not for use in
1632db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        // production)
1642db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com#if GR_GL_EXPERIMENTAL_GS
1652db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        SkBool8                     fExperimentalGS;
1662db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com#endif
1672db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1682db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        int8_t                      fPositionAttributeIndex;
1692db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        int8_t                      fLocalCoordAttributeIndex;
1702db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        int8_t                      fColorAttributeIndex;
1712db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        int8_t                      fCoverageAttributeIndex;
1722d816ad36e806e5b1cf3c447e547829bbbe74fd1skia.committer@gmail.com
1732db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        int8_t                      fColorEffectCnt;
1742db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        int8_t                      fCoverageEffectCnt;
1752db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    };
1762db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1772db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    // The key is 1 uint32_t for the length, followed another for the checksum, the header, and then
1782db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    // the effect keys. Everything is fixed length except the effect key array.
1792db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    enum {
1802db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        kLengthOffset = 0,
1812db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        kChecksumOffset = kLengthOffset + sizeof(uint32_t),
1822db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        kHeaderOffset = kChecksumOffset + sizeof(uint32_t),
1832db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        kHeaderSize = SkAlign4(sizeof(KeyHeader)),
1842db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        kEffectKeyOffset = kHeaderOffset + kHeaderSize,
1852db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    };
1862db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1872db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    template<typename T, size_t OFFSET> T* atOffset() {
1882db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET);
1892db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
1902db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1912db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    template<typename T, size_t OFFSET> const T* atOffset() const {
1922db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET);
1932db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
1942db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1952db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    typedef GrGLEffect::EffectKey EffectKey;
1962db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1972db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    uint32_t* checksum() { return this->atOffset<uint32_t, kChecksumOffset>(); }
1982db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); }
1992db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    EffectKey* effectKeys() { return this->atOffset<EffectKey, kEffectKeyOffset>(); }
2002db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
2012db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
2022db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    const EffectKey* getEffectKeys() const { return this->atOffset<EffectKey, kEffectKeyOffset>(); }
2032db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
2042db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    static size_t KeyLength(int effectCnt) {
2052db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        GR_STATIC_ASSERT(!(sizeof(EffectKey) & 0x3));
2062db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        return kEffectKeyOffset + effectCnt * sizeof(EffectKey);
2072db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
2082db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
2092db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    enum {
2102db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        kMaxPreallocEffects = 16,
2112db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        kPreAllocSize = kEffectKeyOffset +  kMaxPreallocEffects * sizeof(EffectKey),
2122db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    };
21331ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
2142db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    SkAutoSMalloc<kPreAllocSize> fKey;
2152db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    bool fInitialized;
21631ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
21726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // GrGLProgram and GrGLShaderBuilder read the private fields to generate code. TODO: Move all
21826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // code generation to GrGLShaderBuilder (and maybe add getters rather than friending).
21931ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com    friend class GrGLProgram;
22026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    friend class GrGLShaderBuilder;
221261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    friend class GrGLFullShaderBuilder;
2226b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org    friend class GrGLFragmentOnlyShaderBuilder;
22331ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com};
22431ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
22531ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com#endif
226