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 "GrGLSL.h" 17 #include "SkTrace.h" 18 #include "SkXfermode.h" 19 20 #include "SkRTConf.h" 21 22 SK_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 27 SK_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 34 namespace { 35 inline const char* declared_color_output_name() { return "fsColorOut"; } 36 inline const char* dual_source_output_name() { return "dualSourceOut"; } 37 } 38 39 GrGLProgram* GrGLProgram::Create(const GrGLContext& gl, 40 const GrGLProgramDesc& desc, 41 const GrEffectStage* colorStages[], 42 const GrEffectStage* coverageStages[]) { 43 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, colorStages, coverageStages)); 44 if (!program->succeeded()) { 45 delete program; 46 program = NULL; 47 } 48 return program; 49 } 50 51 GrGLProgram::GrGLProgram(const GrGLContext& gl, 52 const GrGLProgramDesc& desc, 53 const GrEffectStage* colorStages[], 54 const GrEffectStage* coverageStages[]) 55 : fContext(gl) 56 , fUniformManager(gl) { 57 fDesc = desc; 58 fVShaderID = 0; 59 fGShaderID = 0; 60 fFShaderID = 0; 61 fProgramID = 0; 62 63 fDstCopyTexUnit = -1; 64 65 fColor = GrColor_ILLEGAL; 66 fColorFilterColor = GrColor_ILLEGAL; 67 68 fColorEffects.reset(desc.numColorEffects()); 69 fCoverageEffects.reset(desc.numCoverageEffects()); 70 71 this->genProgram(colorStages, coverageStages); 72 } 73 74 GrGLProgram::~GrGLProgram() { 75 if (fVShaderID) { 76 GL_CALL(DeleteShader(fVShaderID)); 77 } 78 if (fGShaderID) { 79 GL_CALL(DeleteShader(fGShaderID)); 80 } 81 if (fFShaderID) { 82 GL_CALL(DeleteShader(fFShaderID)); 83 } 84 if (fProgramID) { 85 GL_CALL(DeleteProgram(fProgramID)); 86 } 87 } 88 89 void GrGLProgram::abandon() { 90 fVShaderID = 0; 91 fGShaderID = 0; 92 fFShaderID = 0; 93 fProgramID = 0; 94 } 95 96 void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, 97 GrBlendCoeff* dstCoeff) const { 98 switch (fDesc.getHeader().fCoverageOutput) { 99 case GrGLProgramDesc::kModulate_CoverageOutput: 100 break; 101 // The prog will write a coverage value to the secondary 102 // output and the dst is blended by one minus that value. 103 case GrGLProgramDesc::kSecondaryCoverage_CoverageOutput: 104 case GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput: 105 case GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput: 106 *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; 107 break; 108 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: 109 // We should only have set this if the blend was specified as (1, 0) 110 GrAssert(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *dstCoeff); 111 break; 112 default: 113 GrCrash("Unexpected coverage output"); 114 break; 115 } 116 } 117 118 namespace { 119 // given two blend coefficients determine whether the src 120 // and/or dst computation can be omitted. 121 inline void need_blend_inputs(SkXfermode::Coeff srcCoeff, 122 SkXfermode::Coeff dstCoeff, 123 bool* needSrcValue, 124 bool* needDstValue) { 125 if (SkXfermode::kZero_Coeff == srcCoeff) { 126 switch (dstCoeff) { 127 // these all read the src 128 case SkXfermode::kSC_Coeff: 129 case SkXfermode::kISC_Coeff: 130 case SkXfermode::kSA_Coeff: 131 case SkXfermode::kISA_Coeff: 132 *needSrcValue = true; 133 break; 134 default: 135 *needSrcValue = false; 136 break; 137 } 138 } else { 139 *needSrcValue = true; 140 } 141 if (SkXfermode::kZero_Coeff == dstCoeff) { 142 switch (srcCoeff) { 143 // these all read the dst 144 case SkXfermode::kDC_Coeff: 145 case SkXfermode::kIDC_Coeff: 146 case SkXfermode::kDA_Coeff: 147 case SkXfermode::kIDA_Coeff: 148 *needDstValue = true; 149 break; 150 default: 151 *needDstValue = false; 152 break; 153 } 154 } else { 155 *needDstValue = true; 156 } 157 } 158 159 /** 160 * Create a blend_coeff * value string to be used in shader code. Sets empty 161 * string if result is trivially zero. 162 */ 163 inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff, 164 const char* src, const char* dst, 165 const char* value) { 166 switch (coeff) { 167 case SkXfermode::kZero_Coeff: /** 0 */ 168 *str = ""; 169 break; 170 case SkXfermode::kOne_Coeff: /** 1 */ 171 *str = value; 172 break; 173 case SkXfermode::kSC_Coeff: 174 str->printf("(%s * %s)", src, value); 175 break; 176 case SkXfermode::kISC_Coeff: 177 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value); 178 break; 179 case SkXfermode::kDC_Coeff: 180 str->printf("(%s * %s)", dst, value); 181 break; 182 case SkXfermode::kIDC_Coeff: 183 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value); 184 break; 185 case SkXfermode::kSA_Coeff: /** src alpha */ 186 str->printf("(%s.a * %s)", src, value); 187 break; 188 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ 189 str->printf("((1.0 - %s.a) * %s)", src, value); 190 break; 191 case SkXfermode::kDA_Coeff: /** dst alpha */ 192 str->printf("(%s.a * %s)", dst, value); 193 break; 194 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ 195 str->printf("((1.0 - %s.a) * %s)", dst, value); 196 break; 197 default: 198 GrCrash("Unexpected xfer coeff."); 199 break; 200 } 201 } 202 /** 203 * Adds a line to the fragment shader code which modifies the color by 204 * the specified color filter. 205 */ 206 void add_color_filter(GrGLShaderBuilder* builder, 207 const char * outputVar, 208 SkXfermode::Coeff uniformCoeff, 209 SkXfermode::Coeff colorCoeff, 210 const char* filterColor, 211 const char* inColor) { 212 SkString colorStr, constStr; 213 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); 214 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor); 215 216 SkString sum; 217 GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str()); 218 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); 219 } 220 } 221 222 GrSLConstantVec GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { 223 switch (fDesc.getHeader().fColorInput) { 224 case GrGLProgramDesc::kAttribute_ColorInput: { 225 builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME); 226 const char *vsName, *fsName; 227 builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); 228 builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); 229 *inColor = fsName; 230 return kNone_GrSLConstantVec; 231 } 232 case GrGLProgramDesc::kUniform_ColorInput: { 233 const char* name; 234 fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 235 kVec4f_GrSLType, "Color", &name); 236 *inColor = name; 237 return kNone_GrSLConstantVec; 238 } 239 case GrGLProgramDesc::kTransBlack_ColorInput: 240 inColor->reset(); 241 return kZeros_GrSLConstantVec; 242 case GrGLProgramDesc::kSolidWhite_ColorInput: 243 inColor->reset(); 244 return kOnes_GrSLConstantVec; 245 default: 246 GrCrash("Unknown color type."); 247 return kNone_GrSLConstantVec; 248 } 249 } 250 251 GrSLConstantVec GrGLProgram::genInputCoverage(GrGLShaderBuilder* builder, SkString* inCoverage) { 252 switch (fDesc.getHeader().fCoverageInput) { 253 case GrGLProgramDesc::kAttribute_ColorInput: { 254 builder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME); 255 const char *vsName, *fsName; 256 builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); 257 builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); 258 *inCoverage = fsName; 259 return kNone_GrSLConstantVec; 260 } 261 case GrGLProgramDesc::kUniform_ColorInput: { 262 const char* name; 263 fUniformHandles.fCoverageUni = 264 builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 265 kVec4f_GrSLType, "Coverage", &name); 266 *inCoverage = name; 267 return kNone_GrSLConstantVec; 268 } 269 case GrGLProgramDesc::kTransBlack_ColorInput: 270 inCoverage->reset(); 271 return kZeros_GrSLConstantVec; 272 case GrGLProgramDesc::kSolidWhite_ColorInput: 273 inCoverage->reset(); 274 return kOnes_GrSLConstantVec; 275 default: 276 GrCrash("Unknown color type."); 277 return kNone_GrSLConstantVec; 278 } 279 } 280 281 void GrGLProgram::genGeometryShader(GrGLShaderBuilder* builder) const { 282 #if GR_GL_EXPERIMENTAL_GS 283 // TODO: The builder should add all this glue code. 284 if (fDesc.getHeader().fExperimentalGS) { 285 GrAssert(fContext.info().glslGeneration() >= k150_GrGLSLGeneration); 286 builder->fGSHeader.append("layout(triangles) in;\n" 287 "layout(triangle_strip, max_vertices = 6) out;\n"); 288 builder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" 289 "\t\tgl_Position = gl_in[i].gl_Position;\n"); 290 if (fDesc.getHeader().fEmitsPointSize) { 291 builder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n"); 292 } 293 GrAssert(builder->fGSInputs.count() == builder->fGSOutputs.count()); 294 int count = builder->fGSInputs.count(); 295 for (int i = 0; i < count; ++i) { 296 builder->gsCodeAppendf("\t\t%s = %s[i];\n", 297 builder->fGSOutputs[i].getName().c_str(), 298 builder->fGSInputs[i].getName().c_str()); 299 } 300 builder->gsCodeAppend("\t\tEmitVertex();\n" 301 "\t}\n" 302 "\tEndPrimitive();\n"); 303 } 304 #endif 305 } 306 307 const char* GrGLProgram::adjustInColor(const SkString& inColor) const { 308 if (inColor.size()) { 309 return inColor.c_str(); 310 } else { 311 if (GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.getHeader().fColorInput) { 312 return GrGLSLOnesVecf(4); 313 } else { 314 return GrGLSLZerosVecf(4); 315 } 316 } 317 } 318 319 namespace { 320 // prints a shader using params similar to glShaderSource 321 void print_shader(GrGLint stringCnt, 322 const GrGLchar** strings, 323 GrGLint* stringLengths) { 324 for (int i = 0; i < stringCnt; ++i) { 325 if (NULL == stringLengths || stringLengths[i] < 0) { 326 GrPrintf(strings[i]); 327 } else { 328 GrPrintf("%.*s", stringLengths[i], strings[i]); 329 } 330 } 331 } 332 333 // Compiles a GL shader, returns shader ID or 0 if failed params have same meaning as glShaderSource 334 GrGLuint compile_shader(const GrGLContext& gl, 335 GrGLenum type, 336 int stringCnt, 337 const char** strings, 338 int* stringLengths) { 339 SK_TRACE_EVENT1("GrGLProgram::CompileShader", 340 "stringCount", SkStringPrintf("%i", stringCnt).c_str()); 341 342 GrGLuint shader; 343 GR_GL_CALL_RET(gl.interface(), shader, CreateShader(type)); 344 if (0 == shader) { 345 return 0; 346 } 347 348 const GrGLInterface* gli = gl.interface(); 349 GrGLint compiled = GR_GL_INIT_ZERO; 350 GR_GL_CALL(gli, ShaderSource(shader, stringCnt, strings, stringLengths)); 351 GR_GL_CALL(gli, CompileShader(shader)); 352 GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled)); 353 354 if (!compiled) { 355 GrGLint infoLen = GR_GL_INIT_ZERO; 356 GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen)); 357 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 358 if (infoLen > 0) { 359 // retrieve length even though we don't need it to workaround bug in chrome cmd buffer 360 // param validation. 361 GrGLsizei length = GR_GL_INIT_ZERO; 362 GR_GL_CALL(gli, GetShaderInfoLog(shader, infoLen+1, 363 &length, (char*)log.get())); 364 print_shader(stringCnt, strings, stringLengths); 365 GrPrintf("\n%s", log.get()); 366 } 367 GrAssert(!"Shader compilation failed!"); 368 GR_GL_CALL(gli, DeleteShader(shader)); 369 return 0; 370 } 371 return shader; 372 } 373 374 // helper version of above for when shader is already flattened into a single SkString 375 GrGLuint compile_shader(const GrGLContext& gl, GrGLenum type, const SkString& shader) { 376 const GrGLchar* str = shader.c_str(); 377 int length = shader.size(); 378 return compile_shader(gl, type, 1, &str, &length); 379 } 380 381 void expand_known_value4f(SkString* string, GrSLConstantVec vec) { 382 GrAssert(string->isEmpty() == (vec != kNone_GrSLConstantVec)); 383 switch (vec) { 384 case kNone_GrSLConstantVec: 385 break; 386 case kZeros_GrSLConstantVec: 387 *string = GrGLSLZerosVecf(4); 388 break; 389 case kOnes_GrSLConstantVec: 390 *string = GrGLSLOnesVecf(4); 391 break; 392 } 393 } 394 395 } 396 397 // compiles all the shaders from builder and stores the shader IDs 398 bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) { 399 400 SkString shader; 401 402 builder.getShader(GrGLShaderBuilder::kVertex_ShaderType, &shader); 403 if (c_PrintShaders) { 404 GrPrintf(shader.c_str()); 405 GrPrintf("\n"); 406 } 407 408 if (!(fVShaderID = compile_shader(fContext, GR_GL_VERTEX_SHADER, shader))) { 409 return false; 410 } 411 412 fGShaderID = 0; 413 #if GR_GL_EXPERIMENTAL_GS 414 if (fDesc.getHeader().fExperimentalGS) { 415 builder.getShader(GrGLShaderBuilder::kGeometry_ShaderType, &shader); 416 if (c_PrintShaders) { 417 GrPrintf(shader.c_str()); 418 GrPrintf("\n"); 419 } 420 if (!(fGShaderID = compile_shader(fContext, GR_GL_GEOMETRY_SHADER, shader))) { 421 return false; 422 } 423 } 424 #endif 425 426 builder.getShader(GrGLShaderBuilder::kFragment_ShaderType, &shader); 427 if (c_PrintShaders) { 428 GrPrintf(shader.c_str()); 429 GrPrintf("\n"); 430 } 431 if (!(fFShaderID = compile_shader(fContext, GR_GL_FRAGMENT_SHADER, shader))) { 432 return false; 433 } 434 435 return true; 436 } 437 438 bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], 439 const GrEffectStage* coverageStages[]) { 440 GrAssert(0 == fProgramID); 441 442 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 443 444 GrGLShaderBuilder builder(fContext.info(), fUniformManager, fDesc); 445 446 // the dual source output has no canonical var name, have to 447 // declare an output, which is incompatible with gl_FragColor/gl_FragData. 448 bool dualSourceOutputWritten = false; 449 450 GrGLShaderVar colorOutput; 451 bool isColorDeclared = GrGLSLSetupFSColorOuput(fContext.info().glslGeneration(), 452 declared_color_output_name(), 453 &colorOutput); 454 if (isColorDeclared) { 455 builder.fFSOutputs.push_back(colorOutput); 456 } 457 458 const char* viewMName; 459 fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType, 460 kMat33f_GrSLType, "ViewM", &viewMName); 461 462 463 builder.vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" 464 "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", 465 viewMName, builder.positionAttribute().getName().c_str()); 466 467 // incoming color to current stage being processed. 468 SkString inColor; 469 GrSLConstantVec knownColorValue = this->genInputColor(&builder, &inColor); 470 471 // we output point size in the GS if present 472 if (header.fEmitsPointSize 473 #if GR_GL_EXPERIMENTAL_GS 474 && !header.fExperimentalGS 475 #endif 476 ) { 477 builder.vsCodeAppend("\tgl_PointSize = 1.0;\n"); 478 } 479 480 // Get the coeffs for the Mode-based color filter, determine if color is needed. 481 SkXfermode::Coeff colorCoeff; 482 SkXfermode::Coeff filterColorCoeff; 483 SkAssertResult( 484 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(header.fColorFilterXfermode), 485 &filterColorCoeff, 486 &colorCoeff)); 487 bool needColor, needFilterColor; 488 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor); 489 490 // used in order for builder to return the per-stage uniform handles. 491 typedef SkTArray<GrGLUniformManager::UniformHandle, true>* UniHandleArrayPtr; 492 int maxColorOrCovEffectCnt = GrMax(fDesc.numColorEffects(), fDesc.numCoverageEffects()); 493 SkAutoTArray<UniHandleArrayPtr> effectUniformArrays(maxColorOrCovEffectCnt); 494 SkAutoTArray<GrGLEffect*> glEffects(maxColorOrCovEffectCnt); 495 496 if (needColor) { 497 for (int e = 0; e < fDesc.numColorEffects(); ++e) { 498 effectUniformArrays[e] = &fColorEffects[e].fSamplerUnis; 499 } 500 501 builder.emitEffects(colorStages, 502 fDesc.effectKeys(), 503 fDesc.numColorEffects(), 504 &inColor, 505 &knownColorValue, 506 effectUniformArrays.get(), 507 glEffects.get()); 508 509 for (int e = 0; e < fDesc.numColorEffects(); ++e) { 510 fColorEffects[e].fGLEffect = glEffects[e]; 511 } 512 } 513 514 // Insert the color filter. This will soon be replaced by a color effect. 515 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { 516 const char* colorFilterColorUniName = NULL; 517 fUniformHandles.fColorFilterUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType, 518 kVec4f_GrSLType, "FilterColor", 519 &colorFilterColorUniName); 520 521 builder.fsCodeAppend("\tvec4 filteredColor;\n"); 522 const char* color; 523 // add_color_filter requires a real input string. 524 if (knownColorValue == kOnes_GrSLConstantVec) { 525 color = GrGLSLOnesVecf(4); 526 } else if (knownColorValue == kZeros_GrSLConstantVec) { 527 color = GrGLSLZerosVecf(4); 528 } else { 529 color = inColor.c_str(); 530 } 531 add_color_filter(&builder, "filteredColor", filterColorCoeff, 532 colorCoeff, colorFilterColorUniName, color); 533 inColor = "filteredColor"; 534 } 535 536 /////////////////////////////////////////////////////////////////////////// 537 // compute the partial coverage 538 SkString inCoverage; 539 GrSLConstantVec knownCoverageValue = this->genInputCoverage(&builder, &inCoverage); 540 541 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) { 542 effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis; 543 } 544 545 builder.emitEffects(coverageStages, 546 fDesc.getEffectKeys() + fDesc.numColorEffects(), 547 fDesc.numCoverageEffects(), 548 &inCoverage, 549 &knownCoverageValue, 550 effectUniformArrays.get(), 551 glEffects.get()); 552 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) { 553 fCoverageEffects[e].fGLEffect = glEffects[e]; 554 } 555 556 // discard if coverage is zero 557 if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageValue) { 558 if (kZeros_GrSLConstantVec == knownCoverageValue) { 559 // This is unfortunate. 560 builder.fsCodeAppend("\tdiscard;\n"); 561 } else { 562 builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n", 563 inCoverage.c_str()); 564 } 565 } 566 567 GrGLProgramDesc::CoverageOutput coverageOutput = 568 static_cast<GrGLProgramDesc::CoverageOutput>(header.fCoverageOutput); 569 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(coverageOutput)) { 570 builder.fFSOutputs.push_back().set(kVec4f_GrSLType, 571 GrGLShaderVar::kOut_TypeModifier, 572 dual_source_output_name()); 573 // default coeff to ones for kCoverage_DualSrcOutput 574 SkString coeff; 575 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; 576 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) { 577 // Get (1-A) into coeff 578 SkString inColorAlpha; 579 GrGLSLGetComponent4f(&inColorAlpha, 580 inColor.c_str(), 581 kA_GrColorComponentFlag, 582 knownColorValue, 583 true); 584 knownCoeffValue = GrGLSLSubtractf<1>(&coeff, 585 NULL, 586 inColorAlpha.c_str(), 587 kOnes_GrSLConstantVec, 588 knownColorValue, 589 true); 590 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == coverageOutput) { 591 // Get (1-RGBA) into coeff 592 knownCoeffValue = GrGLSLSubtractf<4>(&coeff, 593 NULL, 594 inColor.c_str(), 595 kOnes_GrSLConstantVec, 596 knownColorValue, 597 true); 598 } 599 // Get coeff * coverage into modulate and then write that to the dual source output. 600 SkString modulate; 601 GrGLSLModulatef<4>(&modulate, 602 coeff.c_str(), 603 inCoverage.c_str(), 604 knownCoeffValue, 605 knownCoverageValue, 606 false); 607 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulate.c_str()); 608 dualSourceOutputWritten = true; 609 } 610 611 /////////////////////////////////////////////////////////////////////////// 612 // combine color and coverage as frag color 613 614 // Get "color * coverage" into fragColor 615 SkString fragColor; 616 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, 617 inColor.c_str(), 618 inCoverage.c_str(), 619 knownColorValue, 620 knownCoverageValue, 621 true); 622 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so. 623 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == coverageOutput) { 624 SkString dstCoeff; 625 GrSLConstantVec knownDstCoeffValue = GrGLSLSubtractf<4>(&dstCoeff, 626 NULL, 627 inCoverage.c_str(), 628 kOnes_GrSLConstantVec, 629 knownCoverageValue, 630 true); 631 SkString dstContribution; 632 GrSLConstantVec knownDstContributionValue = GrGLSLModulatef<4>(&dstContribution, 633 dstCoeff.c_str(), 634 builder.dstColor(), 635 knownDstCoeffValue, 636 kNone_GrSLConstantVec, 637 true); 638 SkString oldFragColor = fragColor; 639 fragColor.reset(); 640 GrGLSLAddf<4>(&fragColor, 641 oldFragColor.c_str(), 642 dstContribution.c_str(), 643 knownFragColorValue, 644 knownDstContributionValue, 645 false); 646 } else { 647 expand_known_value4f(&fragColor, knownFragColorValue); 648 } 649 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), fragColor.c_str()); 650 651 /////////////////////////////////////////////////////////////////////////// 652 // insert GS 653 #if GR_DEBUG 654 this->genGeometryShader(&builder); 655 #endif 656 657 /////////////////////////////////////////////////////////////////////////// 658 // compile and setup attribs and unis 659 660 if (!this->compileShaders(builder)) { 661 return false; 662 } 663 664 if (!this->bindOutputsAttribsAndLinkProgram(builder, 665 isColorDeclared, 666 dualSourceOutputWritten)) { 667 return false; 668 } 669 670 builder.finished(fProgramID); 671 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); 672 fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform(); 673 fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform(); 674 fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform(); 675 // This must be called after we set fDstCopySamplerUni above. 676 this->initSamplerUniforms(); 677 678 return true; 679 } 680 681 bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder, 682 bool bindColorOut, 683 bool bindDualSrcOut) { 684 GL_CALL_RET(fProgramID, CreateProgram()); 685 if (!fProgramID) { 686 return false; 687 } 688 689 GL_CALL(AttachShader(fProgramID, fVShaderID)); 690 if (fGShaderID) { 691 GL_CALL(AttachShader(fProgramID, fGShaderID)); 692 } 693 GL_CALL(AttachShader(fProgramID, fFShaderID)); 694 695 if (bindColorOut) { 696 GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name())); 697 } 698 if (bindDualSrcOut) { 699 GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output_name())); 700 } 701 702 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 703 704 // Bind the attrib locations to same values for all shaders 705 GL_CALL(BindAttribLocation(fProgramID, 706 header.fPositionAttributeIndex, 707 builder.positionAttribute().c_str())); 708 if (-1 != header.fLocalCoordAttributeIndex) { 709 GL_CALL(BindAttribLocation(fProgramID, 710 header.fLocalCoordAttributeIndex, 711 builder.localCoordsAttribute().c_str())); 712 } 713 if (-1 != header.fColorAttributeIndex) { 714 GL_CALL(BindAttribLocation(fProgramID, header.fColorAttributeIndex, COL_ATTR_NAME)); 715 } 716 if (-1 != header.fCoverageAttributeIndex) { 717 GL_CALL(BindAttribLocation(fProgramID, header.fCoverageAttributeIndex, COV_ATTR_NAME)); 718 } 719 720 const GrGLShaderBuilder::AttributePair* attribEnd = builder.getEffectAttributes().end(); 721 for (const GrGLShaderBuilder::AttributePair* attrib = builder.getEffectAttributes().begin(); 722 attrib != attribEnd; 723 ++attrib) { 724 GL_CALL(BindAttribLocation(fProgramID, attrib->fIndex, attrib->fName.c_str())); 725 } 726 727 GL_CALL(LinkProgram(fProgramID)); 728 729 GrGLint linked = GR_GL_INIT_ZERO; 730 GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked)); 731 if (!linked) { 732 GrGLint infoLen = GR_GL_INIT_ZERO; 733 GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen)); 734 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 735 if (infoLen > 0) { 736 // retrieve length even though we don't need it to workaround 737 // bug in chrome cmd buffer param validation. 738 GrGLsizei length = GR_GL_INIT_ZERO; 739 GL_CALL(GetProgramInfoLog(fProgramID, 740 infoLen+1, 741 &length, 742 (char*)log.get())); 743 GrPrintf((char*)log.get()); 744 } 745 GrAssert(!"Error linking program"); 746 GL_CALL(DeleteProgram(fProgramID)); 747 fProgramID = 0; 748 return false; 749 } 750 return true; 751 } 752 753 void GrGLProgram::initSamplerUniforms() { 754 GL_CALL(UseProgram(fProgramID)); 755 GrGLint texUnitIdx = 0; 756 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fDstCopySamplerUni) { 757 fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitIdx); 758 fDstCopyTexUnit = texUnitIdx++; 759 } 760 761 for (int e = 0; e < fColorEffects.count(); ++e) { 762 this->initEffectSamplerUniforms(&fColorEffects[e], &texUnitIdx); 763 } 764 765 for (int e = 0; e < fCoverageEffects.count(); ++e) { 766 this->initEffectSamplerUniforms(&fCoverageEffects[e], &texUnitIdx); 767 } 768 } 769 770 void GrGLProgram::initEffectSamplerUniforms(EffectAndSamplers* effect, int* texUnitIdx) { 771 int numSamplers = effect->fSamplerUnis.count(); 772 effect->fTextureUnits.reset(numSamplers); 773 for (int s = 0; s < numSamplers; ++s) { 774 UniformHandle handle = effect->fSamplerUnis[s]; 775 if (GrGLUniformManager::kInvalidUniformHandle != handle) { 776 fUniformManager.setSampler(handle, *texUnitIdx); 777 effect->fTextureUnits[s] = (*texUnitIdx)++; 778 } 779 } 780 } 781 782 /////////////////////////////////////////////////////////////////////////////// 783 784 void GrGLProgram::setEffectData(GrGpuGL* gpu, 785 const GrEffectStage& stage, 786 const EffectAndSamplers& effect) { 787 788 // Let the GrGLEffect set its data. 789 bool explicitLocalCoords = -1 != fDesc.getHeader().fLocalCoordAttributeIndex; 790 GrDrawEffect drawEffect(stage, explicitLocalCoords); 791 effect.fGLEffect->setData(fUniformManager, drawEffect); 792 793 // Bind the texures for the effect. 794 int numSamplers = effect.fSamplerUnis.count(); 795 GrAssert((*stage.getEffect())->numTextures() == numSamplers); 796 for (int s = 0; s < numSamplers; ++s) { 797 UniformHandle handle = effect.fSamplerUnis[s]; 798 if (GrGLUniformManager::kInvalidUniformHandle != handle) { 799 const GrTextureAccess& access = (*stage.getEffect())->textureAccess(s); 800 GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture()); 801 int unit = effect.fTextureUnits[s]; 802 gpu->bindTexture(unit, access.getParams(), texture); 803 } 804 } 805 } 806 807 void GrGLProgram::setData(GrGpuGL* gpu, 808 GrDrawState::BlendOptFlags blendOpts, 809 const GrEffectStage* colorStages[], 810 const GrEffectStage* coverageStages[], 811 const GrDeviceCoordTexture* dstCopy, 812 SharedGLState* sharedState) { 813 const GrDrawState& drawState = gpu->getDrawState(); 814 815 GrColor color; 816 GrColor coverage; 817 if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) { 818 color = 0; 819 coverage = 0; 820 } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) { 821 color = 0xffffffff; 822 coverage = drawState.getCoverage(); 823 } else { 824 color = drawState.getColor(); 825 coverage = drawState.getCoverage(); 826 } 827 828 this->setColor(drawState, color, sharedState); 829 this->setCoverage(drawState, coverage, sharedState); 830 this->setMatrixAndRenderTargetHeight(drawState); 831 832 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary 833 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fColorFilterUni && 834 fColorFilterColor != drawState.getColorFilterColor()) { 835 GrGLfloat c[4]; 836 GrColorToRGBAFloat(drawState.getColorFilterColor(), c); 837 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c); 838 fColorFilterColor = drawState.getColorFilterColor(); 839 } 840 841 if (NULL != dstCopy) { 842 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fDstCopyTopLeftUni) { 843 GrAssert(GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fDstCopyScaleUni); 844 GrAssert(GrGLUniformManager::kInvalidUniformHandle != 845 fUniformHandles.fDstCopySamplerUni); 846 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, 847 static_cast<GrGLfloat>(dstCopy->offset().fX), 848 static_cast<GrGLfloat>(dstCopy->offset().fY)); 849 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, 850 1.f / dstCopy->texture()->width(), 851 1.f / dstCopy->texture()->height()); 852 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()); 853 static GrTextureParams kParams; // the default is clamp, nearest filtering. 854 gpu->bindTexture(fDstCopyTexUnit, kParams, texture); 855 } else { 856 GrAssert(GrGLUniformManager::kInvalidUniformHandle == 857 fUniformHandles.fDstCopyScaleUni); 858 GrAssert(GrGLUniformManager::kInvalidUniformHandle == 859 fUniformHandles.fDstCopySamplerUni); 860 } 861 } else { 862 GrAssert(GrGLUniformManager::kInvalidUniformHandle == fUniformHandles.fDstCopyTopLeftUni); 863 GrAssert(GrGLUniformManager::kInvalidUniformHandle == fUniformHandles.fDstCopyScaleUni); 864 GrAssert(GrGLUniformManager::kInvalidUniformHandle == fUniformHandles.fDstCopySamplerUni); 865 } 866 867 for (int e = 0; e < fColorEffects.count(); ++e) { 868 // We may have omitted the GrGLEffect because of the color filter logic in genProgram. 869 // This can be removed when the color filter is an effect. 870 if (NULL != fColorEffects[e].fGLEffect) { 871 this->setEffectData(gpu, *colorStages[e], fColorEffects[e]); 872 } 873 } 874 875 for (int e = 0; e < fCoverageEffects.count(); ++e) { 876 if (NULL != fCoverageEffects[e].fGLEffect) { 877 this->setEffectData(gpu, *coverageStages[e], fCoverageEffects[e]); 878 } 879 } 880 } 881 882 void GrGLProgram::setColor(const GrDrawState& drawState, 883 GrColor color, 884 SharedGLState* sharedState) { 885 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 886 if (!drawState.hasColorVertexAttribute()) { 887 switch (header.fColorInput) { 888 case GrGLProgramDesc::kAttribute_ColorInput: 889 GrAssert(-1 != header.fColorAttributeIndex); 890 if (sharedState->fConstAttribColor != color || 891 sharedState->fConstAttribColorIndex != header.fColorAttributeIndex) { 892 // OpenGL ES only supports the float varieties of glVertexAttrib 893 GrGLfloat c[4]; 894 GrColorToRGBAFloat(color, c); 895 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); 896 sharedState->fConstAttribColor = color; 897 sharedState->fConstAttribColorIndex = header.fColorAttributeIndex; 898 } 899 break; 900 case GrGLProgramDesc::kUniform_ColorInput: 901 if (fColor != color) { 902 // OpenGL ES doesn't support unsigned byte varieties of glUniform 903 GrGLfloat c[4]; 904 GrColorToRGBAFloat(color, c); 905 GrAssert(GrGLUniformManager::kInvalidUniformHandle != 906 fUniformHandles.fColorUni); 907 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); 908 fColor = color; 909 } 910 sharedState->fConstAttribColorIndex = -1; 911 break; 912 case GrGLProgramDesc::kSolidWhite_ColorInput: 913 case GrGLProgramDesc::kTransBlack_ColorInput: 914 sharedState->fConstAttribColorIndex = -1; 915 break; 916 default: 917 GrCrash("Unknown color type."); 918 } 919 } else { 920 sharedState->fConstAttribColorIndex = -1; 921 } 922 } 923 924 void GrGLProgram::setCoverage(const GrDrawState& drawState, 925 GrColor coverage, 926 SharedGLState* sharedState) { 927 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 928 if (!drawState.hasCoverageVertexAttribute()) { 929 switch (header.fCoverageInput) { 930 case GrGLProgramDesc::kAttribute_ColorInput: 931 if (sharedState->fConstAttribCoverage != coverage || 932 sharedState->fConstAttribCoverageIndex != header.fCoverageAttributeIndex) { 933 // OpenGL ES only supports the float varieties of glVertexAttrib 934 GrGLfloat c[4]; 935 GrColorToRGBAFloat(coverage, c); 936 GL_CALL(VertexAttrib4fv(header.fCoverageAttributeIndex, c)); 937 sharedState->fConstAttribCoverage = coverage; 938 sharedState->fConstAttribCoverageIndex = header.fCoverageAttributeIndex; 939 } 940 break; 941 case GrGLProgramDesc::kUniform_ColorInput: 942 if (fCoverage != coverage) { 943 // OpenGL ES doesn't support unsigned byte varieties of glUniform 944 GrGLfloat c[4]; 945 GrColorToRGBAFloat(coverage, c); 946 GrAssert(GrGLUniformManager::kInvalidUniformHandle != 947 fUniformHandles.fCoverageUni); 948 fUniformManager.set4fv(fUniformHandles.fCoverageUni, 0, 1, c); 949 fCoverage = coverage; 950 } 951 sharedState->fConstAttribCoverageIndex = -1; 952 break; 953 case GrGLProgramDesc::kSolidWhite_ColorInput: 954 case GrGLProgramDesc::kTransBlack_ColorInput: 955 sharedState->fConstAttribCoverageIndex = -1; 956 break; 957 default: 958 GrCrash("Unknown coverage type."); 959 } 960 } else { 961 sharedState->fConstAttribCoverageIndex = -1; 962 } 963 } 964 965 void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) { 966 const GrRenderTarget* rt = drawState.getRenderTarget(); 967 SkISize size; 968 size.set(rt->width(), rt->height()); 969 970 // Load the RT height uniform if it is needed to y-flip gl_FragCoord. 971 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fRTHeightUni && 972 fMatrixState.fRenderTargetSize.fHeight != size.fHeight) { 973 fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight)); 974 } 975 976 if (fMatrixState.fRenderTargetOrigin != rt->origin() || 977 !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) || 978 fMatrixState.fRenderTargetSize != size) { 979 SkMatrix m; 980 if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { 981 m.setAll( 982 SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1, 983 0,-SkIntToScalar(2) / size.fHeight, SK_Scalar1, 984 0, 0, SkMatrix::I()[8]); 985 } else { 986 m.setAll( 987 SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1, 988 0, SkIntToScalar(2) / size.fHeight,-SK_Scalar1, 989 0, 0, SkMatrix::I()[8]); 990 } 991 m.setConcat(m, drawState.getViewMatrix()); 992 993 // ES doesn't allow you to pass true to the transpose param so we do our own transpose. 994 GrGLfloat mt[] = { 995 SkScalarToFloat(m[SkMatrix::kMScaleX]), 996 SkScalarToFloat(m[SkMatrix::kMSkewY]), 997 SkScalarToFloat(m[SkMatrix::kMPersp0]), 998 SkScalarToFloat(m[SkMatrix::kMSkewX]), 999 SkScalarToFloat(m[SkMatrix::kMScaleY]), 1000 SkScalarToFloat(m[SkMatrix::kMPersp1]), 1001 SkScalarToFloat(m[SkMatrix::kMTransX]), 1002 SkScalarToFloat(m[SkMatrix::kMTransY]), 1003 SkScalarToFloat(m[SkMatrix::kMPersp2]) 1004 }; 1005 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); 1006 fMatrixState.fViewMatrix = drawState.getViewMatrix(); 1007 fMatrixState.fRenderTargetSize = size; 1008 fMatrixState.fRenderTargetOrigin = rt->origin(); 1009 } 1010 } 1011