GrGLProgram.h revision a5e65ec434fed44dc616e4f64950b835b541181b
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */
7f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
9f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#ifndef GrGLProgram_DEFINED
10f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#define GrGLProgram_DEFINED
11f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
12d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com#include "GrDrawState.h"
1396399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com#include "GrGLContextInfo.h"
14086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com#include "GrGLSL.h"
15890e3b58e78c0825820f75f1f0c5a5d71e855aa6bsalomon@google.com#include "GrGLTexture.h"
16dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#include "GrGLUniformManager.h"
17f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
18f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com#include "SkString.h"
1997c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo#include "SkXfermode.h"
2097c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo
21f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.comclass GrBinHashKeyBuilder;
2207eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.comclass GrGLProgramStage;
23f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.comclass GrGLShaderBuilder;
24f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
25edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com// optionally compile the experimental GS code. Set to GR_DEBUG
26edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com// so that debug build bots will execute the code.
27edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com#define GR_GL_EXPERIMENTAL_GS GR_DEBUG
28edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com
29f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com/**
30f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * This class manages a GPU program and records per-program information.
31f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * We can specify the attribute locations so that they are constant
32f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * across our shaders. But the driver determines the uniform locations
33f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * at link time. We don't need to remember the sampler uniform location
34f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * because we will bind a texture slot to it and never change it
35f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * Uniforms are program-local so we can't rely on fHWState to hold the
36f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * previous uniform state after a program change.
37f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */
389ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.comclass GrGLProgram : public GrRefCnt {
39f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.compublic:
409ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    SK_DECLARE_INST_COUNT(GrGLProgram)
414fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com
429ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    struct Desc;
43f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
44ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    static GrGLProgram* Create(const GrGLContextInfo& gl,
45ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com                               const Desc& desc,
46cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com                               const GrCustomStage** customStages);
47ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com
489ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    virtual ~GrGLProgram();
49f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
50ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    /** Call to abandon GL objects owned by this program */
51ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    void abandon();
52ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com
53f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com    /**
54ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com     * The shader may modify the blend coeffecients. Params are in/out
55f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com     */
56ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
57f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
58ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    const Desc& getDesc() { return fDesc; }
599ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
60271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    /**
61b5b5eaff4774d74fda1980963d77b41c4bb8d687bsalomon@google.com     * Attribute indices. These should not overlap. Matrices consume 3 slots.
62271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com     */
639196130af83782fcac4334117142475a837dd74dbsalomon@google.com    static int PositionAttributeIdx() { return 0; }
649196130af83782fcac4334117142475a837dd74dbsalomon@google.com    static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
659381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    static int ColorAttributeIdx() { return 1 + GrDrawState::kMaxTexCoords; }
66a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    static int CoverageAttributeIdx() {
679381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        return 2 + GrDrawState::kMaxTexCoords;
68a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    }
699381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    static int EdgeAttributeIdx() { return 3 + GrDrawState::kMaxTexCoords; }
70aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com
710d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com    static int ViewMatrixAttributeIdx() {
729381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        return 4 + GrDrawState::kMaxTexCoords;
739196130af83782fcac4334117142475a837dd74dbsalomon@google.com    }
740d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com    static int TextureMatrixAttributeIdx(int stage) {
759381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        return 7 + GrDrawState::kMaxTexCoords + 3 * stage;
769196130af83782fcac4334117142475a837dd74dbsalomon@google.com    }
779196130af83782fcac4334117142475a837dd74dbsalomon@google.com
780d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com    // Parameters that affect code generation
790d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com    // These structs should be kept compact; they are the input to an
800d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com    // expensive hash key generator.
819ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    struct Desc {
829ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com        Desc() {
834be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com            // since we use this as part of a key we can't have any unitialized
844be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com            // padding
859ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com            memset(this, 0, sizeof(Desc));
869ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com        }
879ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
889ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com        // returns this as a uint32_t array to be used as a key in the program cache
899ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com        const uint32_t* asKey() const {
909ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com            return reinterpret_cast<const uint32_t*>(this);
914be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com        }
924be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com
93a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com        enum OutputConfig {
94c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            // PM-color OR color with no alpha channel
95a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com            kPremultiplied_OutputConfig,
96a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com            // nonPM-color with alpha channel. Round components up after
97a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com            // dividing by alpha. Assumes output is 8 bits for r, g, and b
98a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com            kUnpremultiplied_RoundUp_OutputConfig,
99a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com            // nonPM-color with alpha channel. Round components down after
100a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com            // dividing by alpha. Assumes output is 8 bits for r, g, and b
101a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com            kUnpremultiplied_RoundDown_OutputConfig,
102a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com
103a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com            kOutputConfigCnt
104c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        };
105c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
1060d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        struct StageDesc {
1070d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com            enum OptFlagBits {
1080d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com                kNoPerspective_OptFlagBit       = 1 << 0,
1090d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com                kIdentityMatrix_OptFlagBit      = 1 << 1,
1100d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com                kIsEnabled_OptFlagBit           = 1 << 7
1110d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com            };
112b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com
1130a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com            /**
11474b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com              Flags set based on a src texture's pixel config. The operations
11574b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com              described are performed after reading a texel.
1160a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com             */
11774b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com            enum InConfigFlags {
118443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                kNone_InConfigFlag                      = 0x00,
11974b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com
12085b505bedc35369283ca3aa4449962622842b720bsalomon@google.com                /**
12174b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                  Swap the R and B channels. This is incompatible with
12274b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                  kSmearAlpha. It is prefereable to perform the swizzle outside
12374b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                  the shader using GL_ARB_texture_swizzle if possible rather
12474b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                  than setting this flag.
1250a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com                 */
126443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                kSwapRAndB_InConfigFlag                 = 0x01,
12774b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com
1280a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com                /**
12974b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                 Smear alpha across all four channels. This is incompatible with
130443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                 kSwapRAndB, kMulRGBByAlpha* and kSmearRed. It is prefereable
131443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                 to perform the smear outside the shader using
132443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                 GL_ARB_texture_swizzle if possible rather than setting this
133443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                 flag.
13485b505bedc35369283ca3aa4449962622842b720bsalomon@google.com                */
135443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                kSmearAlpha_InConfigFlag                = 0x02,
136443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com
137443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                /**
138443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                 Smear the red channel across all four channels. This flag is
139443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                 incompatible with kSwapRAndB, kMulRGBByAlpha*and kSmearAlpha.
140443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                 It is preferable to use GL_ARB_texture_swizzle instead of this
141443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                 flag.
142443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                */
143443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                kSmearRed_InConfigFlag                  = 0x04,
14474b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com
14574b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                /**
14674b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                 Multiply r,g,b by a after texture reads. This flag incompatible
147d2ae1fad78bbd37d77bd437ea14fb7df22c672d8bsalomon@google.com                 with kSmearAlpha.
148a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com
149a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com                 It is assumed the src texture has 8bit color components. After
150a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com                 reading the texture one version rounds up to the next multiple
151a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com                 of 1/255.0 and the other rounds down. At most one of these
152a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com                 flags may be set.
15374b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                 */
154443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                kMulRGBByAlpha_RoundUp_InConfigFlag     =  0x08,
155443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com                kMulRGBByAlpha_RoundDown_InConfigFlag   =  0x10,
15674b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com
15774b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                kDummyInConfigFlag,
15874b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                kInConfigBitMask = (kDummyInConfigFlag-1) |
15974b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                                   (kDummyInConfigFlag-2)
16085b505bedc35369283ca3aa4449962622842b720bsalomon@google.com            };
161f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
1620d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com            uint8_t fOptFlags;
16374b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com            uint8_t fInConfigFlags; // bitfield of InConfigFlags values
1640d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com
16507eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com            /** Non-zero if user-supplied code will write the stage's
16607eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com                contribution to the fragment shader. */
167a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com            GrProgramStageFactory::StageKey fCustomStageKey;
16807eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com
16974b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com            GR_STATIC_ASSERT((InConfigFlags)(uint8_t)kInConfigBitMask ==
17074b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com                             kInConfigBitMask);
17174b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com
1720d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com            inline bool isEnabled() const {
173c2c9b97e603fbccf04d29a550bf73709340ffe7dbsalomon@google.com                return SkToBool(fOptFlags & kIsEnabled_OptFlagBit);
1740d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com            }
1750d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com            inline void setEnabled(bool newValue) {
1760d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com                if (newValue) {
1770d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com                    fOptFlags |= kIsEnabled_OptFlagBit;
1780d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com                } else {
1790d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com                    fOptFlags &= ~kIsEnabled_OptFlagBit;
1800d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com                }
1810d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com            }
1820d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        };
1830d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com
18486c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com        // Specifies where the intitial color comes from before the stages are
18586c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com        // applied.
18685b505bedc35369283ca3aa4449962622842b720bsalomon@google.com        enum ColorInput {
18785b505bedc35369283ca3aa4449962622842b720bsalomon@google.com            kSolidWhite_ColorInput,
18885b505bedc35369283ca3aa4449962622842b720bsalomon@google.com            kTransBlack_ColorInput,
18985b505bedc35369283ca3aa4449962622842b720bsalomon@google.com            kAttribute_ColorInput,
19085b505bedc35369283ca3aa4449962622842b720bsalomon@google.com            kUniform_ColorInput,
19186c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com
19285b505bedc35369283ca3aa4449962622842b720bsalomon@google.com            kColorInputCnt
1930d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        };
1940d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        // Dual-src blending makes use of a secondary output color that can be
195271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        // used as a per-pixel blend coeffecient. This controls whether a
196271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        // secondary source is output and what value it holds.
197271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        enum DualSrcOutput {
198271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com            kNone_DualSrcOutput,
199271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com            kCoverage_DualSrcOutput,
200271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com            kCoverageISA_DualSrcOutput,
201271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com            kCoverageISC_DualSrcOutput,
2021e257a5db32e1c9e3b0dba80f43470816ef948afbsalomon@google.com
203271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com            kDualSrcOutputCnt
2040d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        };
205f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
2069381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        GrDrawState::VertexEdgeType fVertexEdgeType;
207aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com
2080d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        // stripped of bits that don't affect prog generation
2090d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        GrVertexLayout fVertexLayout;
21097c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo
2119381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        StageDesc fStages[GrDrawState::kNumStages];
212f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
213edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com        // To enable experimental geometry shader code (not for use in
214edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com        // production)
215edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com#if GR_GL_EXPERIMENTAL_GS
216edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com        bool fExperimentalGS;
217edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com#endif
218edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com
21985b505bedc35369283ca3aa4449962622842b720bsalomon@google.com        uint8_t fColorInput;        // casts to enum ColorInput
2202401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        uint8_t fCoverageInput;     // casts to enum CoverageInput
221a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com        uint8_t fOutputConfig;      // casts to enum OutputConfig
22285b505bedc35369283ca3aa4449962622842b720bsalomon@google.com        uint8_t fDualSrcOutput;     // casts to enum DualSrcOutput
2230d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        int8_t fFirstCoverageStage;
2240d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        SkBool8 fEmitsPointSize;
22550bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org        SkBool8 fColorMatrixEnabled;
226f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
2270d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com        uint8_t fColorFilterXfermode;  // casts to enum SkXfermode::Mode
2287ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com        int8_t fPadding[1];
2299ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    };
2309ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GR_STATIC_ASSERT(!(sizeof(Desc) % 4));
231f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
23222c5deaf755223111cb055462ac5bbce623f3a08bsalomon@google.com    // for code readability
2339ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    typedef Desc::StageDesc StageDesc;
23422c5deaf755223111cb055462ac5bbce623f3a08bsalomon@google.com
2352a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.comprivate:
236ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    GrGLProgram(const GrGLContextInfo& gl,
237ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com                const Desc& desc,
238cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com                const GrCustomStage** customStages);
239ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com
240ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    bool succeeded() const { return 0 != fProgramID; }
241ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com
242ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    /**
243ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com     *  This is the heavy initilization routine for building a GLProgram.
244ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com     */
245cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com    bool genProgram(const GrCustomStage** customStages);
246ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com
2479ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    void genInputColor(GrGLShaderBuilder* builder, SkString* inColor);
2482a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.com
2499ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    // Determines which uniforms will need to be bound.
250ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    void genStageCode(int stageNum,
2519ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com                      const char* fsInColor, // NULL means no incoming color
2529ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com                      const char* fsOutColor,
2539ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com                      const char* vsInCoord,
2549ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com                      GrGLShaderBuilder* builder);
2552a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.com
256ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    void genGeometryShader(GrGLShaderBuilder* segments) const;
2579ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
258dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    typedef GrGLUniformManager::UniformHandle UniformHandle;
259dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
2609ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    void genUniformCoverage(GrGLShaderBuilder* segments, SkString* inOutCoverage);
2619ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
2629ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    // generates code to compute coverage based on edge AA.
263ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    void genEdgeCoverage(SkString* coverageVar, GrGLShaderBuilder* builder) const;
2649ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
2659ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    // Creates a GL program ID, binds shader attributes to GL vertex attrs, and links the program
266ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    bool bindOutputsAttribsAndLinkProgram(SkString texCoordAttrNames[GrDrawState::kMaxTexCoords],
2679ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com                                          bool bindColorOut,
2689ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com                                          bool bindDualSrcOut);
2699ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
270dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    // Sets the texture units for samplers
271dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    void initSamplerUniforms();
2729ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
273ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    bool compileShaders(const GrGLShaderBuilder& builder);
2749ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
2759ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    const char* adjustInColor(const SkString& inColor) const;
2769196130af83782fcac4334117142475a837dd74dbsalomon@google.com
277dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    struct StageUniforms {
278dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        UniformHandle fTextureMatrixUni;
2790982d35187da7e1ed6c0eba5951bbdadca8b33e7bsalomon@google.com        SkTArray<UniformHandle, true> fSamplerUniforms;
280dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        StageUniforms() {
281dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com            fTextureMatrixUni = GrGLUniformManager::kInvalidUniformHandle;
2829196130af83782fcac4334117142475a837dd74dbsalomon@google.com        }
283f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com    };
284f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
285dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    struct Uniforms {
286dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        UniformHandle fViewMatrixUni;
287dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        UniformHandle fColorUni;
288dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        UniformHandle fCoverageUni;
289dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        UniformHandle fColorFilterUni;
290dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        UniformHandle fColorMatrixUni;
291dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        UniformHandle fColorMatrixVecUni;
292dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        StageUniforms fStages[GrDrawState::kNumStages];
293dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com        Uniforms() {
294dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com            fViewMatrixUni = GrGLUniformManager::kInvalidUniformHandle;
295dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com            fColorUni = GrGLUniformManager::kInvalidUniformHandle;
296dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com            fCoverageUni = GrGLUniformManager::kInvalidUniformHandle;
297dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com            fColorFilterUni = GrGLUniformManager::kInvalidUniformHandle;
298dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com            fColorMatrixUni = GrGLUniformManager::kInvalidUniformHandle;
299dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com            fColorMatrixVecUni = GrGLUniformManager::kInvalidUniformHandle;
3009196130af83782fcac4334117142475a837dd74dbsalomon@google.com        }
301f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com    };
302f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
3039ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    // IDs
3049ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrGLuint    fVShaderID;
3059ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrGLuint    fGShaderID;
3069ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrGLuint    fFShaderID;
3079ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrGLuint    fProgramID;
3089ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
3099ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    // The matrix sent to GL is determined by both the client's matrix and
3109ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    // the size of the viewport.
3119ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrMatrix  fViewMatrix;
3129ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    SkISize   fViewportSize;
3139ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
3149ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    // these reflect the current values of uniforms
3159ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    // (GL uniform values travel with program)
3169ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrColor                     fColor;
3179ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrColor                     fCoverage;
3189ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrColor                     fColorFilterColor;
3192f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    /// When it is sent to GL, the texture matrix will be flipped if the texture orientation
3202f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    /// (below) requires.
3219ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrMatrix                    fTextureMatrices[GrDrawState::kNumStages];
3229ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrGLTexture::Orientation    fTextureOrientation[GrDrawState::kNumStages];
3239ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
3249ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    GrGLProgramStage*           fProgramStage[GrDrawState::kNumStages];
3259ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
3269ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    Desc fDesc;
327ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com    const GrGLContextInfo&      fContextInfo;
3289ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
329dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    GrGLUniformManager          fUniformManager;
330dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    Uniforms                    fUniforms;
331dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com
3329ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    friend class GrGpuGL; // TODO: remove this by adding getters and moving functionality.
3339ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com
3349ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    typedef GrRefCnt INHERITED;
335f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com};
336f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
337f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#endif
338