GrGLProgram.cpp revision ae81d5c4aa1716756b2cfb4c44f27f4dce2716ef
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#include "GrGLProgram.h" 9 10#include "GrAllocator.h" 11#include "GrEffect.h" 12#include "GrDrawEffect.h" 13#include "GrGLEffect.h" 14#include "GrGpuGL.h" 15#include "GrGLShaderVar.h" 16#include "GrBackendEffectFactory.h" 17#include "SkTrace.h" 18#include "SkXfermode.h" 19 20#include "SkRTConf.h" 21 22SK_DEFINE_INST_COUNT(GrGLProgram) 23 24#define GL_CALL(X) GR_GL_CALL(fContext.interface(), X) 25#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContext.interface(), R, X) 26 27SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, 28 "Print the source code for all shaders generated."); 29 30#define COL_ATTR_NAME "aColor" 31#define COV_ATTR_NAME "aCoverage" 32#define EDGE_ATTR_NAME "aEdge" 33 34namespace { 35inline const char* declared_color_output_name() { return "fsColorOut"; } 36inline const char* dual_source_output_name() { return "dualSourceOut"; } 37} 38 39const GrGLProgram::AttribLayout GrGLProgram::kAttribLayouts[kGrVertexAttribTypeCount] = { 40 {1, GR_GL_FLOAT, false}, // kFloat_GrVertexAttribType 41 {2, GR_GL_FLOAT, false}, // kVec2f_GrVertexAttribType 42 {3, GR_GL_FLOAT, false}, // kVec3f_GrVertexAttribType 43 {4, GR_GL_FLOAT, false}, // kVec4f_GrVertexAttribType 44 {4, GR_GL_UNSIGNED_BYTE, true}, // kVec4ub_GrVertexAttribType 45}; 46 47void GrGLProgram::BuildDesc(const GrDrawState& drawState, 48 bool isPoints, 49 GrDrawState::BlendOptFlags blendOpts, 50 GrBlendCoeff srcCoeff, 51 GrBlendCoeff dstCoeff, 52 const GrGpuGL* gpu, 53 Desc* desc) { 54 55 // This should already have been caught 56 GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); 57 58 bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag); 59 60 bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag | 61 GrDrawState::kEmitCoverage_BlendOptFlag)); 62 63 // The descriptor is used as a cache key. Thus when a field of the 64 // descriptor will not affect program generation (because of the attribute 65 // bindings in use or other descriptor field settings) it should be set 66 // to a canonical value to avoid duplicate programs with different keys. 67 68 // Must initialize all fields or cache will have false negatives! 69 desc->fAttribBindings = drawState.getAttribBindings(); 70 71 desc->fEmitsPointSize = isPoints; 72 73 bool requiresAttributeColors = 74 !skipColor && SkToBool(desc->fAttribBindings & GrDrawState::kColor_AttribBindingsBit); 75 bool requiresAttributeCoverage = 76 !skipCoverage && SkToBool(desc->fAttribBindings & GrDrawState::kCoverage_AttribBindingsBit); 77 78 // fColorInput/fCoverageInput records how colors are specified for the program So we strip the 79 // bits from the bindings to avoid false negatives when searching for an existing program in the 80 // cache. 81 desc->fAttribBindings &= 82 ~(GrDrawState::kColor_AttribBindingsBit | GrDrawState::kCoverage_AttribBindingsBit); 83 84 desc->fColorFilterXfermode = skipColor ? 85 SkXfermode::kDst_Mode : 86 drawState.getColorFilterMode(); 87 88 // no reason to do edge aa or look at per-vertex coverage if coverage is ignored 89 if (skipCoverage) { 90 desc->fAttribBindings &= ~(GrDrawState::kEdge_AttribBindingsBit | 91 GrDrawState::kCoverage_AttribBindingsBit); 92 } 93 94 bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag); 95 bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) || 96 (!requiresAttributeColors && 0xffffffff == drawState.getColor()); 97 if (colorIsTransBlack) { 98 desc->fColorInput = Desc::kTransBlack_ColorInput; 99 } else if (colorIsSolidWhite) { 100 desc->fColorInput = Desc::kSolidWhite_ColorInput; 101 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) { 102 desc->fColorInput = Desc::kUniform_ColorInput; 103 } else { 104 desc->fColorInput = Desc::kAttribute_ColorInput; 105 } 106 107 bool covIsSolidWhite = !requiresAttributeCoverage && 0xffffffff == drawState.getCoverage(); 108 109 if (skipCoverage) { 110 desc->fCoverageInput = Desc::kTransBlack_ColorInput; 111 } else if (covIsSolidWhite) { 112 desc->fCoverageInput = Desc::kSolidWhite_ColorInput; 113 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) { 114 desc->fCoverageInput = Desc::kUniform_ColorInput; 115 } else { 116 desc->fCoverageInput = Desc::kAttribute_ColorInput; 117 } 118 119 int lastEnabledStage = -1; 120 121 if (!skipCoverage && (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit)) { 122 desc->fVertexEdgeType = drawState.getVertexEdgeType(); 123 desc->fDiscardIfOutsideEdge = drawState.getStencil().doesWrite(); 124 } else { 125 // Use canonical values when edge-aa is not enabled to avoid program cache misses. 126 desc->fVertexEdgeType = GrDrawState::kHairLine_EdgeType; 127 desc->fDiscardIfOutsideEdge = false; 128 } 129 130 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 131 132 bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCoverage; 133 if (!skip && drawState.isStageEnabled(s)) { 134 lastEnabledStage = s; 135 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); 136 const GrBackendEffectFactory& factory = effect->getFactory(); 137 bool explicitLocalCoords = (drawState.getAttribBindings() & 138 GrDrawState::kLocalCoords_AttribBindingsBit); 139 GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords); 140 desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps()); 141 } else { 142 desc->fEffectKeys[s] = 0; 143 } 144 } 145 146 desc->fDualSrcOutput = Desc::kNone_DualSrcOutput; 147 148 // Currently the experimental GS will only work with triangle prims (and it doesn't do anything 149 // other than pass through values from the VS to the FS anyway). 150#if GR_GL_EXPERIMENTAL_GS 151#if 0 152 desc->fExperimentalGS = gpu->getCaps().geometryShaderSupport(); 153#else 154 desc->fExperimentalGS = false; 155#endif 156#endif 157 158 // We want to avoid generating programs with different "first cov stage" values when they would 159 // compute the same result. We set field in the desc to kNumStages when either there are no 160 // coverage stages or the distinction between coverage and color is immaterial. 161 int firstCoverageStage = GrDrawState::kNumStages; 162 desc->fFirstCoverageStage = GrDrawState::kNumStages; 163 bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage; 164 if (hasCoverage) { 165 firstCoverageStage = drawState.getFirstCoverageStage(); 166 } 167 168 // other coverage inputs 169 if (!hasCoverage) { 170 hasCoverage = requiresAttributeCoverage || 171 (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit); 172 } 173 174 if (hasCoverage) { 175 // color filter is applied between color/coverage computation 176 if (SkXfermode::kDst_Mode != desc->fColorFilterXfermode) { 177 desc->fFirstCoverageStage = firstCoverageStage; 178 } 179 180 if (gpu->getCaps().dualSourceBlendingSupport() && 181 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | 182 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { 183 if (kZero_GrBlendCoeff == dstCoeff) { 184 // write the coverage value to second color 185 desc->fDualSrcOutput = Desc::kCoverage_DualSrcOutput; 186 desc->fFirstCoverageStage = firstCoverageStage; 187 } else if (kSA_GrBlendCoeff == dstCoeff) { 188 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. 189 desc->fDualSrcOutput = Desc::kCoverageISA_DualSrcOutput; 190 desc->fFirstCoverageStage = firstCoverageStage; 191 } else if (kSC_GrBlendCoeff == dstCoeff) { 192 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. 193 desc->fDualSrcOutput = Desc::kCoverageISC_DualSrcOutput; 194 desc->fFirstCoverageStage = firstCoverageStage; 195 } 196 } 197 } 198 199 desc->fPositionAttributeIndex = drawState.getAttribIndex(GrDrawState::kPosition_AttribIndex); 200 if (requiresAttributeColors) { 201 desc->fColorAttributeIndex = drawState.getAttribIndex(GrDrawState::kColor_AttribIndex); 202 } else { 203 desc->fColorAttributeIndex = GrDrawState::kColorOverrideAttribIndexValue; 204 } 205 if (requiresAttributeCoverage) { 206 desc->fCoverageAttributeIndex = drawState.getAttribIndex(GrDrawState::kCoverage_AttribIndex); 207 } else { 208 desc->fCoverageAttributeIndex = GrDrawState::kCoverageOverrideAttribIndexValue; 209 } 210 if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) { 211 desc->fEdgeAttributeIndex = drawState.getAttribIndex(GrDrawState::kEdge_AttribIndex); 212 } 213 if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { 214 desc->fLocalCoordsAttributeIndex = drawState.getAttribIndex(GrDrawState::kLocalCoords_AttribIndex); 215 } 216 217#if GR_DEBUG 218 // verify valid vertex attribute state 219 const GrVertexAttrib* vertexAttribs = drawState.getVertexAttribs(); 220 GrAssert(desc->fPositionAttributeIndex < GrDrawState::kVertexAttribCnt); 221 GrAssert(kAttribLayouts[vertexAttribs[desc->fPositionAttributeIndex].fType].fCount == 2); 222 if (requiresAttributeColors) { 223 GrAssert(desc->fColorAttributeIndex < GrDrawState::kVertexAttribCnt); 224 GrAssert(kAttribLayouts[vertexAttribs[desc->fColorAttributeIndex].fType].fCount == 4); 225 } 226 if (requiresAttributeCoverage) { 227 GrAssert(desc->fCoverageAttributeIndex < GrDrawState::kVertexAttribCnt); 228 GrAssert(kAttribLayouts[vertexAttribs[desc->fCoverageAttributeIndex].fType].fCount == 4); 229 } 230 if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) { 231 GrAssert(desc->fEdgeAttributeIndex < GrDrawState::kVertexAttribCnt); 232 GrAssert(kAttribLayouts[vertexAttribs[desc->fEdgeAttributeIndex].fType].fCount == 4); 233 } 234 if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { 235 GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCnt); 236 GrAssert(kAttribLayouts[vertexAttribs[desc->fLocalCoordsAttributeIndex].fType].fCount == 2); 237 } 238#endif 239} 240 241GrGLProgram* GrGLProgram::Create(const GrGLContext& gl, 242 const Desc& desc, 243 const GrEffectStage* stages[]) { 244 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages)); 245 if (!program->succeeded()) { 246 delete program; 247 program = NULL; 248 } 249 return program; 250} 251 252GrGLProgram::GrGLProgram(const GrGLContext& gl, 253 const Desc& desc, 254 const GrEffectStage* stages[]) 255: fContext(gl) 256, fUniformManager(gl) { 257 fDesc = desc; 258 fVShaderID = 0; 259 fGShaderID = 0; 260 fFShaderID = 0; 261 fProgramID = 0; 262 263 fColor = GrColor_ILLEGAL; 264 fColorFilterColor = GrColor_ILLEGAL; 265 266 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 267 fEffects[s] = NULL; 268 } 269 270 this->genProgram(stages); 271} 272 273GrGLProgram::~GrGLProgram() { 274 if (fVShaderID) { 275 GL_CALL(DeleteShader(fVShaderID)); 276 } 277 if (fGShaderID) { 278 GL_CALL(DeleteShader(fGShaderID)); 279 } 280 if (fFShaderID) { 281 GL_CALL(DeleteShader(fFShaderID)); 282 } 283 if (fProgramID) { 284 GL_CALL(DeleteProgram(fProgramID)); 285 } 286 287 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 288 delete fEffects[i]; 289 } 290} 291 292void GrGLProgram::abandon() { 293 fVShaderID = 0; 294 fGShaderID = 0; 295 fFShaderID = 0; 296 fProgramID = 0; 297} 298 299void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, 300 GrBlendCoeff* dstCoeff) const { 301 switch (fDesc.fDualSrcOutput) { 302 case Desc::kNone_DualSrcOutput: 303 break; 304 // the prog will write a coverage value to the secondary 305 // output and the dst is blended by one minus that value. 306 case Desc::kCoverage_DualSrcOutput: 307 case Desc::kCoverageISA_DualSrcOutput: 308 case Desc::kCoverageISC_DualSrcOutput: 309 *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; 310 break; 311 default: 312 GrCrash("Unexpected dual source blend output"); 313 break; 314 } 315} 316 317namespace { 318 319// given two blend coeffecients determine whether the src 320// and/or dst computation can be omitted. 321inline void need_blend_inputs(SkXfermode::Coeff srcCoeff, 322 SkXfermode::Coeff dstCoeff, 323 bool* needSrcValue, 324 bool* needDstValue) { 325 if (SkXfermode::kZero_Coeff == srcCoeff) { 326 switch (dstCoeff) { 327 // these all read the src 328 case SkXfermode::kSC_Coeff: 329 case SkXfermode::kISC_Coeff: 330 case SkXfermode::kSA_Coeff: 331 case SkXfermode::kISA_Coeff: 332 *needSrcValue = true; 333 break; 334 default: 335 *needSrcValue = false; 336 break; 337 } 338 } else { 339 *needSrcValue = true; 340 } 341 if (SkXfermode::kZero_Coeff == dstCoeff) { 342 switch (srcCoeff) { 343 // these all read the dst 344 case SkXfermode::kDC_Coeff: 345 case SkXfermode::kIDC_Coeff: 346 case SkXfermode::kDA_Coeff: 347 case SkXfermode::kIDA_Coeff: 348 *needDstValue = true; 349 break; 350 default: 351 *needDstValue = false; 352 break; 353 } 354 } else { 355 *needDstValue = true; 356 } 357} 358 359/** 360 * Create a blend_coeff * value string to be used in shader code. Sets empty 361 * string if result is trivially zero. 362 */ 363inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff, 364 const char* src, const char* dst, 365 const char* value) { 366 switch (coeff) { 367 case SkXfermode::kZero_Coeff: /** 0 */ 368 *str = ""; 369 break; 370 case SkXfermode::kOne_Coeff: /** 1 */ 371 *str = value; 372 break; 373 case SkXfermode::kSC_Coeff: 374 str->printf("(%s * %s)", src, value); 375 break; 376 case SkXfermode::kISC_Coeff: 377 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value); 378 break; 379 case SkXfermode::kDC_Coeff: 380 str->printf("(%s * %s)", dst, value); 381 break; 382 case SkXfermode::kIDC_Coeff: 383 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value); 384 break; 385 case SkXfermode::kSA_Coeff: /** src alpha */ 386 str->printf("(%s.a * %s)", src, value); 387 break; 388 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ 389 str->printf("((1.0 - %s.a) * %s)", src, value); 390 break; 391 case SkXfermode::kDA_Coeff: /** dst alpha */ 392 str->printf("(%s.a * %s)", dst, value); 393 break; 394 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ 395 str->printf("((1.0 - %s.a) * %s)", dst, value); 396 break; 397 default: 398 GrCrash("Unexpected xfer coeff."); 399 break; 400 } 401} 402/** 403 * Adds a line to the fragment shader code which modifies the color by 404 * the specified color filter. 405 */ 406void add_color_filter(GrGLShaderBuilder* builder, 407 const char * outputVar, 408 SkXfermode::Coeff uniformCoeff, 409 SkXfermode::Coeff colorCoeff, 410 const char* filterColor, 411 const char* inColor) { 412 SkString colorStr, constStr; 413 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); 414 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor); 415 416 SkString sum; 417 GrGLSLAdd4f(&sum, colorStr.c_str(), constStr.c_str()); 418 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); 419} 420} 421 422bool GrGLProgram::genEdgeCoverage(SkString* coverageVar, 423 GrGLShaderBuilder* builder) const { 424 if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) { 425 const char *vsName, *fsName; 426 builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName); 427 builder->addAttribute(kVec4f_GrSLType, EDGE_ATTR_NAME); 428 builder->vsCodeAppendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName); 429 switch (fDesc.fVertexEdgeType) { 430 case GrDrawState::kHairLine_EdgeType: 431 builder->fsCodeAppendf("\tfloat edgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n", 432 builder->fragmentPosition(), fsName); 433 builder->fsCodeAppendf("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); 434 break; 435 case GrDrawState::kQuad_EdgeType: 436 builder->fsCodeAppendf("\tfloat edgeAlpha;\n"); 437 // keep the derivative instructions outside the conditional 438 builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); 439 builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); 440 builder->fsCodeAppendf("\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName); 441 // today we know z and w are in device space. We could use derivatives 442 builder->fsCodeAppendf("\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, 443 fsName); 444 builder->fsCodeAppendf ("\t} else {\n"); 445 builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" 446 "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n", 447 fsName, fsName); 448 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); 449 builder->fsCodeAppendf("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n" 450 "\t}\n"); 451 if (kES2_GrGLBinding == fContext.info().binding()) { 452 builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n"); 453 } 454 break; 455 case GrDrawState::kHairQuad_EdgeType: 456 builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); 457 builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); 458 builder->fsCodeAppendf("\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" 459 "\t 2.0*%s.x*duvdy.x - duvdy.y);\n", 460 fsName, fsName); 461 builder->fsCodeAppendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, 462 fsName); 463 builder->fsCodeAppend("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n"); 464 builder->fsCodeAppend("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); 465 if (kES2_GrGLBinding == fContext.info().binding()) { 466 builder->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n"); 467 } 468 break; 469 default: 470 GrCrash("Unknown Edge Type!"); 471 break; 472 } 473 if (fDesc.fDiscardIfOutsideEdge) { 474 builder->fsCodeAppend("\tif (edgeAlpha <= 0.0) {\n\t\tdiscard;\n\t}\n"); 475 } 476 *coverageVar = "edgeAlpha"; 477 return true; 478 } else { 479 coverageVar->reset(); 480 return false; 481 } 482} 483 484void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { 485 switch (fDesc.fColorInput) { 486 case GrGLProgram::Desc::kAttribute_ColorInput: { 487 builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME); 488 const char *vsName, *fsName; 489 builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); 490 builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); 491 *inColor = fsName; 492 } break; 493 case GrGLProgram::Desc::kUniform_ColorInput: { 494 const char* name; 495 fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 496 kVec4f_GrSLType, "Color", &name); 497 *inColor = name; 498 break; 499 } 500 case GrGLProgram::Desc::kTransBlack_ColorInput: 501 GrAssert(!"needComputedColor should be false."); 502 break; 503 case GrGLProgram::Desc::kSolidWhite_ColorInput: 504 break; 505 default: 506 GrCrash("Unknown color type."); 507 break; 508 } 509} 510 511void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOutCoverage) { 512 const char* covUniName; 513 fUniformHandles.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 514 kVec4f_GrSLType, "Coverage", &covUniName); 515 if (inOutCoverage->size()) { 516 builder->fsCodeAppendf("\tvec4 uniCoverage = %s * %s;\n", 517 covUniName, inOutCoverage->c_str()); 518 *inOutCoverage = "uniCoverage"; 519 } else { 520 *inOutCoverage = covUniName; 521 } 522} 523 524namespace { 525void gen_attribute_coverage(GrGLShaderBuilder* builder, 526 SkString* inOutCoverage) { 527 builder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME); 528 const char *vsName, *fsName; 529 builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); 530 builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); 531 if (inOutCoverage->size()) { 532 builder->fsCodeAppendf("\tvec4 attrCoverage = %s * %s;\n", fsName, inOutCoverage->c_str()); 533 *inOutCoverage = "attrCoverage"; 534 } else { 535 *inOutCoverage = fsName; 536 } 537} 538} 539 540void GrGLProgram::genGeometryShader(GrGLShaderBuilder* builder) const { 541#if GR_GL_EXPERIMENTAL_GS 542 // TODO: The builder should add all this glue code. 543 if (fDesc.fExperimentalGS) { 544 GrAssert(fContext.info().glslGeneration() >= k150_GrGLSLGeneration); 545 builder->fGSHeader.append("layout(triangles) in;\n" 546 "layout(triangle_strip, max_vertices = 6) out;\n"); 547 builder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" 548 "\t\tgl_Position = gl_in[i].gl_Position;\n"); 549 if (fDesc.fEmitsPointSize) { 550 builder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n"); 551 } 552 GrAssert(builder->fGSInputs.count() == builder->fGSOutputs.count()); 553 int count = builder->fGSInputs.count(); 554 for (int i = 0; i < count; ++i) { 555 builder->gsCodeAppendf("\t\t%s = %s[i];\n", 556 builder->fGSOutputs[i].getName().c_str(), 557 builder->fGSInputs[i].getName().c_str()); 558 } 559 builder->gsCodeAppend("\t\tEmitVertex();\n" 560 "\t}\n" 561 "\tEndPrimitive();\n"); 562 } 563#endif 564} 565 566const char* GrGLProgram::adjustInColor(const SkString& inColor) const { 567 if (inColor.size()) { 568 return inColor.c_str(); 569 } else { 570 if (Desc::kSolidWhite_ColorInput == fDesc.fColorInput) { 571 return GrGLSLOnesVecf(4); 572 } else { 573 return GrGLSLZerosVecf(4); 574 } 575 } 576} 577 578namespace { 579// prints a shader using params similar to glShaderSource 580void print_shader(GrGLint stringCnt, 581 const GrGLchar** strings, 582 GrGLint* stringLengths) { 583 for (int i = 0; i < stringCnt; ++i) { 584 if (NULL == stringLengths || stringLengths[i] < 0) { 585 GrPrintf(strings[i]); 586 } else { 587 GrPrintf("%.*s", stringLengths[i], strings[i]); 588 } 589 } 590} 591 592// Compiles a GL shader, returns shader ID or 0 if failed params have same meaning as glShaderSource 593GrGLuint compile_shader(const GrGLContext& gl, 594 GrGLenum type, 595 int stringCnt, 596 const char** strings, 597 int* stringLengths) { 598 SK_TRACE_EVENT1("GrGLProgram::CompileShader", 599 "stringCount", SkStringPrintf("%i", stringCnt).c_str()); 600 601 GrGLuint shader; 602 GR_GL_CALL_RET(gl.interface(), shader, CreateShader(type)); 603 if (0 == shader) { 604 return 0; 605 } 606 607 const GrGLInterface* gli = gl.interface(); 608 GrGLint compiled = GR_GL_INIT_ZERO; 609 GR_GL_CALL(gli, ShaderSource(shader, stringCnt, strings, stringLengths)); 610 GR_GL_CALL(gli, CompileShader(shader)); 611 GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled)); 612 613 if (!compiled) { 614 GrGLint infoLen = GR_GL_INIT_ZERO; 615 GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen)); 616 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 617 if (infoLen > 0) { 618 // retrieve length even though we don't need it to workaround bug in chrome cmd buffer 619 // param validation. 620 GrGLsizei length = GR_GL_INIT_ZERO; 621 GR_GL_CALL(gli, GetShaderInfoLog(shader, infoLen+1, 622 &length, (char*)log.get())); 623 print_shader(stringCnt, strings, stringLengths); 624 GrPrintf("\n%s", log.get()); 625 } 626 GrAssert(!"Shader compilation failed!"); 627 GR_GL_CALL(gli, DeleteShader(shader)); 628 return 0; 629 } 630 return shader; 631} 632 633// helper version of above for when shader is already flattened into a single SkString 634GrGLuint compile_shader(const GrGLContext& gl, GrGLenum type, const SkString& shader) { 635 const GrGLchar* str = shader.c_str(); 636 int length = shader.size(); 637 return compile_shader(gl, type, 1, &str, &length); 638} 639 640} 641 642// compiles all the shaders from builder and stores the shader IDs 643bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) { 644 645 SkString shader; 646 647 builder.getShader(GrGLShaderBuilder::kVertex_ShaderType, &shader); 648 if (c_PrintShaders) { 649 GrPrintf(shader.c_str()); 650 GrPrintf("\n"); 651 } 652 653 if (!(fVShaderID = compile_shader(fContext, GR_GL_VERTEX_SHADER, shader))) { 654 return false; 655 } 656 657 if (builder.fUsesGS) { 658 builder.getShader(GrGLShaderBuilder::kGeometry_ShaderType, &shader); 659 if (c_PrintShaders) { 660 GrPrintf(shader.c_str()); 661 GrPrintf("\n"); 662 } 663 if (!(fGShaderID = compile_shader(fContext, GR_GL_GEOMETRY_SHADER, shader))) { 664 return false; 665 } 666 } else { 667 fGShaderID = 0; 668 } 669 670 builder.getShader(GrGLShaderBuilder::kFragment_ShaderType, &shader); 671 if (c_PrintShaders) { 672 GrPrintf(shader.c_str()); 673 GrPrintf("\n"); 674 } 675 if (!(fFShaderID = compile_shader(fContext, GR_GL_FRAGMENT_SHADER, shader))) { 676 return false; 677 } 678 679 return true; 680} 681 682bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { 683 GrAssert(0 == fProgramID); 684 685 const GrAttribBindings& attribBindings = fDesc.fAttribBindings; 686 bool hasExplicitLocalCoords = 687 SkToBool(attribBindings & GrDrawState::kLocalCoords_AttribBindingsBit); 688 GrGLShaderBuilder builder(fContext.info(), fUniformManager, hasExplicitLocalCoords); 689 690#if GR_GL_EXPERIMENTAL_GS 691 builder.fUsesGS = fDesc.fExperimentalGS; 692#endif 693 694 SkXfermode::Coeff colorCoeff, uniformCoeff; 695 // The rest of transfer mode color filters have not been implemented 696 if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) { 697 GR_DEBUGCODE(bool success =) 698 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode> 699 (fDesc.fColorFilterXfermode), 700 &uniformCoeff, &colorCoeff); 701 GR_DEBUGASSERT(success); 702 } else { 703 colorCoeff = SkXfermode::kOne_Coeff; 704 uniformCoeff = SkXfermode::kZero_Coeff; 705 } 706 707 // no need to do the color filter if coverage is 0. The output color is scaled by the coverage. 708 // All the dual source outputs are scaled by the coverage as well. 709 if (Desc::kTransBlack_ColorInput == fDesc.fCoverageInput) { 710 colorCoeff = SkXfermode::kZero_Coeff; 711 uniformCoeff = SkXfermode::kZero_Coeff; 712 } 713 714 // If we know the final color is going to be all zeros then we can 715 // simplify the color filter coefficients. needComputedColor will then 716 // come out false below. 717 if (Desc::kTransBlack_ColorInput == fDesc.fColorInput) { 718 colorCoeff = SkXfermode::kZero_Coeff; 719 if (SkXfermode::kDC_Coeff == uniformCoeff || 720 SkXfermode::kDA_Coeff == uniformCoeff) { 721 uniformCoeff = SkXfermode::kZero_Coeff; 722 } else if (SkXfermode::kIDC_Coeff == uniformCoeff || 723 SkXfermode::kIDA_Coeff == uniformCoeff) { 724 uniformCoeff = SkXfermode::kOne_Coeff; 725 } 726 } 727 728 bool needColorFilterUniform; 729 bool needComputedColor; 730 need_blend_inputs(uniformCoeff, colorCoeff, 731 &needColorFilterUniform, &needComputedColor); 732 733 // the dual source output has no canonical var name, have to 734 // declare an output, which is incompatible with gl_FragColor/gl_FragData. 735 bool dualSourceOutputWritten = false; 736 builder.fHeader.append(GrGetGLSLVersionDecl(fContext.info().binding(), 737 fContext.info().glslGeneration())); 738 739 GrGLShaderVar colorOutput; 740 bool isColorDeclared = GrGLSLSetupFSColorOuput(fContext.info().glslGeneration(), 741 declared_color_output_name(), 742 &colorOutput); 743 if (isColorDeclared) { 744 builder.fFSOutputs.push_back(colorOutput); 745 } 746 747 const char* viewMName; 748 fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType, 749 kMat33f_GrSLType, "ViewM", &viewMName); 750 751 752 builder.vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" 753 "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", 754 viewMName, builder.positionAttribute().getName().c_str()); 755 756 // incoming color to current stage being processed. 757 SkString inColor; 758 759 if (needComputedColor) { 760 this->genInputColor(&builder, &inColor); 761 } 762 763 // we output point size in the GS if present 764 if (fDesc.fEmitsPointSize && !builder.fUsesGS){ 765 builder.vsCodeAppend("\tgl_PointSize = 1.0;\n"); 766 } 767 768 /////////////////////////////////////////////////////////////////////////// 769 // compute the final color 770 771 // if we have color stages string them together, feeding the output color 772 // of each to the next and generating code for each stage. 773 if (needComputedColor) { 774 SkString outColor; 775 for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) { 776 if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) { 777 // create var to hold stage result 778 outColor = "color"; 779 outColor.appendS32(s); 780 builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); 781 782 builder.setCurrentStage(s); 783 fEffects[s] = builder.createAndEmitGLEffect(*stages[s], 784 fDesc.fEffectKeys[s], 785 inColor.size() ? inColor.c_str() : NULL, 786 outColor.c_str(), 787 &fUniformHandles.fSamplerUnis[s]); 788 builder.setNonStage(); 789 inColor = outColor; 790 } 791 } 792 } 793 794 // if have all ones or zeros for the "dst" input to the color filter then we 795 // may be able to make additional optimizations. 796 if (needColorFilterUniform && needComputedColor && !inColor.size()) { 797 GrAssert(Desc::kSolidWhite_ColorInput == fDesc.fColorInput); 798 bool uniformCoeffIsZero = SkXfermode::kIDC_Coeff == uniformCoeff || 799 SkXfermode::kIDA_Coeff == uniformCoeff; 800 if (uniformCoeffIsZero) { 801 uniformCoeff = SkXfermode::kZero_Coeff; 802 bool bogus; 803 need_blend_inputs(SkXfermode::kZero_Coeff, colorCoeff, 804 &needColorFilterUniform, &bogus); 805 } 806 } 807 const char* colorFilterColorUniName = NULL; 808 if (needColorFilterUniform) { 809 fUniformHandles.fColorFilterUni = builder.addUniform( 810 GrGLShaderBuilder::kFragment_ShaderType, 811 kVec4f_GrSLType, "FilterColor", 812 &colorFilterColorUniName); 813 } 814 bool wroteFragColorZero = false; 815 if (SkXfermode::kZero_Coeff == uniformCoeff && 816 SkXfermode::kZero_Coeff == colorCoeff) { 817 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrGLSLZerosVecf(4)); 818 wroteFragColorZero = true; 819 } else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) { 820 builder.fsCodeAppend("\tvec4 filteredColor;\n"); 821 const char* color = adjustInColor(inColor); 822 add_color_filter(&builder, "filteredColor", uniformCoeff, 823 colorCoeff, colorFilterColorUniName, color); 824 inColor = "filteredColor"; 825 } 826 827 /////////////////////////////////////////////////////////////////////////// 828 // compute the partial coverage (coverage stages and edge aa) 829 830 SkString inCoverage; 831 bool coverageIsZero = Desc::kTransBlack_ColorInput == fDesc.fCoverageInput; 832 // we don't need to compute coverage at all if we know the final shader 833 // output will be zero and we don't have a dual src blend output. 834 if (!wroteFragColorZero || Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { 835 836 if (!coverageIsZero) { 837 bool inCoverageIsScalar = this->genEdgeCoverage(&inCoverage, &builder); 838 839 switch (fDesc.fCoverageInput) { 840 case Desc::kSolidWhite_ColorInput: 841 // empty string implies solid white 842 break; 843 case Desc::kAttribute_ColorInput: 844 gen_attribute_coverage(&builder, &inCoverage); 845 inCoverageIsScalar = false; 846 break; 847 case Desc::kUniform_ColorInput: 848 this->genUniformCoverage(&builder, &inCoverage); 849 inCoverageIsScalar = false; 850 break; 851 default: 852 GrCrash("Unexpected input coverage."); 853 } 854 855 SkString outCoverage; 856 const int& startStage = fDesc.fFirstCoverageStage; 857 for (int s = startStage; s < GrDrawState::kNumStages; ++s) { 858 if (fDesc.fEffectKeys[s]) { 859 // create var to hold stage output 860 outCoverage = "coverage"; 861 outCoverage.appendS32(s); 862 builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str()); 863 864 // stages don't know how to deal with a scalar input. (Maybe they should. We 865 // could pass a GrGLShaderVar) 866 if (inCoverageIsScalar) { 867 builder.fsCodeAppendf("\tvec4 %s4 = vec4(%s);\n", 868 inCoverage.c_str(), inCoverage.c_str()); 869 inCoverage.append("4"); 870 } 871 builder.setCurrentStage(s); 872 fEffects[s] = builder.createAndEmitGLEffect( 873 *stages[s], 874 fDesc.fEffectKeys[s], 875 inCoverage.size() ? inCoverage.c_str() : NULL, 876 outCoverage.c_str(), 877 &fUniformHandles.fSamplerUnis[s]); 878 builder.setNonStage(); 879 inCoverage = outCoverage; 880 } 881 } 882 883 // discard if coverage is zero 884 if (fDesc.fDiscardIfOutsideEdge && !outCoverage.isEmpty()) { 885 builder.fsCodeAppendf( 886 "\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n", 887 outCoverage.c_str()); 888 } 889 } 890 891 if (Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { 892 builder.fFSOutputs.push_back().set(kVec4f_GrSLType, 893 GrGLShaderVar::kOut_TypeModifier, 894 dual_source_output_name()); 895 bool outputIsZero = coverageIsZero; 896 SkString coeff; 897 if (!outputIsZero && 898 Desc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) { 899 if (!inColor.size()) { 900 outputIsZero = true; 901 } else { 902 if (Desc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) { 903 coeff.printf("(1 - %s.a)", inColor.c_str()); 904 } else { 905 coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str()); 906 } 907 } 908 } 909 if (outputIsZero) { 910 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), GrGLSLZerosVecf(4)); 911 } else { 912 SkString modulate; 913 GrGLSLModulate4f(&modulate, coeff.c_str(), inCoverage.c_str()); 914 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulate.c_str()); 915 } 916 dualSourceOutputWritten = true; 917 } 918 } 919 920 /////////////////////////////////////////////////////////////////////////// 921 // combine color and coverage as frag color 922 923 if (!wroteFragColorZero) { 924 if (coverageIsZero) { 925 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrGLSLZerosVecf(4)); 926 } else { 927 SkString modulate; 928 GrGLSLModulate4f(&modulate, inColor.c_str(), inCoverage.c_str()); 929 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), modulate.c_str()); 930 } 931 } 932 933 /////////////////////////////////////////////////////////////////////////// 934 // insert GS 935#if GR_DEBUG 936 this->genGeometryShader(&builder); 937#endif 938 939 /////////////////////////////////////////////////////////////////////////// 940 // compile and setup attribs and unis 941 942 if (!this->compileShaders(builder)) { 943 return false; 944 } 945 946 if (!this->bindOutputsAttribsAndLinkProgram(builder, 947 isColorDeclared, 948 dualSourceOutputWritten)) { 949 return false; 950 } 951 952 builder.finished(fProgramID); 953 this->initSamplerUniforms(); 954 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); 955 956 return true; 957} 958 959bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder, 960 bool bindColorOut, 961 bool bindDualSrcOut) { 962 GL_CALL_RET(fProgramID, CreateProgram()); 963 if (!fProgramID) { 964 return false; 965 } 966 967 GL_CALL(AttachShader(fProgramID, fVShaderID)); 968 if (fGShaderID) { 969 GL_CALL(AttachShader(fProgramID, fGShaderID)); 970 } 971 GL_CALL(AttachShader(fProgramID, fFShaderID)); 972 973 if (bindColorOut) { 974 GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name())); 975 } 976 if (bindDualSrcOut) { 977 GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output_name())); 978 } 979 980 // Bind the attrib locations to same values for all shaders 981 GL_CALL(BindAttribLocation(fProgramID, 982 fDesc.fPositionAttributeIndex, 983 builder.positionAttribute().c_str())); 984 GL_CALL(BindAttribLocation(fProgramID, fDesc.fColorAttributeIndex, COL_ATTR_NAME)); 985 GL_CALL(BindAttribLocation(fProgramID, fDesc.fCoverageAttributeIndex, COV_ATTR_NAME)); 986 987 if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) { 988 GL_CALL(BindAttribLocation(fProgramID, fDesc.fEdgeAttributeIndex, EDGE_ATTR_NAME)); 989 } 990 if (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { 991 GL_CALL(BindAttribLocation(fProgramID, 992 fDesc.fLocalCoordsAttributeIndex, 993 builder.localCoordsAttribute().c_str())); 994 } 995 996 const GrGLShaderBuilder::AttributePair* attribEnd = builder.getEffectAttributes().end(); 997 for (const GrGLShaderBuilder::AttributePair* attrib = builder.getEffectAttributes().begin(); 998 attrib != attribEnd; 999 ++attrib) { 1000 GL_CALL(BindAttribLocation(fProgramID, attrib->fIndex, attrib->fName.c_str())); 1001 } 1002 1003 GL_CALL(LinkProgram(fProgramID)); 1004 1005 GrGLint linked = GR_GL_INIT_ZERO; 1006 GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked)); 1007 if (!linked) { 1008 GrGLint infoLen = GR_GL_INIT_ZERO; 1009 GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen)); 1010 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 1011 if (infoLen > 0) { 1012 // retrieve length even though we don't need it to workaround 1013 // bug in chrome cmd buffer param validation. 1014 GrGLsizei length = GR_GL_INIT_ZERO; 1015 GL_CALL(GetProgramInfoLog(fProgramID, 1016 infoLen+1, 1017 &length, 1018 (char*)log.get())); 1019 GrPrintf((char*)log.get()); 1020 } 1021 GrAssert(!"Error linking program"); 1022 GL_CALL(DeleteProgram(fProgramID)); 1023 fProgramID = 0; 1024 return false; 1025 } 1026 return true; 1027} 1028 1029void GrGLProgram::initSamplerUniforms() { 1030 GL_CALL(UseProgram(fProgramID)); 1031 // We simply bind the uniforms to successive texture units beginning at 0. setData() assumes this 1032 // behavior. 1033 GrGLint texUnitIdx = 0; 1034 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 1035 int numSamplers = fUniformHandles.fSamplerUnis[s].count(); 1036 for (int u = 0; u < numSamplers; ++u) { 1037 UniformHandle handle = fUniformHandles.fSamplerUnis[s][u]; 1038 if (GrGLUniformManager::kInvalidUniformHandle != handle) { 1039 fUniformManager.setSampler(handle, texUnitIdx); 1040 ++texUnitIdx; 1041 } 1042 } 1043 } 1044} 1045 1046/////////////////////////////////////////////////////////////////////////////// 1047 1048void GrGLProgram::setData(GrGpuGL* gpu, 1049 GrColor color, 1050 GrColor coverage, 1051 SharedGLState* sharedState) { 1052 const GrDrawState& drawState = gpu->getDrawState(); 1053 1054 this->setColor(drawState, color, sharedState); 1055 this->setCoverage(drawState, coverage, sharedState); 1056 this->setMatrixAndRenderTargetHeight(drawState); 1057 1058 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary 1059 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fColorFilterUni && 1060 fColorFilterColor != drawState.getColorFilterColor()) { 1061 GrGLfloat c[4]; 1062 GrColorToRGBAFloat(drawState.getColorFilterColor(), c); 1063 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c); 1064 fColorFilterColor = drawState.getColorFilterColor(); 1065 } 1066 1067 GrGLint texUnitIdx = 0; 1068 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 1069 if (NULL != fEffects[s]) { 1070 const GrEffectStage& stage = drawState.getStage(s); 1071 GrAssert(NULL != stage.getEffect()); 1072 1073 bool explicitLocalCoords = 1074 (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit); 1075 GrDrawEffect drawEffect(stage, explicitLocalCoords); 1076 fEffects[s]->setData(fUniformManager, drawEffect); 1077 int numSamplers = fUniformHandles.fSamplerUnis[s].count(); 1078 for (int u = 0; u < numSamplers; ++u) { 1079 UniformHandle handle = fUniformHandles.fSamplerUnis[s][u]; 1080 if (GrGLUniformManager::kInvalidUniformHandle != handle) { 1081 const GrTextureAccess& access = (*stage.getEffect())->textureAccess(u); 1082 GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture()); 1083 gpu->bindTexture(texUnitIdx, access.getParams(), texture); 1084 ++texUnitIdx; 1085 } 1086 } 1087 } 1088 } 1089} 1090 1091void GrGLProgram::setColor(const GrDrawState& drawState, 1092 GrColor color, 1093 SharedGLState* sharedState) { 1094 if (!(drawState.getAttribBindings() & GrDrawState::kColor_AttribBindingsBit)) { 1095 switch (fDesc.fColorInput) { 1096 case GrGLProgram::Desc::kAttribute_ColorInput: 1097 if (sharedState->fConstAttribColor != color) { 1098 // OpenGL ES only supports the float varieties of glVertexAttrib 1099 GrGLfloat c[4]; 1100 GrColorToRGBAFloat(color, c); 1101 GL_CALL(VertexAttrib4fv(fDesc.fColorAttributeIndex, c)); 1102 sharedState->fConstAttribColor = color; 1103 } 1104 break; 1105 case GrGLProgram::Desc::kUniform_ColorInput: 1106 if (fColor != color) { 1107 // OpenGL ES doesn't support unsigned byte varieties of glUniform 1108 GrGLfloat c[4]; 1109 GrColorToRGBAFloat(color, c); 1110 GrAssert(GrGLUniformManager::kInvalidUniformHandle != 1111 fUniformHandles.fColorUni); 1112 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); 1113 fColor = color; 1114 } 1115 break; 1116 case GrGLProgram::Desc::kSolidWhite_ColorInput: 1117 case GrGLProgram::Desc::kTransBlack_ColorInput: 1118 break; 1119 default: 1120 GrCrash("Unknown color type."); 1121 } 1122 } 1123} 1124 1125void GrGLProgram::setCoverage(const GrDrawState& drawState, 1126 GrColor coverage, 1127 SharedGLState* sharedState) { 1128 if (!(drawState.getAttribBindings() & GrDrawState::kCoverage_AttribBindingsBit)) { 1129 switch (fDesc.fCoverageInput) { 1130 case Desc::kAttribute_ColorInput: 1131 if (sharedState->fConstAttribCoverage != coverage) { 1132 // OpenGL ES only supports the float varieties of glVertexAttrib 1133 GrGLfloat c[4]; 1134 GrColorToRGBAFloat(coverage, c); 1135 GL_CALL(VertexAttrib4fv(fDesc.fCoverageAttributeIndex, c)); 1136 sharedState->fConstAttribCoverage = coverage; 1137 } 1138 break; 1139 case Desc::kUniform_ColorInput: 1140 if (fCoverage != coverage) { 1141 // OpenGL ES doesn't support unsigned byte varieties of glUniform 1142 GrGLfloat c[4]; 1143 GrColorToRGBAFloat(coverage, c); 1144 GrAssert(GrGLUniformManager::kInvalidUniformHandle != 1145 fUniformHandles.fCoverageUni); 1146 fUniformManager.set4fv(fUniformHandles.fCoverageUni, 0, 1, c); 1147 fCoverage = coverage; 1148 } 1149 break; 1150 case Desc::kSolidWhite_ColorInput: 1151 case Desc::kTransBlack_ColorInput: 1152 break; 1153 default: 1154 GrCrash("Unknown coverage type."); 1155 } 1156 } 1157} 1158 1159void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) { 1160 const GrRenderTarget* rt = drawState.getRenderTarget(); 1161 SkISize size; 1162 size.set(rt->width(), rt->height()); 1163 1164 // Load the RT height uniform if it is needed to y-flip gl_FragCoord. 1165 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fRTHeightUni && 1166 fMatrixState.fRenderTargetSize.fHeight != size.fHeight) { 1167 fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight)); 1168 } 1169 1170 if (fMatrixState.fRenderTargetOrigin != rt->origin() || 1171 !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) || 1172 fMatrixState.fRenderTargetSize != size) { 1173 SkMatrix m; 1174 if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { 1175 m.setAll( 1176 SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1, 1177 0,-SkIntToScalar(2) / size.fHeight, SK_Scalar1, 1178 0, 0, SkMatrix::I()[8]); 1179 } else { 1180 m.setAll( 1181 SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1, 1182 0, SkIntToScalar(2) / size.fHeight,-SK_Scalar1, 1183 0, 0, SkMatrix::I()[8]); 1184 } 1185 m.setConcat(m, drawState.getViewMatrix()); 1186 1187 // ES doesn't allow you to pass true to the transpose param so we do our own transpose. 1188 GrGLfloat mt[] = { 1189 SkScalarToFloat(m[SkMatrix::kMScaleX]), 1190 SkScalarToFloat(m[SkMatrix::kMSkewY]), 1191 SkScalarToFloat(m[SkMatrix::kMPersp0]), 1192 SkScalarToFloat(m[SkMatrix::kMSkewX]), 1193 SkScalarToFloat(m[SkMatrix::kMScaleY]), 1194 SkScalarToFloat(m[SkMatrix::kMPersp1]), 1195 SkScalarToFloat(m[SkMatrix::kMTransX]), 1196 SkScalarToFloat(m[SkMatrix::kMTransY]), 1197 SkScalarToFloat(m[SkMatrix::kMPersp2]) 1198 }; 1199 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); 1200 fMatrixState.fViewMatrix = drawState.getViewMatrix(); 1201 fMatrixState.fRenderTargetSize = size; 1202 fMatrixState.fRenderTargetOrigin = rt->origin(); 1203 } 1204} 1205