Home | History | Annotate | Download | only in src
      1 /*
      2     Copyright 2011 Google Inc.
      3 
      4     Licensed under the Apache License, Version 2.0 (the "License");
      5     you may not use this file except in compliance with the License.
      6     You may obtain a copy of the License at
      7 
      8          http://www.apache.org/licenses/LICENSE-2.0
      9 
     10     Unless required by applicable law or agreed to in writing, software
     11     distributed under the License is distributed on an "AS IS" BASIS,
     12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13     See the License for the specific language governing permissions and
     14     limitations under the License.
     15  */
     16 
     17 #ifndef GrGLProgram_DEFINED
     18 #define GrGLProgram_DEFINED
     19 
     20 #include "GrGLInterface.h"
     21 #include "GrStringBuilder.h"
     22 #include "GrGpu.h"
     23 
     24 #include "SkXfermode.h"
     25 
     26 class GrBinHashKeyBuilder;
     27 
     28 struct ShaderCodeSegments {
     29     GrStringBuilder fHeader; // VS+FS, GLSL version, etc
     30     GrStringBuilder fVSUnis;
     31     GrStringBuilder fVSAttrs;
     32     GrStringBuilder fVaryings;
     33     GrStringBuilder fFSUnis;
     34     GrStringBuilder fFSOutputs;
     35     GrStringBuilder fVSCode;
     36     GrStringBuilder fFSCode;
     37 };
     38 
     39 /**
     40  * This class manages a GPU program and records per-program information.
     41  * We can specify the attribute locations so that they are constant
     42  * across our shaders. But the driver determines the uniform locations
     43  * at link time. We don't need to remember the sampler uniform location
     44  * because we will bind a texture slot to it and never change it
     45  * Uniforms are program-local so we can't rely on fHWState to hold the
     46  * previous uniform state after a program change.
     47  */
     48 class GrGLProgram {
     49 public:
     50     class CachedData;
     51 
     52     GrGLProgram();
     53     ~GrGLProgram();
     54 
     55     /**
     56      *  Streams data that can uniquely identifies the generated
     57      *  gpu program into a key, for cache indexing purposes.
     58      *
     59      *  @param key The key object to receive the key data
     60      */
     61     void buildKey(GrBinHashKeyBuilder& key) const;
     62 
     63     /**
     64      *  This is the heavy initilization routine for building a GLProgram.
     65      *  The result of heavy init is not stored in datamembers of GrGLProgam,
     66      *  but in a separate cacheable container.
     67      */
     68     bool genProgram(CachedData* programData) const;
     69 
     70      /**
     71       * The shader may modify the blend coeffecients. Params are in/out
     72       */
     73      void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
     74 
     75     /**
     76      * Attribute indices
     77      */
     78     static int PositionAttributeIdx() { return 0; }
     79     static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
     80     static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; }
     81     static int ViewMatrixAttributeIdx() {
     82         return 2 + GrDrawTarget::kMaxTexCoords;
     83     }
     84     static int TextureMatrixAttributeIdx(int stage) {
     85         return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
     86     }
     87 
     88 private:
     89 
     90     // Parameters that affect code generation
     91     // These structs should be kept compact; they are the input to an
     92     // expensive hash key generator.
     93     struct ProgramDesc {
     94         ProgramDesc() {
     95             // since we use this as part of a key we can't have any unitialized
     96             // padding
     97             memset(this, 0, sizeof(ProgramDesc));
     98         }
     99 
    100         struct StageDesc {
    101             enum OptFlagBits {
    102                 kNoPerspective_OptFlagBit       = 1 << 0,
    103                 kIdentityMatrix_OptFlagBit      = 1 << 1,
    104                 kCustomTextureDomain_OptFlagBit = 1 << 2,
    105                 kIsEnabled_OptFlagBit           = 1 << 7
    106             };
    107             enum Modulation {
    108                 kColor_Modulation,
    109                 kAlpha_Modulation
    110             };
    111             enum FetchMode {
    112                 kSingle_FetchMode,
    113                 k2x2_FetchMode
    114             };
    115             enum CoordMapping {
    116                 kIdentity_CoordMapping,
    117                 kRadialGradient_CoordMapping,
    118                 kSweepGradient_CoordMapping,
    119                 kRadial2Gradient_CoordMapping
    120             };
    121 
    122             uint8_t fOptFlags;
    123             uint8_t fModulation;  // casts to enum Modulation
    124             uint8_t fFetchMode;  // casts to enum FetchMode
    125             uint8_t fCoordMapping;  // casts to enum CoordMapping
    126 
    127             inline bool isEnabled() const {
    128                 return fOptFlags & kIsEnabled_OptFlagBit;
    129             }
    130             inline void setEnabled(bool newValue) {
    131                 if (newValue) {
    132                     fOptFlags |= kIsEnabled_OptFlagBit;
    133                 } else {
    134                     fOptFlags &= ~kIsEnabled_OptFlagBit;
    135                 }
    136             }
    137         };
    138 
    139         enum ColorType {
    140             kNone_ColorType         = 0,
    141             kAttribute_ColorType    = 1,
    142             kUniform_ColorType      = 2,
    143         };
    144         // Dual-src blending makes use of a secondary output color that can be
    145         // used as a per-pixel blend coeffecient. This controls whether a
    146         // secondary source is output and what value it holds.
    147         enum DualSrcOutput {
    148             kNone_DualSrcOutput,
    149             kCoverage_DualSrcOutput,
    150             kCoverageISA_DualSrcOutput,
    151             kCoverageISC_DualSrcOutput,
    152             kDualSrcOutputCnt
    153         };
    154 
    155         // stripped of bits that don't affect prog generation
    156         GrVertexLayout fVertexLayout;
    157 
    158         StageDesc fStages[GrDrawTarget::kNumStages];
    159 
    160         uint8_t fColorType;  // casts to enum ColorType
    161         uint8_t fDualSrcOutput;  // casts to enum DualSrcOutput
    162         int8_t fFirstCoverageStage;
    163         SkBool8 fEmitsPointSize;
    164 
    165         int8_t fEdgeAANumEdges;
    166         uint8_t fColorFilterXfermode;  // casts to enum SkXfermode::Mode
    167 
    168         uint8_t fPadTo32bLengthMultiple [2];
    169 
    170     } fProgramDesc;
    171 
    172     const ProgramDesc& getDesc() { return fProgramDesc; }
    173 
    174 public:
    175     enum {
    176         kUnusedUniform = -1,
    177         kSetAsAttribute = 1000,
    178     };
    179 
    180     struct StageUniLocations {
    181         GrGLint fTextureMatrixUni;
    182         GrGLint fNormalizedTexelSizeUni;
    183         GrGLint fSamplerUni;
    184         GrGLint fRadial2Uni;
    185         GrGLint fTexDomUni;
    186         void reset() {
    187             fTextureMatrixUni = kUnusedUniform;
    188             fNormalizedTexelSizeUni = kUnusedUniform;
    189             fSamplerUni = kUnusedUniform;
    190             fRadial2Uni = kUnusedUniform;
    191             fTexDomUni = kUnusedUniform;
    192         }
    193     };
    194 
    195     struct UniLocations {
    196         GrGLint fViewMatrixUni;
    197         GrGLint fColorUni;
    198         GrGLint fEdgesUni;
    199         GrGLint fColorFilterUni;
    200         StageUniLocations fStages[GrDrawTarget::kNumStages];
    201         void reset() {
    202             fViewMatrixUni = kUnusedUniform;
    203             fColorUni = kUnusedUniform;
    204             fEdgesUni = kUnusedUniform;
    205             fColorFilterUni = kUnusedUniform;
    206             for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
    207                 fStages[s].reset();
    208             }
    209         }
    210     };
    211 
    212     class CachedData : public ::GrNoncopyable {
    213     public:
    214         CachedData() {
    215         }
    216 
    217         ~CachedData() {
    218         }
    219 
    220         void copyAndTakeOwnership(CachedData& other) {
    221             memcpy(this, &other, sizeof(*this));
    222         }
    223 
    224     public:
    225 
    226         // IDs
    227         GrGLuint    fVShaderID;
    228         GrGLuint    fFShaderID;
    229         GrGLuint    fProgramID;
    230         // shader uniform locations (-1 if shader doesn't use them)
    231         UniLocations fUniLocations;
    232 
    233         GrMatrix  fViewMatrix;
    234 
    235         // these reflect the current values of uniforms
    236         // (GL uniform values travel with program)
    237         GrColor                     fColor;
    238         GrColor                     fColorFilterColor;
    239         GrMatrix                    fTextureMatrices[GrDrawTarget::kNumStages];
    240         // width and height used for normalized texel size
    241         int                         fTextureWidth[GrDrawTarget::kNumStages];
    242         int                         fTextureHeight[GrDrawTarget::kNumStages];
    243         GrScalar                    fRadial2CenterX1[GrDrawTarget::kNumStages];
    244         GrScalar                    fRadial2Radius0[GrDrawTarget::kNumStages];
    245         bool                        fRadial2PosRoot[GrDrawTarget::kNumStages];
    246         GrRect                      fTextureDomain[GrDrawTarget::kNumStages];
    247 
    248     private:
    249         enum Constants {
    250             kUniLocationPreAllocSize = 8
    251         };
    252 
    253     }; // CachedData
    254 
    255 private:
    256     enum {
    257         kUseUniform = 2000
    258     };
    259 
    260     // should set all fields in locations var to kUseUniform if the
    261     // corresponding uniform is required for the program.
    262     void genStageCode(int stageNum,
    263                       const ProgramDesc::StageDesc& desc,
    264                       const char* fsInColor, // NULL means no incoming color
    265                       const char* fsOutColor,
    266                       const char* vsInCoord,
    267                       ShaderCodeSegments* segments,
    268                       StageUniLocations* locations) const;
    269 
    270     static bool CompileFSAndVS(const ShaderCodeSegments& segments,
    271                                CachedData* programData);
    272 
    273     // Compiles a GL shader, returns shader ID or 0 if failed
    274     // params have same meaning as glShaderSource
    275     static GrGLuint CompileShader(GrGLenum type, int stringCnt,
    276                                   const char** strings,
    277                                   int* stringLengths);
    278 
    279     // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
    280     // links the program
    281     bool bindOutputsAttribsAndLinkProgram(
    282                 GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
    283                 bool bindColorOut,
    284                 bool bindDualSrcOut,
    285                 CachedData* programData) const;
    286 
    287     // Gets locations for all uniforms set to kUseUniform and initializes cache
    288     // to invalid values.
    289     void getUniformLocationsAndInitCache(CachedData* programData) const;
    290 
    291     friend class GrGpuGLShaders;
    292 };
    293 
    294 #endif
    295