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