GrGLProgram.h revision dd182cbca60a7f0003330c01dfc64f69f56aea90
1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10#ifndef GrGLProgram_DEFINED 11#define GrGLProgram_DEFINED 12 13#include "../GrDrawState.h" 14#include "GrGLInterface.h" 15#include "GrGLSL.h" 16#include "../GrStringBuilder.h" 17#include "../GrGpu.h" 18 19#include "SkXfermode.h" 20 21class GrBinHashKeyBuilder; 22 23struct ShaderCodeSegments; 24 25// optionally compile the experimental GS code. Set to GR_DEBUG 26// so that debug build bots will execute the code. 27#define GR_GL_EXPERIMENTAL_GS GR_DEBUG 28 29/** 30 * This class manages a GPU program and records per-program information. 31 * We can specify the attribute locations so that they are constant 32 * across our shaders. But the driver determines the uniform locations 33 * at link time. We don't need to remember the sampler uniform location 34 * because we will bind a texture slot to it and never change it 35 * Uniforms are program-local so we can't rely on fHWState to hold the 36 * previous uniform state after a program change. 37 */ 38class GrGLProgram { 39public: 40 41 class CachedData; 42 43 GrGLProgram(); 44 ~GrGLProgram(); 45 46 /** 47 * This is the heavy initilization routine for building a GLProgram. 48 * The result of heavy init is not stored in datamembers of GrGLProgam, 49 * but in a separate cacheable container. 50 */ 51 bool genProgram(const GrGLInterface* gl, 52 GrGLSLGeneration glslVersion, 53 CachedData* programData) const; 54 55 /** 56 * The shader may modify the blend coeffecients. Params are in/out 57 */ 58 void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const; 59 60 /** 61 * Attribute indices. These should not overlap. Matrices consume 3 slots. 62 */ 63 static int PositionAttributeIdx() { return 0; } 64 static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; } 65 static int ColorAttributeIdx() { return 1 + GrDrawState::kMaxTexCoords; } 66 static int CoverageAttributeIdx() { 67 return 2 + GrDrawState::kMaxTexCoords; 68 } 69 static int EdgeAttributeIdx() { return 3 + GrDrawState::kMaxTexCoords; } 70 71 static int ViewMatrixAttributeIdx() { 72 return 4 + GrDrawState::kMaxTexCoords; 73 } 74 static int TextureMatrixAttributeIdx(int stage) { 75 return 7 + GrDrawState::kMaxTexCoords + 3 * stage; 76 } 77 78public: 79 80 // Parameters that affect code generation 81 // These structs should be kept compact; they are the input to an 82 // expensive hash key generator. 83 struct ProgramDesc { 84 ProgramDesc() { 85 // since we use this as part of a key we can't have any unitialized 86 // padding 87 memset(this, 0, sizeof(ProgramDesc)); 88 } 89 90 enum OutputPM { 91 // PM-color OR color with no alpha channel 92 kYes_OutputPM, 93 // nonPM-color with alpha channel 94 kNo_OutputPM, 95 96 kOutputPMCnt 97 }; 98 99 struct StageDesc { 100 enum OptFlagBits { 101 kNoPerspective_OptFlagBit = 1 << 0, 102 kIdentityMatrix_OptFlagBit = 1 << 1, 103 kCustomTextureDomain_OptFlagBit = 1 << 2, 104 kIsEnabled_OptFlagBit = 1 << 7 105 }; 106 enum FetchMode { 107 kSingle_FetchMode, 108 k2x2_FetchMode, 109 kConvolution_FetchMode, 110 111 kFetchModeCnt, 112 }; 113 /** 114 Flags set based on a src texture's pixel config. The operations 115 described are performed after reading a texel. 116 */ 117 enum InConfigFlags { 118 kNone_InConfigFlag = 0x0, 119 120 /** 121 Swap the R and B channels. This is incompatible with 122 kSmearAlpha. It is prefereable to perform the swizzle outside 123 the shader using GL_ARB_texture_swizzle if possible rather 124 than setting this flag. 125 */ 126 kSwapRAndB_InConfigFlag = 0x1, 127 128 /** 129 Smear alpha across all four channels. This is incompatible with 130 kSwapRAndB and kPremul. It is prefereable to perform the 131 smear outside the shader using GL_ARB_texture_swizzle if 132 possible rather than setting this flag. 133 */ 134 kSmearAlpha_InConfigFlag = 0x2, 135 136 /** 137 Multiply r,g,b by a after texture reads. This flag incompatible 138 with kSmearAlpha and may only be used with FetchMode kSingle. 139 */ 140 kMulRGBByAlpha_InConfigFlag = 0x4, 141 142 kDummyInConfigFlag, 143 kInConfigBitMask = (kDummyInConfigFlag-1) | 144 (kDummyInConfigFlag-2) 145 }; 146 enum CoordMapping { 147 kIdentity_CoordMapping, 148 kRadialGradient_CoordMapping, 149 kSweepGradient_CoordMapping, 150 kRadial2Gradient_CoordMapping, 151 // need different shader computation when quadratic 152 // eq describing the gradient degenerates to a linear eq. 153 kRadial2GradientDegenerate_CoordMapping, 154 kCoordMappingCnt 155 }; 156 157 uint8_t fOptFlags; 158 uint8_t fInConfigFlags; // bitfield of InConfigFlags values 159 uint8_t fFetchMode; // casts to enum FetchMode 160 uint8_t fCoordMapping; // casts to enum CoordMapping 161 uint8_t fKernelWidth; 162 163 GR_STATIC_ASSERT((InConfigFlags)(uint8_t)kInConfigBitMask == 164 kInConfigBitMask); 165 166 inline bool isEnabled() const { 167 return SkToBool(fOptFlags & kIsEnabled_OptFlagBit); 168 } 169 inline void setEnabled(bool newValue) { 170 if (newValue) { 171 fOptFlags |= kIsEnabled_OptFlagBit; 172 } else { 173 fOptFlags &= ~kIsEnabled_OptFlagBit; 174 } 175 } 176 }; 177 178 // Specifies where the intitial color comes from before the stages are 179 // applied. 180 enum ColorInput { 181 kSolidWhite_ColorInput, 182 kTransBlack_ColorInput, 183 kAttribute_ColorInput, 184 kUniform_ColorInput, 185 186 kColorInputCnt 187 }; 188 // Dual-src blending makes use of a secondary output color that can be 189 // used as a per-pixel blend coeffecient. This controls whether a 190 // secondary source is output and what value it holds. 191 enum DualSrcOutput { 192 kNone_DualSrcOutput, 193 kCoverage_DualSrcOutput, 194 kCoverageISA_DualSrcOutput, 195 kCoverageISC_DualSrcOutput, 196 197 kDualSrcOutputCnt 198 }; 199 200 GrDrawState::VertexEdgeType fVertexEdgeType; 201 202 // stripped of bits that don't affect prog generation 203 GrVertexLayout fVertexLayout; 204 205 StageDesc fStages[GrDrawState::kNumStages]; 206 207 // To enable experimental geometry shader code (not for use in 208 // production) 209#if GR_GL_EXPERIMENTAL_GS 210 bool fExperimentalGS; 211#endif 212 213 uint8_t fColorInput; // casts to enum ColorInput 214 uint8_t fCoverageInput; // casts to enum CoverageInput 215 uint8_t fOutputPM; // cases to enum OutputPM 216 uint8_t fDualSrcOutput; // casts to enum DualSrcOutput 217 int8_t fFirstCoverageStage; 218 SkBool8 fEmitsPointSize; 219 SkBool8 fEdgeAAConcave; 220 SkBool8 fColorMatrixEnabled; 221 222 int8_t fEdgeAANumEdges; 223 uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode 224 int8_t fPadding[3]; 225 226 } fProgramDesc; 227 GR_STATIC_ASSERT(!(sizeof(ProgramDesc) % 4)); 228 229 // for code readability 230 typedef ProgramDesc::StageDesc StageDesc; 231 232private: 233 234 const ProgramDesc& getDesc() { return fProgramDesc; } 235 const char* adjustInColor(const GrStringBuilder& inColor) const; 236 237public: 238 enum { 239 kUnusedUniform = -1, 240 kSetAsAttribute = 1000, 241 }; 242 243 struct StageUniLocations { 244 GrGLint fTextureMatrixUni; 245 GrGLint fNormalizedTexelSizeUni; 246 GrGLint fSamplerUni; 247 GrGLint fRadial2Uni; 248 GrGLint fTexDomUni; 249 GrGLint fKernelUni; 250 GrGLint fImageIncrementUni; 251 void reset() { 252 fTextureMatrixUni = kUnusedUniform; 253 fNormalizedTexelSizeUni = kUnusedUniform; 254 fSamplerUni = kUnusedUniform; 255 fRadial2Uni = kUnusedUniform; 256 fTexDomUni = kUnusedUniform; 257 fKernelUni = kUnusedUniform; 258 fImageIncrementUni = kUnusedUniform; 259 } 260 }; 261 262 struct UniLocations { 263 GrGLint fViewMatrixUni; 264 GrGLint fColorUni; 265 GrGLint fCoverageUni; 266 GrGLint fEdgesUni; 267 GrGLint fColorFilterUni; 268 GrGLint fColorMatrixUni; 269 GrGLint fColorMatrixVecUni; 270 StageUniLocations fStages[GrDrawState::kNumStages]; 271 void reset() { 272 fViewMatrixUni = kUnusedUniform; 273 fColorUni = kUnusedUniform; 274 fCoverageUni = kUnusedUniform; 275 fEdgesUni = kUnusedUniform; 276 fColorFilterUni = kUnusedUniform; 277 fColorMatrixUni = kUnusedUniform; 278 fColorMatrixVecUni = kUnusedUniform; 279 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 280 fStages[s].reset(); 281 } 282 } 283 }; 284 285 class CachedData : public ::GrNoncopyable { 286 public: 287 CachedData() { 288 } 289 290 ~CachedData() { 291 } 292 293 void copyAndTakeOwnership(CachedData& other) { 294 memcpy(this, &other, sizeof(*this)); 295 } 296 297 public: 298 299 // IDs 300 GrGLuint fVShaderID; 301 GrGLuint fGShaderID; 302 GrGLuint fFShaderID; 303 GrGLuint fProgramID; 304 // shader uniform locations (-1 if shader doesn't use them) 305 UniLocations fUniLocations; 306 307 GrMatrix fViewMatrix; 308 309 // these reflect the current values of uniforms 310 // (GL uniform values travel with program) 311 GrColor fColor; 312 GrColor fCoverage; 313 GrColor fColorFilterColor; 314 GrMatrix fTextureMatrices[GrDrawState::kNumStages]; 315 // width and height used for normalized texel size 316 int fTextureWidth[GrDrawState::kNumStages]; 317 int fTextureHeight[GrDrawState::kNumStages]; 318 GrScalar fRadial2CenterX1[GrDrawState::kNumStages]; 319 GrScalar fRadial2Radius0[GrDrawState::kNumStages]; 320 bool fRadial2PosRoot[GrDrawState::kNumStages]; 321 GrRect fTextureDomain[GrDrawState::kNumStages]; 322 323 private: 324 enum Constants { 325 kUniLocationPreAllocSize = 8 326 }; 327 328 }; // CachedData 329 330 enum Constants { 331 kProgramKeySize = sizeof(ProgramDesc) 332 }; 333 334 // Provide an opaque ProgramDesc 335 const uint32_t* keyData() const{ 336 return reinterpret_cast<const uint32_t*>(&fProgramDesc); 337 } 338 339private: 340 341 // Determines which uniforms will need to be bound. 342 void genStageCode(const GrGLInterface* gl, 343 int stageNum, 344 const ProgramDesc::StageDesc& desc, 345 const char* fsInColor, // NULL means no incoming color 346 const char* fsOutColor, 347 const char* vsInCoord, 348 ShaderCodeSegments* segments, 349 StageUniLocations* locations) const; 350 351 void genGeometryShader(const GrGLInterface* gl, 352 GrGLSLGeneration glslVersion, 353 ShaderCodeSegments* segments) const; 354 355 // generates code to compute coverage based on edge AA. 356 void genEdgeCoverage(const GrGLInterface* gl, 357 GrVertexLayout layout, 358 CachedData* programData, 359 GrStringBuilder* coverageVar, 360 ShaderCodeSegments* segments) const; 361 362 static bool CompileShaders(const GrGLInterface* gl, 363 GrGLSLGeneration glslVersion, 364 const ShaderCodeSegments& segments, 365 CachedData* programData); 366 367 // Compiles a GL shader, returns shader ID or 0 if failed 368 // params have same meaning as glShaderSource 369 static GrGLuint CompileShader(const GrGLInterface* gl, 370 GrGLenum type, int stringCnt, 371 const char** strings, 372 int* stringLengths); 373 374 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and 375 // links the program 376 bool bindOutputsAttribsAndLinkProgram( 377 const GrGLInterface* gl, 378 GrStringBuilder texCoordAttrNames[GrDrawState::kMaxTexCoords], 379 bool bindColorOut, 380 bool bindDualSrcOut, 381 CachedData* programData) const; 382 383 // Binds uniforms; initializes cache to invalid values. 384 void getUniformLocationsAndInitCache(const GrGLInterface* gl, 385 CachedData* programData) const; 386 387 friend class GrGpuGLShaders; 388}; 389 390#endif 391