| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 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" | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 21 | #include "GrStringBuilder.h" | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 22 | #include "GrDrawTarget.h" | 
 | 23 |  | 
| Scroggo | 97c88c2 | 2011-05-11 14:05:25 +0000 | [diff] [blame] | 24 | #include "SkXfermode.h" | 
 | 25 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 26 | class GrBinHashKeyBuilder; | 
| junov@google.com | d31cbc4 | 2011-05-17 17:01:17 +0000 | [diff] [blame^] | 27 |  | 
 | 28 | struct ShaderCodeSegments { | 
 | 29 |     GrStringBuilder fVSUnis; | 
 | 30 |     GrStringBuilder fVSAttrs; | 
 | 31 |     GrStringBuilder fVaryings; | 
 | 32 |     GrStringBuilder fFSUnis; | 
 | 33 |     GrStringBuilder fVSCode; | 
 | 34 |     GrStringBuilder fFSCode; | 
 | 35 | }; | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 36 |  | 
 | 37 | /** | 
 | 38 |  * This class manages a GPU program and records per-program information. | 
 | 39 |  * We can specify the attribute locations so that they are constant | 
 | 40 |  * across our shaders. But the driver determines the uniform locations | 
 | 41 |  * at link time. We don't need to remember the sampler uniform location | 
 | 42 |  * because we will bind a texture slot to it and never change it | 
 | 43 |  * Uniforms are program-local so we can't rely on fHWState to hold the | 
 | 44 |  * previous uniform state after a program change. | 
 | 45 |  */ | 
 | 46 | class GrGLProgram { | 
 | 47 | public: | 
 | 48 |     class CachedData; | 
 | 49 |  | 
 | 50 |     GrGLProgram(); | 
 | 51 |     ~GrGLProgram(); | 
 | 52 |  | 
 | 53 |     /** | 
 | 54 |      *  Streams data that can uniquely identifies the generated | 
 | 55 |      *  gpu program into a key, for cache indexing purposes. | 
 | 56 |      * | 
 | 57 |      *  @param key The key object to receive the key data | 
 | 58 |      */ | 
 | 59 |     void buildKey(GrBinHashKeyBuilder& key) const; | 
 | 60 |  | 
 | 61 |     /** | 
 | 62 |      *  This is the heavy initilization routine for building a GLProgram. | 
 | 63 |      *  The result of heavy init is not stored in datamembers of GrGLProgam, | 
 | 64 |      *  but in a separate cacheable container. | 
 | 65 |      */ | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 66 |     bool genProgram(CachedData* programData) const; | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 67 |  | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 68 |     static int PositionAttributeIdx() { return 0; } | 
 | 69 |     static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; } | 
 | 70 |     static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; } | 
 | 71 |     static int ViewMatrixAttributeIdx() {  | 
 | 72 |         return 2 + GrDrawTarget::kMaxTexCoords;  | 
 | 73 |     } | 
 | 74 |     static int TextureMatrixAttributeIdx(int stage) {  | 
 | 75 |         return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;  | 
 | 76 |     } | 
 | 77 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 78 | private: | 
 | 79 |  | 
 | 80 |     //Parameters that affect code generation | 
 | 81 |     struct ProgramDesc { | 
| bsalomon@google.com | 4be283f | 2011-04-19 21:15:09 +0000 | [diff] [blame] | 82 |         ProgramDesc() { | 
 | 83 |             // since we use this as part of a key we can't have any unitialized | 
 | 84 |             // padding | 
 | 85 |             memset(this, 0, sizeof(ProgramDesc)); | 
 | 86 |         } | 
 | 87 |  | 
 | 88 |         // stripped of bits that don't affect prog generation | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 89 |         GrVertexLayout fVertexLayout; | 
 | 90 |  | 
 | 91 |         enum { | 
| bsalomon@google.com | 4be283f | 2011-04-19 21:15:09 +0000 | [diff] [blame] | 92 |             kNone_ColorType         = 0, | 
 | 93 |             kAttribute_ColorType    = 1, | 
 | 94 |             kUniform_ColorType      = 2, | 
 | 95 |         } fColorType; | 
 | 96 |  | 
| bsalomon@google.com | f2d9155 | 2011-05-16 20:56:06 +0000 | [diff] [blame] | 97 |         int  fFirstCoverageStage; | 
| bsalomon@google.com | 4be283f | 2011-04-19 21:15:09 +0000 | [diff] [blame] | 98 |         bool fEmitsPointSize; | 
| senorblanco@chromium.org | 92e0f22 | 2011-05-12 15:49:15 +0000 | [diff] [blame] | 99 |         bool fUsesEdgeAA; | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 100 |  | 
| Scroggo | 97c88c2 | 2011-05-11 14:05:25 +0000 | [diff] [blame] | 101 |         SkXfermode::Mode fColorFilterXfermode; | 
 | 102 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 103 |         struct StageDesc { | 
 | 104 |             enum OptFlagBits { | 
| junov@google.com | 6acc9b3 | 2011-05-16 18:32:07 +0000 | [diff] [blame] | 105 |                 kNoPerspective_OptFlagBit       = 1 << 0, | 
 | 106 |                 kIdentityMatrix_OptFlagBit      = 1 << 1, | 
 | 107 |                 kCustomTextureDomain_OptFlagBit = 1 << 2 | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 108 |             }; | 
 | 109 |  | 
| bsalomon@google.com | 6aef1fb | 2011-05-05 12:33:22 +0000 | [diff] [blame] | 110 |             unsigned fOptFlags; | 
 | 111 |             bool fEnabled; | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 112 |  | 
 | 113 |             enum Modulation { | 
 | 114 |                 kColor_Modulation, | 
 | 115 |                 kAlpha_Modulation | 
| bsalomon@google.com | 6aef1fb | 2011-05-05 12:33:22 +0000 | [diff] [blame] | 116 |             } fModulation; | 
 | 117 |  | 
 | 118 |             enum FetchMode { | 
 | 119 |                 kSingle_FetchMode, | 
 | 120 |                 k2x2_FetchMode | 
 | 121 |             } fFetchMode; | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 122 |  | 
 | 123 |             enum CoordMapping { | 
 | 124 |                 kIdentity_CoordMapping, | 
 | 125 |                 kRadialGradient_CoordMapping, | 
 | 126 |                 kSweepGradient_CoordMapping, | 
 | 127 |                 kRadial2Gradient_CoordMapping | 
| bsalomon@google.com | 6aef1fb | 2011-05-05 12:33:22 +0000 | [diff] [blame] | 128 |             } fCoordMapping; | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 129 |         } fStages[GrDrawTarget::kNumStages]; | 
 | 130 |     } fProgramDesc; | 
 | 131 |  | 
| bsalomon@google.com | 4be283f | 2011-04-19 21:15:09 +0000 | [diff] [blame] | 132 |     const ProgramDesc& getDesc() { return fProgramDesc; } | 
 | 133 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 134 | public: | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 135 |     enum { | 
 | 136 |         kUnusedUniform = -1, | 
 | 137 |         kSetAsAttribute = 1000, | 
 | 138 |     }; | 
 | 139 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 140 |     struct StageUniLocations { | 
 | 141 |         GrGLint fTextureMatrixUni; | 
| bsalomon@google.com | 6aef1fb | 2011-05-05 12:33:22 +0000 | [diff] [blame] | 142 |         GrGLint fNormalizedTexelSizeUni; | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 143 |         GrGLint fSamplerUni; | 
 | 144 |         GrGLint fRadial2Uni; | 
| junov@google.com | 6acc9b3 | 2011-05-16 18:32:07 +0000 | [diff] [blame] | 145 |         GrGLint fTexDomUni; | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 146 |         void reset() { | 
 | 147 |             fTextureMatrixUni = kUnusedUniform; | 
 | 148 |             fNormalizedTexelSizeUni = kUnusedUniform; | 
 | 149 |             fSamplerUni = kUnusedUniform; | 
 | 150 |             fRadial2Uni = kUnusedUniform; | 
| junov@google.com | 6acc9b3 | 2011-05-16 18:32:07 +0000 | [diff] [blame] | 151 |             fTexDomUni = kUnusedUniform; | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 152 |         } | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 153 |     }; | 
 | 154 |  | 
 | 155 |     struct UniLocations { | 
 | 156 |         GrGLint fViewMatrixUni; | 
| bsalomon@google.com | 4be283f | 2011-04-19 21:15:09 +0000 | [diff] [blame] | 157 |         GrGLint fColorUni; | 
| senorblanco@chromium.org | 92e0f22 | 2011-05-12 15:49:15 +0000 | [diff] [blame] | 158 |         GrGLint fEdgesUni; | 
| Scroggo | 97c88c2 | 2011-05-11 14:05:25 +0000 | [diff] [blame] | 159 |         GrGLint fColorFilterUni; | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 160 |         StageUniLocations fStages[GrDrawTarget::kNumStages]; | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 161 |         void reset() { | 
 | 162 |             fViewMatrixUni = kUnusedUniform; | 
 | 163 |             fColorUni = kUnusedUniform; | 
| senorblanco@chromium.org | 92e0f22 | 2011-05-12 15:49:15 +0000 | [diff] [blame] | 164 |             fEdgesUni = kUnusedUniform; | 
| Scroggo | 97c88c2 | 2011-05-11 14:05:25 +0000 | [diff] [blame] | 165 |             fColorFilterUni = kUnusedUniform; | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 166 |             for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { | 
 | 167 |                 fStages[s].reset(); | 
 | 168 |             } | 
 | 169 |         } | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 170 |     }; | 
 | 171 |  | 
 | 172 |     class CachedData : public ::GrNoncopyable { | 
 | 173 |     public: | 
 | 174 |         CachedData() { | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 175 |         } | 
 | 176 |  | 
 | 177 |         ~CachedData() { | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 178 |         } | 
 | 179 |  | 
 | 180 |         void copyAndTakeOwnership(CachedData& other) { | 
| bsalomon@google.com | 2d9ddf9 | 2011-05-11 16:52:59 +0000 | [diff] [blame] | 181 |             memcpy(this, &other, sizeof(*this)); | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 182 |         } | 
 | 183 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 184 |  | 
 | 185 |     public: | 
 | 186 |  | 
 | 187 |         // IDs | 
 | 188 |         GrGLuint    fVShaderID; | 
 | 189 |         GrGLuint    fFShaderID; | 
 | 190 |         GrGLuint    fProgramID; | 
 | 191 |         // shader uniform locations (-1 if shader doesn't use them) | 
 | 192 |         UniLocations fUniLocations; | 
 | 193 |  | 
 | 194 |         GrMatrix  fViewMatrix; | 
 | 195 |  | 
 | 196 |         // these reflect the current values of uniforms | 
 | 197 |         // (GL uniform values travel with program) | 
| bsalomon@google.com | 4be283f | 2011-04-19 21:15:09 +0000 | [diff] [blame] | 198 |         GrColor                     fColor; | 
| Scroggo | 97c88c2 | 2011-05-11 14:05:25 +0000 | [diff] [blame] | 199 |         GrColor                     fColorFilterColor; | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 200 |         GrMatrix                    fTextureMatrices[GrDrawTarget::kNumStages]; | 
| bsalomon@google.com | 6aef1fb | 2011-05-05 12:33:22 +0000 | [diff] [blame] | 201 |         // width and height used for normalized texel size | 
 | 202 |         int                         fTextureWidth[GrDrawTarget::kNumStages]; | 
 | 203 |         int                         fTextureHeight[GrDrawTarget::kNumStages];  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 204 |         GrScalar                    fRadial2CenterX1[GrDrawTarget::kNumStages]; | 
 | 205 |         GrScalar                    fRadial2Radius0[GrDrawTarget::kNumStages]; | 
 | 206 |         bool                        fRadial2PosRoot[GrDrawTarget::kNumStages]; | 
 | 207 |  | 
 | 208 |     private: | 
 | 209 |         enum Constants { | 
 | 210 |             kUniLocationPreAllocSize = 8 | 
 | 211 |         }; | 
 | 212 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 213 |     }; // CachedData | 
 | 214 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 215 | private: | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 216 |     enum { | 
 | 217 |         kUseUniform = 2000 | 
 | 218 |     }; | 
 | 219 |  | 
 | 220 |     // should set all fields in locations var to kUseUniform if the | 
 | 221 |     // corresponding uniform is required for the program. | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 222 |     void genStageCode(int stageNum, | 
 | 223 |                       const ProgramDesc::StageDesc& desc, | 
 | 224 |                       const char* fsInColor, // NULL means no incoming color | 
 | 225 |                       const char* fsOutColor, | 
 | 226 |                       const char* vsInCoord, | 
 | 227 |                       ShaderCodeSegments* segments, | 
 | 228 |                       StageUniLocations* locations) const; | 
 | 229 |  | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 230 |     static bool CompileFSAndVS(const ShaderCodeSegments& segments,  | 
 | 231 |                                CachedData* programData); | 
 | 232 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 233 |     // Compiles a GL shader, returns shader ID or 0 if failed | 
 | 234 |     // params have same meaning as glShaderSource | 
 | 235 |     static GrGLuint CompileShader(GrGLenum type, int stringCnt, | 
 | 236 |                                   const char** strings, | 
 | 237 |                                   int* stringLengths); | 
 | 238 |  | 
| bsalomon@google.com | 9196130 | 2011-05-09 18:39:58 +0000 | [diff] [blame] | 239 |     // Creates a GL program ID, binds shader attributes to GL vertex attrs, and | 
 | 240 |     // links the program | 
 | 241 |     bool bindAttribsAndLinkProgram(GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords], | 
 | 242 |                                    CachedData* programData) const; | 
 | 243 |  | 
 | 244 |     // Gets locations for all uniforms set to kUseUniform and initializes cache | 
 | 245 |     // to invalid values. | 
 | 246 |     void getUniformLocationsAndInitCache(CachedData* programData) const; | 
 | 247 |  | 
| junov@google.com | f93e717 | 2011-03-31 21:26:24 +0000 | [diff] [blame] | 248 |     friend class GrGpuGLShaders; | 
 | 249 | }; | 
 | 250 |  | 
 | 251 | #endif |