| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "effects/GrPorterDuffXferProcessor.h" | 8 #include "effects/GrPorterDuffXferProcessor.h" |
| 9 | 9 |
| 10 #include "GrBlend.h" | 10 #include "GrBlend.h" |
| 11 #include "GrDrawTargetCaps.h" | 11 #include "GrDrawTargetCaps.h" |
| 12 #include "GrInvariantOutput.h" | |
| 13 #include "GrProcessor.h" | 12 #include "GrProcessor.h" |
| 14 #include "GrProcOptInfo.h" | 13 #include "GrProcOptInfo.h" |
| 15 #include "GrTypes.h" | 14 #include "GrTypes.h" |
| 16 #include "GrXferProcessor.h" | 15 #include "GrXferProcessor.h" |
| 17 #include "gl/GrGLXferProcessor.h" | 16 #include "gl/GrGLXferProcessor.h" |
| 18 #include "gl/builders/GrGLFragmentShaderBuilder.h" | 17 #include "gl/builders/GrGLFragmentShaderBuilder.h" |
| 19 #include "gl/builders/GrGLProgramBuilder.h" | 18 #include "gl/builders/GrGLProgramBuilder.h" |
| 20 | 19 |
| 21 static bool can_tweak_alpha_for_coverage(GrBlendCoeff dstCoeff) { | 20 static bool can_tweak_alpha_for_coverage(GrBlendCoeff dstCoeff) { |
| 22 /* | 21 /* |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 GrGLPorterDuffXferProcessor::GenKey(*this, caps, b); | 119 GrGLPorterDuffXferProcessor::GenKey(*this, caps, b); |
| 121 } | 120 } |
| 122 | 121 |
| 123 GrGLXferProcessor* GrPorterDuffXferProcessor::createGLInstance() const { | 122 GrGLXferProcessor* GrPorterDuffXferProcessor::createGLInstance() const { |
| 124 return SkNEW_ARGS(GrGLPorterDuffXferProcessor, (*this)); | 123 return SkNEW_ARGS(GrGLPorterDuffXferProcessor, (*this)); |
| 125 } | 124 } |
| 126 | 125 |
| 127 GrXferProcessor::OptFlags | 126 GrXferProcessor::OptFlags |
| 128 GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, | 127 GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, |
| 129 const GrProcOptInfo& coveragePOI, | 128 const GrProcOptInfo& coveragePOI, |
| 130 bool colorWriteDisabled, | |
| 131 bool doesStencilWrite, | 129 bool doesStencilWrite, |
| 132 GrColor* overrideColor, | 130 GrColor* overrideColor, |
| 133 const GrDrawTargetCaps& caps) { | 131 const GrDrawTargetCaps& caps) { |
| 134 GrXferProcessor::OptFlags optFlags; | 132 GrXferProcessor::OptFlags optFlags; |
| 135 // Optimizations when doing RGB Coverage | 133 // Optimizations when doing RGB Coverage |
| 136 if (coveragePOI.isFourChannelOutput()) { | 134 if (coveragePOI.isFourChannelOutput()) { |
| 137 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha | 135 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha |
| 138 // value of the blend the constant. We should already have valid blend c
oeff's if we are at | 136 // value of the blend the constant. We should already have valid blend c
oeff's if we are at |
| 139 // a point where we have RGB coverage. We don't need any color stages si
nce the known color | 137 // a point where we have RGB coverage. We don't need any color stages si
nce the known color |
| 140 // output is already baked into the blendConstant. | 138 // output is already baked into the blendConstant. |
| 141 uint8_t alpha = GrColorUnpackA(fBlendConstant); | 139 uint8_t alpha = GrColorUnpackA(fBlendConstant); |
| 142 *overrideColor = GrColorPackRGBA(alpha, alpha, alpha, alpha); | 140 *overrideColor = GrColorPackRGBA(alpha, alpha, alpha, alpha); |
| 143 optFlags = GrXferProcessor::kOverrideColor_OptFlag; | 141 optFlags = GrXferProcessor::kOverrideColor_OptFlag; |
| 144 } else { | 142 } else { |
| 145 optFlags = this->internalGetOptimizations(colorPOI, | 143 optFlags = this->internalGetOptimizations(colorPOI, |
| 146 coveragePOI, | 144 coveragePOI, |
| 147 colorWriteDisabled, | |
| 148 doesStencilWrite); | 145 doesStencilWrite); |
| 149 } | 146 } |
| 150 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite(), | 147 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite(), |
| 151 colorPOI.readsDst() || coveragePOI.readsDst()); | 148 colorPOI.readsDst() || coveragePOI.readsDst()); |
| 152 return optFlags; | 149 return optFlags; |
| 153 } | 150 } |
| 154 | 151 |
| 155 void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFla
gs, | 152 void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFla
gs, |
| 156 const GrDrawTargetCaps& caps, | 153 const GrDrawTargetCaps& caps, |
| 157 bool hasSolidCoverage, bool read
sDst) { | 154 bool hasSolidCoverage, bool read
sDst) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 kOne_GrBlendCoeff == fSrcBlend && | 188 kOne_GrBlendCoeff == fSrcBlend && |
| 192 kZero_GrBlendCoeff == fDstBlend) { | 189 kZero_GrBlendCoeff == fDstBlend) { |
| 193 fPrimaryOutputType = kCombineWithDst_PrimaryOutputType; | 190 fPrimaryOutputType = kCombineWithDst_PrimaryOutputType; |
| 194 } | 191 } |
| 195 } | 192 } |
| 196 } | 193 } |
| 197 | 194 |
| 198 GrXferProcessor::OptFlags | 195 GrXferProcessor::OptFlags |
| 199 GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
I, | 196 GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
I, |
| 200 const GrProcOptInfo& coverag
ePOI, | 197 const GrProcOptInfo& coverag
ePOI, |
| 201 bool colorWriteDisabled, | |
| 202 bool doesStencilWrite) { | 198 bool doesStencilWrite) { |
| 203 if (colorWriteDisabled) { | |
| 204 fSrcBlend = kZero_GrBlendCoeff; | |
| 205 fDstBlend = kOne_GrBlendCoeff; | |
| 206 } | |
| 207 | |
| 208 bool srcAIsOne; | 199 bool srcAIsOne; |
| 209 bool hasCoverage; | 200 bool hasCoverage; |
| 210 | 201 |
| 211 srcAIsOne = colorPOI.isOpaque(); | 202 srcAIsOne = colorPOI.isOpaque(); |
| 212 hasCoverage = !coveragePOI.isSolidWhite(); | 203 hasCoverage = !coveragePOI.isSolidWhite(); |
| 213 | 204 |
| 214 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend || | 205 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend || |
| 215 (kSA_GrBlendCoeff == fDstBlend && srcAIsOne); | 206 (kSA_GrBlendCoeff == fDstBlend && srcAIsOne); |
| 216 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend || | 207 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend || |
| 217 (kISA_GrBlendCoeff == fDstBlend && srcAIsOne); | 208 (kISA_GrBlendCoeff == fDstBlend && srcAIsOne); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, | 383 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, |
| 393 uint32_t knownColorFlags) const
{ | 384 uint32_t knownColorFlags) const
{ |
| 394 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff && | 385 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff && |
| 395 kRGBA_GrColorComponentFlags == knownColorFlags) { | 386 kRGBA_GrColorComponentFlags == knownColorFlags) { |
| 396 return true; | 387 return true; |
| 397 } | 388 } |
| 398 return false; | 389 return false; |
| 399 } | 390 } |
| 400 | 391 |
| 401 bool GrPorterDuffXPFactory::canApplyCoverage(const GrProcOptInfo& colorPOI, | 392 bool GrPorterDuffXPFactory::canApplyCoverage(const GrProcOptInfo& colorPOI, |
| 402 const GrProcOptInfo& coveragePOI, | 393 const GrProcOptInfo& coveragePOI) c
onst { |
| 403 bool colorWriteDisabled) const { | |
| 404 bool srcAIsOne = colorPOI.isOpaque(); | 394 bool srcAIsOne = colorPOI.isOpaque(); |
| 405 | 395 |
| 406 if (colorWriteDisabled) { | |
| 407 return true; | |
| 408 } | |
| 409 | |
| 410 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstCoeff || | 396 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstCoeff || |
| 411 (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne); | 397 (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne); |
| 412 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstCoeff || | 398 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstCoeff || |
| 413 (kISA_GrBlendCoeff == fDstCoeff && srcAIsOne); | 399 (kISA_GrBlendCoeff == fDstCoeff && srcAIsOne); |
| 414 | 400 |
| 415 if ((kZero_GrBlendCoeff == fSrcCoeff && dstCoeffIsOne)) { | 401 if ((kZero_GrBlendCoeff == fSrcCoeff && dstCoeffIsOne)) { |
| 416 return true; | 402 return true; |
| 417 } | 403 } |
| 418 | 404 |
| 419 // if we don't have coverage we can check whether the dst | 405 // if we don't have coverage we can check whether the dst |
| (...skipping 22 matching lines...) Expand all Loading... |
| 442 | 428 |
| 443 return false; | 429 return false; |
| 444 } | 430 } |
| 445 | 431 |
| 446 bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const { | 432 bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const { |
| 447 return can_tweak_alpha_for_coverage(fDstCoeff); | 433 return can_tweak_alpha_for_coverage(fDstCoeff); |
| 448 } | 434 } |
| 449 | 435 |
| 450 void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, | 436 void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, |
| 451 const GrProcOptInfo& coveragePOI, | 437 const GrProcOptInfo& coveragePOI, |
| 452 bool colorWriteDisabled, | |
| 453 GrXPFactory::InvariantOutput* out
put) const { | 438 GrXPFactory::InvariantOutput* out
put) const { |
| 454 if (!coveragePOI.isSolidWhite()) { | 439 if (!coveragePOI.isSolidWhite()) { |
| 455 output->fWillBlendWithDst = true; | 440 output->fWillBlendWithDst = true; |
| 456 output->fBlendedColorFlags = 0; | 441 output->fBlendedColorFlags = 0; |
| 457 return; | 442 return; |
| 458 } | 443 } |
| 459 | 444 |
| 460 GrBlendCoeff srcCoeff = fSrcCoeff; | 445 GrBlendCoeff srcCoeff = fSrcCoeff; |
| 461 GrBlendCoeff dstCoeff = fDstCoeff; | 446 GrBlendCoeff dstCoeff = fDstCoeff; |
| 462 | 447 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 case kConstC_GrBlendCoeff: | 494 case kConstC_GrBlendCoeff: |
| 510 case kIConstC_GrBlendCoeff: | 495 case kIConstC_GrBlendCoeff: |
| 511 case kConstA_GrBlendCoeff: | 496 case kConstA_GrBlendCoeff: |
| 512 case kIConstA_GrBlendCoeff: | 497 case kIConstA_GrBlendCoeff: |
| 513 output->fBlendedColorFlags = 0; | 498 output->fBlendedColorFlags = 0; |
| 514 break; | 499 break; |
| 515 } | 500 } |
| 516 | 501 |
| 517 // TODO: once all SkXferEffects are XP's then we will never reads dst here s
ince only XP's | 502 // TODO: once all SkXferEffects are XP's then we will never reads dst here s
ince only XP's |
| 518 // will readDst and PD XP's don't read dst. | 503 // will readDst and PD XP's don't read dst. |
| 519 if ((!colorWriteDisabled && colorPOI.readsDst()) || coveragePOI.readsDst())
{ | 504 if (colorPOI.readsDst() || coveragePOI.readsDst()) { |
| 520 output->fWillBlendWithDst = true; | 505 output->fWillBlendWithDst = true; |
| 521 return; | 506 return; |
| 522 } | 507 } |
| 523 output->fWillBlendWithDst = false; | 508 output->fWillBlendWithDst = false; |
| 524 } | 509 } |
| 525 | 510 |
| 511 bool GrPorterDuffXPFactory::willReadDst(const GrProcOptInfo& colorPOI, |
| 512 const GrProcOptInfo& coveragePOI) const
{ |
| 513 return colorPOI.readsDst() || coveragePOI.readsDst(); |
| 514 } |
| 515 |
| 526 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); | 516 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); |
| 527 | 517 |
| 528 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, | 518 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, |
| 529 GrContext*, | 519 GrContext*, |
| 530 const GrDrawTargetCaps&, | 520 const GrDrawTargetCaps&, |
| 531 GrTexture*[]) { | 521 GrTexture*[]) { |
| 532 GrBlendCoeff src; | 522 GrBlendCoeff src; |
| 533 do { | 523 do { |
| 534 src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub
licGrBlendCoeff)); | 524 src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub
licGrBlendCoeff)); |
| 535 } while (GrBlendCoeffRefsSrc(src)); | 525 } while (GrBlendCoeffRefsSrc(src)); |
| 536 | 526 |
| 537 GrBlendCoeff dst; | 527 GrBlendCoeff dst; |
| 538 do { | 528 do { |
| 539 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub
licGrBlendCoeff)); | 529 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub
licGrBlendCoeff)); |
| 540 } while (GrBlendCoeffRefsDst(dst)); | 530 } while (GrBlendCoeffRefsDst(dst)); |
| 541 | 531 |
| 542 return GrPorterDuffXPFactory::Create(src, dst); | 532 return GrPorterDuffXPFactory::Create(src, dst); |
| 543 } | 533 } |
| 544 | 534 |
| OLD | NEW |