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