GrGLProgram.cpp revision 949eef0af2f5b47000e637347801cf2970092a38
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 "SkXfermode.h" 18 19SK_DEFINE_INST_COUNT(GrGLProgram) 20 21#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) 22#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) 23 24GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu, 25 const GrGLProgramDesc& desc, 26 const GrEffectStage* colorStages[], 27 const GrEffectStage* coverageStages[]) { 28 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gpu, desc, colorStages, coverageStages)); 29 if (!program->succeeded()) { 30 delete program; 31 program = NULL; 32 } 33 return program; 34} 35 36GrGLProgram::GrGLProgram(GrGpuGL* gpu, 37 const GrGLProgramDesc& desc, 38 const GrEffectStage* colorStages[], 39 const GrEffectStage* coverageStages[]) 40: fGpu(gpu) 41, fUniformManager(gpu) { 42 fDesc = desc; 43 fProgramID = 0; 44 45 fDstCopyTexUnit = -1; 46 47 fColor = GrColor_ILLEGAL; 48 fColorFilterColor = GrColor_ILLEGAL; 49 50 fColorEffects.reset(desc.numColorEffects()); 51 fCoverageEffects.reset(desc.numCoverageEffects()); 52 53 this->genProgram(colorStages, coverageStages); 54} 55 56GrGLProgram::~GrGLProgram() { 57 if (fProgramID) { 58 GL_CALL(DeleteProgram(fProgramID)); 59 } 60} 61 62void GrGLProgram::abandon() { 63 fProgramID = 0; 64} 65 66void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, 67 GrBlendCoeff* dstCoeff) const { 68 switch (fDesc.getHeader().fCoverageOutput) { 69 case GrGLProgramDesc::kModulate_CoverageOutput: 70 break; 71 // The prog will write a coverage value to the secondary 72 // output and the dst is blended by one minus that value. 73 case GrGLProgramDesc::kSecondaryCoverage_CoverageOutput: 74 case GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput: 75 case GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput: 76 *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; 77 break; 78 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: 79 // We should only have set this if the blend was specified as (1, 0) 80 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *dstCoeff); 81 break; 82 default: 83 GrCrash("Unexpected coverage output"); 84 break; 85 } 86} 87 88namespace { 89// given two blend coefficients determine whether the src 90// and/or dst computation can be omitted. 91inline void need_blend_inputs(SkXfermode::Coeff srcCoeff, 92 SkXfermode::Coeff dstCoeff, 93 bool* needSrcValue, 94 bool* needDstValue) { 95 if (SkXfermode::kZero_Coeff == srcCoeff) { 96 switch (dstCoeff) { 97 // these all read the src 98 case SkXfermode::kSC_Coeff: 99 case SkXfermode::kISC_Coeff: 100 case SkXfermode::kSA_Coeff: 101 case SkXfermode::kISA_Coeff: 102 *needSrcValue = true; 103 break; 104 default: 105 *needSrcValue = false; 106 break; 107 } 108 } else { 109 *needSrcValue = true; 110 } 111 if (SkXfermode::kZero_Coeff == dstCoeff) { 112 switch (srcCoeff) { 113 // these all read the dst 114 case SkXfermode::kDC_Coeff: 115 case SkXfermode::kIDC_Coeff: 116 case SkXfermode::kDA_Coeff: 117 case SkXfermode::kIDA_Coeff: 118 *needDstValue = true; 119 break; 120 default: 121 *needDstValue = false; 122 break; 123 } 124 } else { 125 *needDstValue = true; 126 } 127} 128 129/** 130 * Create a blend_coeff * value string to be used in shader code. Sets empty 131 * string if result is trivially zero. 132 */ 133inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff, 134 const char* src, const char* dst, 135 const char* value) { 136 switch (coeff) { 137 case SkXfermode::kZero_Coeff: /** 0 */ 138 *str = ""; 139 break; 140 case SkXfermode::kOne_Coeff: /** 1 */ 141 *str = value; 142 break; 143 case SkXfermode::kSC_Coeff: 144 str->printf("(%s * %s)", src, value); 145 break; 146 case SkXfermode::kISC_Coeff: 147 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value); 148 break; 149 case SkXfermode::kDC_Coeff: 150 str->printf("(%s * %s)", dst, value); 151 break; 152 case SkXfermode::kIDC_Coeff: 153 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value); 154 break; 155 case SkXfermode::kSA_Coeff: /** src alpha */ 156 str->printf("(%s.a * %s)", src, value); 157 break; 158 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ 159 str->printf("((1.0 - %s.a) * %s)", src, value); 160 break; 161 case SkXfermode::kDA_Coeff: /** dst alpha */ 162 str->printf("(%s.a * %s)", dst, value); 163 break; 164 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ 165 str->printf("((1.0 - %s.a) * %s)", dst, value); 166 break; 167 default: 168 GrCrash("Unexpected xfer coeff."); 169 break; 170 } 171} 172/** 173 * Adds a line to the fragment shader code which modifies the color by 174 * the specified color filter. 175 */ 176void add_color_filter(GrGLShaderBuilder* builder, 177 const char * outputVar, 178 SkXfermode::Coeff uniformCoeff, 179 SkXfermode::Coeff colorCoeff, 180 const char* filterColor, 181 const char* inColor) { 182 SkString colorStr, constStr; 183 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); 184 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor); 185 186 SkString sum; 187 GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str()); 188 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); 189} 190} 191 192namespace { 193 194void expand_known_value4f(SkString* string, GrSLConstantVec vec) { 195 SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec)); 196 switch (vec) { 197 case kNone_GrSLConstantVec: 198 break; 199 case kZeros_GrSLConstantVec: 200 *string = GrGLSLZerosVecf(4); 201 break; 202 case kOnes_GrSLConstantVec: 203 *string = GrGLSLOnesVecf(4); 204 break; 205 } 206} 207 208} 209 210bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], 211 const GrEffectStage* coverageStages[]) { 212 SkASSERT(0 == fProgramID); 213 214 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 215 216 bool needsVertexShader = true; 217 218 GrGLShaderBuilder builder(fGpu, fUniformManager, fDesc, needsVertexShader); 219 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) { 220 fUniformHandles.fViewMatrixUni = vertexBuilder->getViewMatrixUniform(); 221 } 222 223 // incoming color to current stage being processed. 224 SkString inColor = builder.getInputColor(); 225 GrSLConstantVec knownColorValue = builder.getKnownColorValue(); 226 227 // Get the coeffs for the Mode-based color filter, determine if color is needed. 228 SkXfermode::Coeff colorCoeff; 229 SkXfermode::Coeff filterColorCoeff; 230 SkAssertResult( 231 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, 232 &filterColorCoeff, 233 &colorCoeff)); 234 bool needColor, needFilterColor; 235 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor); 236 237 // used in order for builder to return the per-stage uniform handles. 238 typedef SkTArray<GrGLUniformManager::UniformHandle, true>* UniHandleArrayPtr; 239 int maxColorOrCovEffectCnt = GrMax(fDesc.numColorEffects(), fDesc.numCoverageEffects()); 240 SkAutoTArray<UniHandleArrayPtr> effectUniformArrays(maxColorOrCovEffectCnt); 241 SkAutoTArray<GrGLEffect*> glEffects(maxColorOrCovEffectCnt); 242 243 if (needColor) { 244 for (int e = 0; e < fDesc.numColorEffects(); ++e) { 245 effectUniformArrays[e] = &fColorEffects[e].fSamplerUnis; 246 } 247 248 builder.emitEffects(colorStages, 249 fDesc.effectKeys(), 250 fDesc.numColorEffects(), 251 &inColor, 252 &knownColorValue, 253 effectUniformArrays.get(), 254 glEffects.get()); 255 256 for (int e = 0; e < fDesc.numColorEffects(); ++e) { 257 fColorEffects[e].fGLEffect = glEffects[e]; 258 } 259 } 260 261 // Insert the color filter. This will soon be replaced by a color effect. 262 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { 263 const char* colorFilterColorUniName = NULL; 264 fUniformHandles.fColorFilterUni = builder.addUniform(GrGLShaderBuilder::kFragment_Visibility, 265 kVec4f_GrSLType, "FilterColor", 266 &colorFilterColorUniName); 267 268 builder.fsCodeAppend("\tvec4 filteredColor;\n"); 269 const char* color; 270 // add_color_filter requires a real input string. 271 if (knownColorValue == kOnes_GrSLConstantVec) { 272 color = GrGLSLOnesVecf(4); 273 } else if (knownColorValue == kZeros_GrSLConstantVec) { 274 color = GrGLSLZerosVecf(4); 275 } else { 276 color = inColor.c_str(); 277 } 278 add_color_filter(&builder, "filteredColor", filterColorCoeff, 279 colorCoeff, colorFilterColorUniName, color); 280 inColor = "filteredColor"; 281 } 282 283 /////////////////////////////////////////////////////////////////////////// 284 // compute the partial coverage 285 SkString inCoverage = builder.getInputCoverage(); 286 GrSLConstantVec knownCoverageValue = builder.getKnownCoverageValue(); 287 288 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) { 289 effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis; 290 } 291 292 builder.emitEffects(coverageStages, 293 fDesc.getEffectKeys() + fDesc.numColorEffects(), 294 fDesc.numCoverageEffects(), 295 &inCoverage, 296 &knownCoverageValue, 297 effectUniformArrays.get(), 298 glEffects.get()); 299 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) { 300 fCoverageEffects[e].fGLEffect = glEffects[e]; 301 } 302 303 // discard if coverage is zero 304 if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageValue) { 305 if (kZeros_GrSLConstantVec == knownCoverageValue) { 306 // This is unfortunate. 307 builder.fsCodeAppend("\tdiscard;\n"); 308 } else { 309 builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n", 310 inCoverage.c_str()); 311 } 312 } 313 314 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) { 315 const char* secondaryOutputName = builder.enableSecondaryOutput(); 316 317 // default coeff to ones for kCoverage_DualSrcOutput 318 SkString coeff; 319 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; 320 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) { 321 // Get (1-A) into coeff 322 SkString inColorAlpha; 323 GrGLSLGetComponent4f(&inColorAlpha, 324 inColor.c_str(), 325 kA_GrColorComponentFlag, 326 knownColorValue, 327 true); 328 knownCoeffValue = GrGLSLSubtractf<1>(&coeff, 329 NULL, 330 inColorAlpha.c_str(), 331 kOnes_GrSLConstantVec, 332 knownColorValue, 333 true); 334 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == header.fCoverageOutput) { 335 // Get (1-RGBA) into coeff 336 knownCoeffValue = GrGLSLSubtractf<4>(&coeff, 337 NULL, 338 inColor.c_str(), 339 kOnes_GrSLConstantVec, 340 knownColorValue, 341 true); 342 } 343 // Get coeff * coverage into modulate and then write that to the dual source output. 344 SkString modulate; 345 GrGLSLModulatef<4>(&modulate, 346 coeff.c_str(), 347 inCoverage.c_str(), 348 knownCoeffValue, 349 knownCoverageValue, 350 false); 351 builder.fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_str()); 352 } 353 354 /////////////////////////////////////////////////////////////////////////// 355 // combine color and coverage as frag color 356 357 // Get "color * coverage" into fragColor 358 SkString fragColor; 359 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, 360 inColor.c_str(), 361 inCoverage.c_str(), 362 knownColorValue, 363 knownCoverageValue, 364 true); 365 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so. 366 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) { 367 SkString dstCoeff; 368 GrSLConstantVec knownDstCoeffValue = GrGLSLSubtractf<4>(&dstCoeff, 369 NULL, 370 inCoverage.c_str(), 371 kOnes_GrSLConstantVec, 372 knownCoverageValue, 373 true); 374 SkString dstContribution; 375 GrSLConstantVec knownDstContributionValue = GrGLSLModulatef<4>(&dstContribution, 376 dstCoeff.c_str(), 377 builder.dstColor(), 378 knownDstCoeffValue, 379 kNone_GrSLConstantVec, 380 true); 381 SkString oldFragColor = fragColor; 382 fragColor.reset(); 383 GrGLSLAddf<4>(&fragColor, 384 oldFragColor.c_str(), 385 dstContribution.c_str(), 386 knownFragColorValue, 387 knownDstContributionValue, 388 false); 389 } else { 390 expand_known_value4f(&fragColor, knownFragColorValue); 391 } 392 builder.fsCodeAppendf("\t%s = %s;\n", builder.getColorOutputName(), fragColor.c_str()); 393 394 if (!builder.finish(&fProgramID)) { 395 return false; 396 } 397 398 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); 399 fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform(); 400 fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform(); 401 fUniformHandles.fColorUni = builder.getColorUniform(); 402 fUniformHandles.fCoverageUni = builder.getCoverageUniform(); 403 fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform(); 404 // This must be called after we set fDstCopySamplerUni above. 405 this->initSamplerUniforms(); 406 407 return true; 408} 409 410void GrGLProgram::initSamplerUniforms() { 411 GL_CALL(UseProgram(fProgramID)); 412 GrGLint texUnitIdx = 0; 413 if (fUniformHandles.fDstCopySamplerUni.isValid()) { 414 fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitIdx); 415 fDstCopyTexUnit = texUnitIdx++; 416 } 417 418 for (int e = 0; e < fColorEffects.count(); ++e) { 419 this->initEffectSamplerUniforms(&fColorEffects[e], &texUnitIdx); 420 } 421 422 for (int e = 0; e < fCoverageEffects.count(); ++e) { 423 this->initEffectSamplerUniforms(&fCoverageEffects[e], &texUnitIdx); 424 } 425} 426 427void GrGLProgram::initEffectSamplerUniforms(EffectAndSamplers* effect, int* texUnitIdx) { 428 int numSamplers = effect->fSamplerUnis.count(); 429 effect->fTextureUnits.reset(numSamplers); 430 for (int s = 0; s < numSamplers; ++s) { 431 UniformHandle handle = effect->fSamplerUnis[s]; 432 if (handle.isValid()) { 433 fUniformManager.setSampler(handle, *texUnitIdx); 434 effect->fTextureUnits[s] = (*texUnitIdx)++; 435 } 436 } 437} 438 439/////////////////////////////////////////////////////////////////////////////// 440 441void GrGLProgram::setEffectData(const GrEffectStage& stage, 442 const EffectAndSamplers& effect) { 443 444 // Let the GrGLEffect set its data. 445 bool explicitLocalCoords = -1 != fDesc.getHeader().fLocalCoordAttributeIndex; 446 GrDrawEffect drawEffect(stage, explicitLocalCoords); 447 effect.fGLEffect->setData(fUniformManager, drawEffect); 448 449 // Bind the texures for the effect. 450 int numSamplers = effect.fSamplerUnis.count(); 451 SkASSERT((*stage.getEffect())->numTextures() == numSamplers); 452 for (int s = 0; s < numSamplers; ++s) { 453 UniformHandle handle = effect.fSamplerUnis[s]; 454 if (handle.isValid()) { 455 const GrTextureAccess& access = (*stage.getEffect())->textureAccess(s); 456 GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture()); 457 int unit = effect.fTextureUnits[s]; 458 fGpu->bindTexture(unit, access.getParams(), texture); 459 } 460 } 461} 462 463void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts, 464 const GrEffectStage* colorStages[], 465 const GrEffectStage* coverageStages[], 466 const GrDeviceCoordTexture* dstCopy, 467 SharedGLState* sharedState) { 468 const GrDrawState& drawState = fGpu->getDrawState(); 469 470 GrColor color; 471 GrColor coverage; 472 if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) { 473 color = 0; 474 coverage = 0; 475 } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) { 476 color = 0xffffffff; 477 coverage = drawState.getCoverage(); 478 } else { 479 color = drawState.getColor(); 480 coverage = drawState.getCoverage(); 481 } 482 483 this->setColor(drawState, color, sharedState); 484 this->setCoverage(drawState, coverage, sharedState); 485 this->setMatrixAndRenderTargetHeight(drawState); 486 487 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary 488 if (fUniformHandles.fColorFilterUni.isValid() && 489 fColorFilterColor != drawState.getColorFilterColor()) { 490 GrGLfloat c[4]; 491 GrColorToRGBAFloat(drawState.getColorFilterColor(), c); 492 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c); 493 fColorFilterColor = drawState.getColorFilterColor(); 494 } 495 496 if (NULL != dstCopy) { 497 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { 498 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, 499 static_cast<GrGLfloat>(dstCopy->offset().fX), 500 static_cast<GrGLfloat>(dstCopy->offset().fY)); 501 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, 502 1.f / dstCopy->texture()->width(), 503 1.f / dstCopy->texture()->height()); 504 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()); 505 static GrTextureParams kParams; // the default is clamp, nearest filtering. 506 fGpu->bindTexture(fDstCopyTexUnit, kParams, texture); 507 } else { 508 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid()); 509 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); 510 } 511 } else { 512 SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid()); 513 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid()); 514 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); 515 } 516 517 for (int e = 0; e < fColorEffects.count(); ++e) { 518 // We may have omitted the GrGLEffect because of the color filter logic in genProgram. 519 // This can be removed when the color filter is an effect. 520 if (NULL != fColorEffects[e].fGLEffect) { 521 this->setEffectData(*colorStages[e], fColorEffects[e]); 522 } 523 } 524 525 for (int e = 0; e < fCoverageEffects.count(); ++e) { 526 if (NULL != fCoverageEffects[e].fGLEffect) { 527 this->setEffectData(*coverageStages[e], fCoverageEffects[e]); 528 } 529 } 530} 531 532void GrGLProgram::setColor(const GrDrawState& drawState, 533 GrColor color, 534 SharedGLState* sharedState) { 535 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 536 if (!drawState.hasColorVertexAttribute()) { 537 switch (header.fColorInput) { 538 case GrGLProgramDesc::kAttribute_ColorInput: 539 SkASSERT(-1 != header.fColorAttributeIndex); 540 if (sharedState->fConstAttribColor != color || 541 sharedState->fConstAttribColorIndex != header.fColorAttributeIndex) { 542 // OpenGL ES only supports the float varieties of glVertexAttrib 543 GrGLfloat c[4]; 544 GrColorToRGBAFloat(color, c); 545 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); 546 sharedState->fConstAttribColor = color; 547 sharedState->fConstAttribColorIndex = header.fColorAttributeIndex; 548 } 549 break; 550 case GrGLProgramDesc::kUniform_ColorInput: 551 if (fColor != color) { 552 // OpenGL ES doesn't support unsigned byte varieties of glUniform 553 GrGLfloat c[4]; 554 GrColorToRGBAFloat(color, c); 555 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); 556 fColor = color; 557 } 558 sharedState->fConstAttribColorIndex = -1; 559 break; 560 case GrGLProgramDesc::kSolidWhite_ColorInput: 561 case GrGLProgramDesc::kTransBlack_ColorInput: 562 sharedState->fConstAttribColorIndex = -1; 563 break; 564 default: 565 GrCrash("Unknown color type."); 566 } 567 } else { 568 sharedState->fConstAttribColorIndex = -1; 569 } 570} 571 572void GrGLProgram::setCoverage(const GrDrawState& drawState, 573 GrColor coverage, 574 SharedGLState* sharedState) { 575 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 576 if (!drawState.hasCoverageVertexAttribute()) { 577 switch (header.fCoverageInput) { 578 case GrGLProgramDesc::kAttribute_ColorInput: 579 if (sharedState->fConstAttribCoverage != coverage || 580 sharedState->fConstAttribCoverageIndex != header.fCoverageAttributeIndex) { 581 // OpenGL ES only supports the float varieties of glVertexAttrib 582 GrGLfloat c[4]; 583 GrColorToRGBAFloat(coverage, c); 584 GL_CALL(VertexAttrib4fv(header.fCoverageAttributeIndex, c)); 585 sharedState->fConstAttribCoverage = coverage; 586 sharedState->fConstAttribCoverageIndex = header.fCoverageAttributeIndex; 587 } 588 break; 589 case GrGLProgramDesc::kUniform_ColorInput: 590 if (fCoverage != coverage) { 591 // OpenGL ES doesn't support unsigned byte varieties of glUniform 592 GrGLfloat c[4]; 593 GrColorToRGBAFloat(coverage, c); 594 fUniformManager.set4fv(fUniformHandles.fCoverageUni, 0, 1, c); 595 fCoverage = coverage; 596 } 597 sharedState->fConstAttribCoverageIndex = -1; 598 break; 599 case GrGLProgramDesc::kSolidWhite_ColorInput: 600 case GrGLProgramDesc::kTransBlack_ColorInput: 601 sharedState->fConstAttribCoverageIndex = -1; 602 break; 603 default: 604 GrCrash("Unknown coverage type."); 605 } 606 } else { 607 sharedState->fConstAttribCoverageIndex = -1; 608 } 609} 610 611void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) { 612 const GrRenderTarget* rt = drawState.getRenderTarget(); 613 SkISize size; 614 size.set(rt->width(), rt->height()); 615 616 // Load the RT height uniform if it is needed to y-flip gl_FragCoord. 617 if (fUniformHandles.fRTHeightUni.isValid() && 618 fMatrixState.fRenderTargetSize.fHeight != size.fHeight) { 619 fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight)); 620 } 621 622 if (fMatrixState.fRenderTargetOrigin != rt->origin() || 623 !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) || 624 fMatrixState.fRenderTargetSize != size) { 625 626 fMatrixState.fViewMatrix = drawState.getViewMatrix(); 627 fMatrixState.fRenderTargetSize = size; 628 fMatrixState.fRenderTargetOrigin = rt->origin(); 629 630 GrGLfloat viewMatrix[3 * 3]; 631 fMatrixState.getGLMatrix<3>(viewMatrix); 632 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); 633 } 634} 635