| 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" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 struct BlendFormula { | 24 struct BlendFormula { |
| 25 public: | 25 public: |
| 26 /** | 26 /** |
| 27 * Values the shader can write to primary and secondary outputs. These must
all be modulated by | 27 * Values the shader can write to primary and secondary outputs. These must
all be modulated by |
| 28 * coverage to support mixed samples. The XP will ignore the multiplies when
not using coverage. | 28 * coverage to support mixed samples. The XP will ignore the multiplies when
not using coverage. |
| 29 */ | 29 */ |
| 30 enum OutputType { | 30 enum OutputType { |
| 31 kNone_OutputType, //<! 0 | 31 kNone_OutputType, //<! 0 |
| 32 kCoverage_OutputType, //<! inputCoverage | 32 kCoverage_OutputType, //<! inputCoverage |
| 33 kModulate_OutputType, //<! inputColor * inputCoverage | 33 kModulate_OutputType, //<! inputColor * inputCoverage |
| 34 kSAModulate_OutputType, //<! inputColor.a * inputCoverage |
| 34 kISAModulate_OutputType, //<! (1 - inputColor.a) * inputCoverage | 35 kISAModulate_OutputType, //<! (1 - inputColor.a) * inputCoverage |
| 35 kISCModulate_OutputType, //<! (1 - inputColor) * inputCoverage | 36 kISCModulate_OutputType, //<! (1 - inputColor) * inputCoverage |
| 36 | 37 |
| 37 kLast_OutputType = kISCModulate_OutputType | 38 kLast_OutputType = kISCModulate_OutputType |
| 38 }; | 39 }; |
| 39 | 40 |
| 40 enum Properties { | 41 enum Properties { |
| 41 kModifiesDst_Property = 1, | 42 kModifiesDst_Property = 1, |
| 42 kUsesDstColor_Property = 1 << 1, | 43 kUsesDstColor_Property = 1 << 1, |
| 43 kUsesInputColor_Property = 1 << 2, | 44 kUsesInputColor_Property = 1 << 2, |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 /** | 133 /** |
| 133 * When there is no coverage, or the blend mode can tweak alpha for coverage, we
use the standard | 134 * When there is no coverage, or the blend mode can tweak alpha for coverage, we
use the standard |
| 134 * Porter Duff formula. | 135 * Porter Duff formula. |
| 135 */ | 136 */ |
| 136 #define COEFF_FORMULA(SRC_COEFF, DST_COEFF) \ | 137 #define COEFF_FORMULA(SRC_COEFF, DST_COEFF) \ |
| 137 INIT_BLEND_FORMULA(BlendFormula::kModulate_OutputType, \ | 138 INIT_BLEND_FORMULA(BlendFormula::kModulate_OutputType, \ |
| 138 BlendFormula::kNone_OutputType, \ | 139 BlendFormula::kNone_OutputType, \ |
| 139 kAdd_GrBlendEquation, SRC_COEFF, DST_COEFF) | 140 kAdd_GrBlendEquation, SRC_COEFF, DST_COEFF) |
| 140 | 141 |
| 141 /** | 142 /** |
| 143 * Basic coeff formula similar to COEFF_FORMULA but we will make the src f*Sa. T
his is used in |
| 144 * LCD dst-out. |
| 145 */ |
| 146 #define COEFF_FORMULA_SA_MODULATE(SRC_COEFF, DST_COEFF) \ |
| 147 INIT_BLEND_FORMULA(BlendFormula::kSAModulate_OutputType, \ |
| 148 BlendFormula::kNone_OutputType, \ |
| 149 kAdd_GrBlendEquation, SRC_COEFF, DST_COEFF) |
| 150 |
| 151 /** |
| 142 * When the coeffs are (Zero, Zero), we clear the dst. This formula has its own
macro so we can set | 152 * When the coeffs are (Zero, Zero), we clear the dst. This formula has its own
macro so we can set |
| 143 * the primary output type to none. | 153 * the primary output type to none. |
| 144 */ | 154 */ |
| 145 #define DST_CLEAR_FORMULA \ | 155 #define DST_CLEAR_FORMULA \ |
| 146 INIT_BLEND_FORMULA(BlendFormula::kNone_OutputType, \ | 156 INIT_BLEND_FORMULA(BlendFormula::kNone_OutputType, \ |
| 147 BlendFormula::kNone_OutputType, \ | 157 BlendFormula::kNone_OutputType, \ |
| 148 kAdd_GrBlendEquation, kZero_GrBlendCoeff, kZero_GrBlendCo
eff) | 158 kAdd_GrBlendEquation, kZero_GrBlendCoeff, kZero_GrBlendCo
eff) |
| 149 | 159 |
| 150 /** | 160 /** |
| 151 * When the coeffs are (Zero, One), we don't write to the dst at all. This formu
la has its own macro | 161 * When the coeffs are (Zero, One), we don't write to the dst at all. This formu
la has its own macro |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 /* src-out */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff), | 292 /* src-out */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff), |
| 283 /* dst-out */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_Out
putType), | 293 /* dst-out */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_Out
putType), |
| 284 /* src-atop */ COEFF_FORMULA( kDA_GrBlendCoeff, kISA_GrBlendCoeff), | 294 /* src-atop */ COEFF_FORMULA( kDA_GrBlendCoeff, kISA_GrBlendCoeff), |
| 285 /* dst-atop */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff), | 295 /* dst-atop */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff), |
| 286 /* xor */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff), | 296 /* xor */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff), |
| 287 /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff), | 297 /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff), |
| 288 /* modulate */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_
OutputType), | 298 /* modulate */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_
OutputType), |
| 289 /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff), | 299 /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff), |
| 290 }}}; | 300 }}}; |
| 291 | 301 |
| 302 static const BlendFormula gLCDBlendTable[SkXfermode::kLastCoeffMode + 1] = { |
| 303 /* clear */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_Out
putType), |
| 304 /* src */ COVERAGE_FORMULA(BlendFormula::kCoverage_OutputType, kOne_G
rBlendCoeff), |
| 305 /* dst */ NO_DST_WRITE_FORMULA, |
| 306 /* src-over */ COVERAGE_FORMULA(BlendFormula::kSAModulate_OutputType, kOne
_GrBlendCoeff), |
| 307 /* dst-over */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff), |
| 308 /* src-in */ COVERAGE_FORMULA(BlendFormula::kCoverage_OutputType, kDA_Gr
BlendCoeff), |
| 309 /* dst-in */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISAModulate_
OutputType), |
| 310 /* src-out */ COVERAGE_FORMULA(BlendFormula::kCoverage_OutputType, kIDA_G
rBlendCoeff), |
| 311 /* dst-out */ COEFF_FORMULA_SA_MODULATE( kZero_GrBlendCoeff, kISC_GrB
lendCoeff), |
| 312 /* src-atop */ COVERAGE_FORMULA(BlendFormula::kSAModulate_OutputType, kDA_
GrBlendCoeff), |
| 313 /* dst-atop */ COVERAGE_FORMULA(BlendFormula::kISAModulate_OutputType, kID
A_GrBlendCoeff), |
| 314 /* xor */ COVERAGE_FORMULA(BlendFormula::kSAModulate_OutputType, kIDA
_GrBlendCoeff), |
| 315 /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff), |
| 316 /* modulate */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_
OutputType), |
| 317 /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff), |
| 318 }; |
| 319 |
| 292 static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI, | 320 static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI, |
| 293 const GrProcOptInfo& coveragePOI, | 321 const GrProcOptInfo& coveragePOI, |
| 294 bool hasMixedSamples, | 322 bool hasMixedSamples, |
| 295 SkXfermode::Mode xfermode) { | 323 SkXfermode::Mode xfermode) { |
| 296 SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode); | 324 SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode); |
| 297 SkASSERT(!coveragePOI.isFourChannelOutput()); | 325 SkASSERT(!coveragePOI.isFourChannelOutput()); |
| 298 | 326 |
| 299 bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples; | 327 bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples; |
| 300 return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][xfermode]; | 328 return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][xfermode]; |
| 301 } | 329 } |
| 302 | 330 |
| 331 static BlendFormula get_lcd_blend_formula(const GrProcOptInfo& coveragePOI, |
| 332 SkXfermode::Mode xfermode) { |
| 333 SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode); |
| 334 SkASSERT(coveragePOI.isFourChannelOutput()); |
| 335 |
| 336 return gLCDBlendTable[xfermode]; |
| 337 } |
| 338 |
| 303 /////////////////////////////////////////////////////////////////////////////// | 339 /////////////////////////////////////////////////////////////////////////////// |
| 304 | 340 |
| 305 class PorterDuffXferProcessor : public GrXferProcessor { | 341 class PorterDuffXferProcessor : public GrXferProcessor { |
| 306 public: | 342 public: |
| 307 PorterDuffXferProcessor(BlendFormula blendFormula) : fBlendFormula(blendForm
ula) { | 343 PorterDuffXferProcessor(BlendFormula blendFormula) : fBlendFormula(blendForm
ula) { |
| 308 this->initClassID<PorterDuffXferProcessor>(); | 344 this->initClassID<PorterDuffXferProcessor>(); |
| 309 } | 345 } |
| 310 | 346 |
| 311 const char* name() const override { return "Porter Duff"; } | 347 const char* name() const override { return "Porter Duff"; } |
| 312 | 348 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 fsBuilder->codeAppendf("%s = %s;", | 392 fsBuilder->codeAppendf("%s = %s;", |
| 357 output, xp.readsCoverage() ? inCoverage : "ve
c4(1.0)"); | 393 output, xp.readsCoverage() ? inCoverage : "ve
c4(1.0)"); |
| 358 break; | 394 break; |
| 359 case BlendFormula::kModulate_OutputType: | 395 case BlendFormula::kModulate_OutputType: |
| 360 if (xp.readsCoverage()) { | 396 if (xp.readsCoverage()) { |
| 361 fsBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCover
age); | 397 fsBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCover
age); |
| 362 } else { | 398 } else { |
| 363 fsBuilder->codeAppendf("%s = %s;", output, inColor); | 399 fsBuilder->codeAppendf("%s = %s;", output, inColor); |
| 364 } | 400 } |
| 365 break; | 401 break; |
| 402 case BlendFormula::kSAModulate_OutputType: |
| 403 if (xp.readsCoverage()) { |
| 404 fsBuilder->codeAppendf("%s = %s.a * %s;", output, inColor, inCov
erage); |
| 405 } else { |
| 406 fsBuilder->codeAppendf("%s = %s;", output, inColor); |
| 407 } |
| 408 break; |
| 366 case BlendFormula::kISAModulate_OutputType: | 409 case BlendFormula::kISAModulate_OutputType: |
| 367 if (xp.readsCoverage()) { | 410 if (xp.readsCoverage()) { |
| 368 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inColo
r, inCoverage); | 411 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inColo
r, inCoverage); |
| 369 } else { | 412 } else { |
| 370 fsBuilder->codeAppendf("%s = vec4(1.0 - %s.a);", output, inColor
); | 413 fsBuilder->codeAppendf("%s = vec4(1.0 - %s.a);", output, inColor
); |
| 371 } | 414 } |
| 372 break; | 415 break; |
| 373 case BlendFormula::kISCModulate_OutputType: | 416 case BlendFormula::kISCModulate_OutputType: |
| 374 if (xp.readsCoverage()) { | 417 if (xp.readsCoverage()) { |
| 375 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", output, in
Color, inCoverage); | 418 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", output, in
Color, inCoverage); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag | | 480 optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag | |
| 438 GrXferProcessor::kIgnoreCoverage_OptFlag | | 481 GrXferProcessor::kIgnoreCoverage_OptFlag | |
| 439 GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag); | 482 GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag); |
| 440 } else { | 483 } else { |
| 441 if (!fBlendFormula.usesInputColor()) { | 484 if (!fBlendFormula.usesInputColor()) { |
| 442 optFlags |= GrXferProcessor::kIgnoreColor_OptFlag; | 485 optFlags |= GrXferProcessor::kIgnoreColor_OptFlag; |
| 443 } | 486 } |
| 444 if (coveragePOI.isSolidWhite()) { | 487 if (coveragePOI.isSolidWhite()) { |
| 445 optFlags |= GrXferProcessor::kIgnoreCoverage_OptFlag; | 488 optFlags |= GrXferProcessor::kIgnoreCoverage_OptFlag; |
| 446 } | 489 } |
| 447 if (colorPOI.allStagesMultiplyInput() && fBlendFormula.canTweakAlphaForC
overage()) { | 490 if (colorPOI.allStagesMultiplyInput() && |
| 491 fBlendFormula.canTweakAlphaForCoverage() && |
| 492 !coveragePOI.isFourChannelOutput()) { |
| 448 optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; | 493 optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; |
| 449 } | 494 } |
| 450 } | 495 } |
| 451 return optFlags; | 496 return optFlags; |
| 452 } | 497 } |
| 453 | 498 |
| 454 /////////////////////////////////////////////////////////////////////////////// | 499 /////////////////////////////////////////////////////////////////////////////// |
| 455 | 500 |
| 456 class ShaderPDXferProcessor : public GrXferProcessor { | 501 class ShaderPDXferProcessor : public GrXferProcessor { |
| 457 public: | 502 public: |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 GLPDLCDXferProcessor(const GrProcessor&) {} | 617 GLPDLCDXferProcessor(const GrProcessor&) {} |
| 573 | 618 |
| 574 virtual ~GLPDLCDXferProcessor() {} | 619 virtual ~GLPDLCDXferProcessor() {} |
| 575 | 620 |
| 576 static void GenKey(const GrProcessor& processor, const GrGLSLCaps& caps, | 621 static void GenKey(const GrProcessor& processor, const GrGLSLCaps& caps, |
| 577 GrProcessorKeyBuilder* b) {} | 622 GrProcessorKeyBuilder* b) {} |
| 578 | 623 |
| 579 private: | 624 private: |
| 580 void emitOutputsForBlendState(const EmitArgs& args) override { | 625 void emitOutputsForBlendState(const EmitArgs& args) override { |
| 581 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 626 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 582 | |
| 583 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInput
Color, | 627 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInput
Color, |
| 584 args.fInputCoverage); | 628 args.fInputCoverage); |
| 585 } | 629 } |
| 586 | 630 |
| 587 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri
de {}; | 631 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri
de {}; |
| 588 | 632 |
| 589 typedef GrGLXferProcessor INHERITED; | 633 typedef GrGLXferProcessor INHERITED; |
| 590 }; | 634 }; |
| 591 | 635 |
| 592 /////////////////////////////////////////////////////////////////////////////// | 636 /////////////////////////////////////////////////////////////////////////////// |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 } | 721 } |
| 678 return SkRef(gFactories[xfermode]); | 722 return SkRef(gFactories[xfermode]); |
| 679 } | 723 } |
| 680 | 724 |
| 681 GrXferProcessor* | 725 GrXferProcessor* |
| 682 GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, | 726 GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, |
| 683 const GrProcOptInfo& colorPOI, | 727 const GrProcOptInfo& colorPOI, |
| 684 const GrProcOptInfo& covPOI, | 728 const GrProcOptInfo& covPOI, |
| 685 bool hasMixedSamples, | 729 bool hasMixedSamples, |
| 686 const DstTexture* dstTexture) const
{ | 730 const DstTexture* dstTexture) const
{ |
| 731 BlendFormula blendFormula; |
| 687 if (covPOI.isFourChannelOutput()) { | 732 if (covPOI.isFourChannelOutput()) { |
| 688 SkASSERT(!dstTexture || !dstTexture->texture()); | 733 if (SkXfermode::kSrcOver_Mode == fXfermode && |
| 689 return PDLCDXferProcessor::Create(fXfermode, colorPOI); | 734 kRGBA_GrColorComponentFlags == colorPOI.validFlags()) { |
| 735 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 736 return PDLCDXferProcessor::Create(fXfermode, colorPOI); |
| 737 } |
| 738 blendFormula = get_lcd_blend_formula(covPOI, fXfermode); |
| 739 } else { |
| 740 blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfe
rmode); |
| 690 } | 741 } |
| 691 | 742 |
| 692 BlendFormula blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamp
les, fXfermode); | |
| 693 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { | 743 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { |
| 694 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode)
; | 744 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode)
; |
| 695 } | 745 } |
| 696 | 746 |
| 697 SkASSERT(!dstTexture || !dstTexture->texture()); | 747 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 698 return new PorterDuffXferProcessor(blendFormula); | 748 return new PorterDuffXferProcessor(blendFormula); |
| 699 } | 749 } |
| 700 | 750 |
| 701 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, | |
| 702 uint32_t knownColorFlags) const
{ | |
| 703 if (SkXfermode::kSrcOver_Mode == fXfermode && | |
| 704 kRGBA_GrColorComponentFlags == knownColorFlags) { | |
| 705 return true; | |
| 706 } | |
| 707 return false; | |
| 708 } | |
| 709 | |
| 710 void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP
OI, | 751 void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP
OI, |
| 711 InvariantBlendedColor* blen
dedColor) const { | 752 InvariantBlendedColor* blen
dedColor) const { |
| 712 // Find the blended color info based on the formula that does not have cover
age. | 753 // Find the blended color info based on the formula that does not have cover
age. |
| 713 BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][fXfermode]; | 754 BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][fXfermode]; |
| 714 if (colorFormula.usesDstColor()) { | 755 if (colorFormula.usesDstColor()) { |
| 715 blendedColor->fWillBlendWithDst = true; | 756 blendedColor->fWillBlendWithDst = true; |
| 716 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; | 757 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; |
| 717 return; | 758 return; |
| 718 } | 759 } |
| 719 | 760 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 738 } | 779 } |
| 739 } | 780 } |
| 740 | 781 |
| 741 bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, | 782 bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, |
| 742 const GrProcOptInfo& colorPOI, | 783 const GrProcOptInfo& colorPOI, |
| 743 const GrProcOptInfo& covPOI, | 784 const GrProcOptInfo& covPOI, |
| 744 bool hasMixedSamples) const { | 785 bool hasMixedSamples) const { |
| 745 if (caps.shaderCaps()->dualSourceBlendingSupport()) { | 786 if (caps.shaderCaps()->dualSourceBlendingSupport()) { |
| 746 return false; | 787 return false; |
| 747 } | 788 } |
| 789 |
| 790 // When we have four channel coverage we always need to read the dst in orde
r to correctly |
| 791 // blend. The one exception is when we are using srcover mode and we know th
e input color into |
| 792 // the XP. |
| 748 if (covPOI.isFourChannelOutput()) { | 793 if (covPOI.isFourChannelOutput()) { |
| 749 return false; // The LCD XP will abort rather than doing a dst read. | 794 if (SkXfermode::kSrcOver_Mode == fXfermode && |
| 795 kRGBA_GrColorComponentFlags == colorPOI.validFlags()) { |
| 796 return false; |
| 797 } |
| 798 return get_lcd_blend_formula(covPOI, fXfermode).hasSecondaryOutput(); |
| 750 } | 799 } |
| 751 // We fallback on the shader XP when the blend formula would use dual source
blending but we | 800 // We fallback on the shader XP when the blend formula would use dual source
blending but we |
| 752 // don't have support for it. | 801 // don't have support for it. |
| 753 return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSe
condaryOutput(); | 802 return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSe
condaryOutput(); |
| 754 } | 803 } |
| 755 | 804 |
| 756 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); | 805 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); |
| 757 | 806 |
| 758 const GrXPFactory* GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) { | 807 const GrXPFactory* GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) { |
| 759 SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermod
e::kLastCoeffMode)); | 808 SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermod
e::kLastCoeffMode)); |
| 760 return GrPorterDuffXPFactory::Create(mode); | 809 return GrPorterDuffXPFactory::Create(mode); |
| 761 } | 810 } |
| 762 | 811 |
| 763 void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, | 812 void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, |
| 764 int* outPrimary, | 813 int* outPrimary, |
| 765 int* outSecondary) { | 814 int* outSecondary) { |
| 766 if (!!strcmp(xp->name(), "Porter Duff")) { | 815 if (!!strcmp(xp->name(), "Porter Duff")) { |
| 767 *outPrimary = *outSecondary = -1; | 816 *outPrimary = *outSecondary = -1; |
| 768 return; | 817 return; |
| 769 } | 818 } |
| 770 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)-
>getBlendFormula(); | 819 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)-
>getBlendFormula(); |
| 771 *outPrimary = blendFormula.fPrimaryOutputType; | 820 *outPrimary = blendFormula.fPrimaryOutputType; |
| 772 *outSecondary = blendFormula.fSecondaryOutputType; | 821 *outSecondary = blendFormula.fSecondaryOutputType; |
| 773 } | 822 } |
| OLD | NEW |