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