Home | History | Annotate | Download | only in gl
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 
      9 #ifndef GrGLProgram_DEFINED
     10 #define GrGLProgram_DEFINED
     11 
     12 #include "GrDrawState.h"
     13 #include "GrGLContext.h"
     14 #include "GrGLProgramDesc.h"
     15 #include "GrGLSL.h"
     16 #include "GrGLTexture.h"
     17 #include "GrGLUniformManager.h"
     18 
     19 #include "SkString.h"
     20 #include "SkXfermode.h"
     21 
     22 class GrBinHashKeyBuilder;
     23 class GrGLEffect;
     24 class GrGLShaderBuilder;
     25 
     26 /**
     27  * This class manages a GPU program and records per-program information.
     28  * We can specify the attribute locations so that they are constant
     29  * across our shaders. But the driver determines the uniform locations
     30  * at link time. We don't need to remember the sampler uniform location
     31  * because we will bind a texture slot to it and never change it
     32  * Uniforms are program-local so we can't rely on fHWState to hold the
     33  * previous uniform state after a program change.
     34  */
     35 class GrGLProgram : public GrRefCnt {
     36 public:
     37     SK_DECLARE_INST_COUNT(GrGLProgram)
     38 
     39     static GrGLProgram* Create(const GrGLContext& gl,
     40                                const GrGLProgramDesc& desc,
     41                                const GrEffectStage* colorStages[],
     42                                const GrEffectStage* coverageStages[]);
     43 
     44     virtual ~GrGLProgram();
     45 
     46     /**
     47      * Call to abandon GL objects owned by this program.
     48      */
     49     void abandon();
     50 
     51     /**
     52      * The shader may modify the blend coefficients. Params are in/out.
     53      */
     54     void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
     55 
     56     const GrGLProgramDesc& getDesc() { return fDesc; }
     57 
     58     /**
     59      * Gets the GL program ID for this program.
     60      */
     61     GrGLuint programID() const { return fProgramID; }
     62 
     63     /**
     64      * Some GL state that is relevant to programs is not stored per-program. In particular color
     65      * and coverage attributes can be global state. This struct is read and updated by
     66      * GrGLProgram::setColor and GrGLProgram::setCoverage to allow us to avoid setting this state
     67      * redundantly.
     68      */
     69     struct SharedGLState {
     70         GrColor fConstAttribColor;
     71         int     fConstAttribColorIndex;
     72         GrColor fConstAttribCoverage;
     73         int     fConstAttribCoverageIndex;
     74 
     75         SharedGLState() { this->invalidate(); }
     76         void invalidate() {
     77             fConstAttribColor = GrColor_ILLEGAL;
     78             fConstAttribColorIndex = -1;
     79             fConstAttribCoverage = GrColor_ILLEGAL;
     80             fConstAttribCoverageIndex = -1;
     81         }
     82     };
     83 
     84     /**
     85      * The GrDrawState's view matrix along with the aspects of the render target determine the
     86      * matrix sent to GL. The size of the render target affects the GL matrix because we must
     87      * convert from Skia device coords to GL's normalized coords. Also the origin of the render
     88      * target may require us to perform a mirror-flip.
     89      */
     90     struct MatrixState {
     91         SkMatrix        fViewMatrix;
     92         SkISize         fRenderTargetSize;
     93         GrSurfaceOrigin fRenderTargetOrigin;
     94 
     95         MatrixState() { this->invalidate(); }
     96         void invalidate() {
     97             fViewMatrix = SkMatrix::InvalidMatrix();
     98             fRenderTargetSize.fWidth = -1;
     99             fRenderTargetSize.fHeight = -1;
    100             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
    101         }
    102     };
    103 
    104     /**
    105      * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a
    106      * draw occurs using the program after the program has already been bound. It also uses the
    107      * GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage
    108      * stages come from GrGLProgramDesc::Build().
    109      */
    110     void setData(GrGpuGL*,
    111                  GrDrawState::BlendOptFlags,
    112                  const GrEffectStage* colorStages[],
    113                  const GrEffectStage* coverageStages[],
    114                  const GrDeviceCoordTexture* dstCopy, // can be NULL
    115                  SharedGLState*);
    116 
    117 private:
    118     typedef GrGLUniformManager::UniformHandle UniformHandle;
    119 
    120     // handles for uniforms (aside from per-effect samplers)
    121     struct UniformHandles {
    122         UniformHandle       fViewMatrixUni;
    123         UniformHandle       fColorUni;
    124         UniformHandle       fCoverageUni;
    125         UniformHandle       fColorFilterUni;
    126 
    127         // We use the render target height to provide a y-down frag coord when specifying
    128         // origin_upper_left is not supported.
    129         UniformHandle       fRTHeightUni;
    130 
    131         // Uniforms for computing texture coords to do the dst-copy lookup
    132         UniformHandle       fDstCopyTopLeftUni;
    133         UniformHandle       fDstCopyScaleUni;
    134         UniformHandle       fDstCopySamplerUni;
    135 
    136         UniformHandles() {
    137             fViewMatrixUni = GrGLUniformManager::kInvalidUniformHandle;
    138             fColorUni = GrGLUniformManager::kInvalidUniformHandle;
    139             fCoverageUni = GrGLUniformManager::kInvalidUniformHandle;
    140             fColorFilterUni = GrGLUniformManager::kInvalidUniformHandle;
    141             fRTHeightUni = GrGLUniformManager::kInvalidUniformHandle;
    142             fDstCopyTopLeftUni = GrGLUniformManager::kInvalidUniformHandle;
    143             fDstCopyScaleUni = GrGLUniformManager::kInvalidUniformHandle;
    144             fDstCopySamplerUni = GrGLUniformManager::kInvalidUniformHandle;
    145         }
    146     };
    147 
    148     typedef SkSTArray<4, UniformHandle, true> SamplerUniSArray;
    149     typedef SkSTArray<4, int, true> TextureUnitSArray;
    150 
    151     struct EffectAndSamplers {
    152         EffectAndSamplers() : fGLEffect(NULL) {}
    153         ~EffectAndSamplers() { delete fGLEffect; }
    154         GrGLEffect*         fGLEffect;
    155         SamplerUniSArray    fSamplerUnis;  // sampler uni handles for effect's GrTextureAccess
    156         TextureUnitSArray   fTextureUnits; // texture unit used for each entry of fSamplerUnis
    157     };
    158 
    159     GrGLProgram(const GrGLContext& gl,
    160                 const GrGLProgramDesc& desc,
    161                 const GrEffectStage* colorStages[],
    162                 const GrEffectStage* coverageStages[]);
    163 
    164     bool succeeded() const { return 0 != fProgramID; }
    165 
    166     /**
    167      * This is the heavy initialization routine for building a GLProgram. colorStages and
    168      * coverageStages correspond to the output of GrGLProgramDesc::Build().
    169      */
    170     bool genProgram(const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[]);
    171 
    172     GrSLConstantVec genInputColor(GrGLShaderBuilder* builder, SkString* inColor);
    173 
    174     GrSLConstantVec genInputCoverage(GrGLShaderBuilder* builder, SkString* inCoverage);
    175 
    176     void genGeometryShader(GrGLShaderBuilder* segments) const;
    177 
    178     // Creates a GL program ID, binds shader attributes to GL vertex attrs, and links the program
    179     bool bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder,
    180                                           bool bindColorOut,
    181                                           bool bindDualSrcOut);
    182 
    183     // Sets the texture units for samplers
    184     void initSamplerUniforms();
    185     void initEffectSamplerUniforms(EffectAndSamplers* effect, int* texUnitIdx);
    186 
    187     bool compileShaders(const GrGLShaderBuilder& builder);
    188 
    189     const char* adjustInColor(const SkString& inColor) const;
    190 
    191     // Helper for setData().
    192     void setEffectData(GrGpuGL* gpu, const GrEffectStage& stage, const EffectAndSamplers& effect);
    193 
    194     // Helper for setData(). Makes GL calls to specify the initial color when there is not
    195     // per-vertex colors.
    196     void setColor(const GrDrawState&, GrColor color, SharedGLState*);
    197 
    198     // Helper for setData(). Makes GL calls to specify the initial coverage when there is not
    199     // per-vertex coverages.
    200     void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*);
    201 
    202     // Helper for setData() that sets the view matrix and loads the render target height uniform
    203     void setMatrixAndRenderTargetHeight(const GrDrawState&);
    204 
    205     // GL IDs
    206     GrGLuint                    fVShaderID;
    207     GrGLuint                    fGShaderID;
    208     GrGLuint                    fFShaderID;
    209     GrGLuint                    fProgramID;
    210 
    211     // these reflect the current values of uniforms (GL uniform values travel with program)
    212     MatrixState                 fMatrixState;
    213     GrColor                     fColor;
    214     GrColor                     fCoverage;
    215     GrColor                     fColorFilterColor;
    216     int                         fDstCopyTexUnit;
    217 
    218     SkTArray<EffectAndSamplers> fColorEffects;
    219     SkTArray<EffectAndSamplers> fCoverageEffects;
    220 
    221     GrGLProgramDesc             fDesc;
    222     const GrGLContext&          fContext;
    223 
    224     GrGLUniformManager          fUniformManager;
    225     UniformHandles              fUniformHandles;
    226 
    227     typedef GrRefCnt INHERITED;
    228 };
    229 
    230 #endif
    231