| 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 "GrCaps.h" | 11 #include "GrCaps.h" |
| 12 #include "GrPipeline.h" |
| 12 #include "GrProcessor.h" | 13 #include "GrProcessor.h" |
| 13 #include "GrProcOptInfo.h" | 14 #include "GrProcOptInfo.h" |
| 14 #include "GrTypes.h" | 15 #include "GrTypes.h" |
| 15 #include "GrXferProcessor.h" | 16 #include "GrXferProcessor.h" |
| 16 #include "glsl/GrGLSLBlend.h" | 17 #include "glsl/GrGLSLBlend.h" |
| 17 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 18 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
| 18 #include "glsl/GrGLSLProgramBuilder.h" | 19 #include "glsl/GrGLSLProgramBuilder.h" |
| 19 #include "glsl/GrGLSLProgramDataManager.h" | 20 #include "glsl/GrGLSLProgramDataManager.h" |
| 20 #include "glsl/GrGLSLXferProcessor.h" | 21 #include "glsl/GrGLSLXferProcessor.h" |
| 21 | 22 |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 this->initClassID<PorterDuffXferProcessor>(); | 346 this->initClassID<PorterDuffXferProcessor>(); |
| 346 } | 347 } |
| 347 | 348 |
| 348 const char* name() const override { return "Porter Duff"; } | 349 const char* name() const override { return "Porter Duff"; } |
| 349 | 350 |
| 350 GrGLSLXferProcessor* createGLSLInstance() const override; | 351 GrGLSLXferProcessor* createGLSLInstance() const override; |
| 351 | 352 |
| 352 BlendFormula getBlendFormula() const { return fBlendFormula; } | 353 BlendFormula getBlendFormula() const { return fBlendFormula; } |
| 353 | 354 |
| 354 private: | 355 private: |
| 355 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, | 356 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&
optimizations, |
| 356 const GrProcOptInfo& coveragePO
I, | |
| 357 bool doesStencilWrite, | 357 bool doesStencilWrite, |
| 358 GrColor* overrideColor, | 358 GrColor* overrideColor, |
| 359 const GrCaps& caps) override; | 359 const GrCaps& caps) override; |
| 360 | 360 |
| 361 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; | 361 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; |
| 362 | 362 |
| 363 bool onHasSecondaryOutput() const override { return fBlendFormula.hasSeconda
ryOutput(); } | 363 bool onHasSecondaryOutput() const override { return fBlendFormula.hasSeconda
ryOutput(); } |
| 364 | 364 |
| 365 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { | 365 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { |
| 366 blendInfo->fEquation = fBlendFormula.fBlendEquation; | 366 blendInfo->fEquation = fBlendFormula.fBlendEquation; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 void PorterDuffXferProcessor::onGetGLSLProcessorKey(const GrGLSLCaps&, | 462 void PorterDuffXferProcessor::onGetGLSLProcessorKey(const GrGLSLCaps&, |
| 463 GrProcessorKeyBuilder* b) co
nst { | 463 GrProcessorKeyBuilder* b) co
nst { |
| 464 GLPorterDuffXferProcessor::GenKey(*this, b); | 464 GLPorterDuffXferProcessor::GenKey(*this, b); |
| 465 } | 465 } |
| 466 | 466 |
| 467 GrGLSLXferProcessor* PorterDuffXferProcessor::createGLSLInstance() const { | 467 GrGLSLXferProcessor* PorterDuffXferProcessor::createGLSLInstance() const { |
| 468 return new GLPorterDuffXferProcessor; | 468 return new GLPorterDuffXferProcessor; |
| 469 } | 469 } |
| 470 | 470 |
| 471 GrXferProcessor::OptFlags | 471 GrXferProcessor::OptFlags |
| 472 PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, | 472 PorterDuffXferProcessor::onGetOptimizations(const GrPipelineOptimizations& optim
izations, |
| 473 const GrProcOptInfo& coveragePOI, | |
| 474 bool doesStencilWrite, | 473 bool doesStencilWrite, |
| 475 GrColor* overrideColor, | 474 GrColor* overrideColor, |
| 476 const GrCaps& caps) { | 475 const GrCaps& caps) { |
| 477 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; | 476 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; |
| 478 if (!fBlendFormula.modifiesDst()) { | 477 if (!fBlendFormula.modifiesDst()) { |
| 479 if (!doesStencilWrite) { | 478 if (!doesStencilWrite) { |
| 480 optFlags |= GrXferProcessor::kSkipDraw_OptFlag; | 479 optFlags |= GrXferProcessor::kSkipDraw_OptFlag; |
| 481 } | 480 } |
| 482 optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag | | 481 optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag | |
| 483 GrXferProcessor::kIgnoreCoverage_OptFlag | | 482 GrXferProcessor::kIgnoreCoverage_OptFlag | |
| 484 GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag); | 483 GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag); |
| 485 } else { | 484 } else { |
| 486 if (!fBlendFormula.usesInputColor()) { | 485 if (!fBlendFormula.usesInputColor()) { |
| 487 optFlags |= GrXferProcessor::kIgnoreColor_OptFlag; | 486 optFlags |= GrXferProcessor::kIgnoreColor_OptFlag; |
| 488 } | 487 } |
| 489 if (coveragePOI.isSolidWhite()) { | 488 if (optimizations.fCoveragePOI.isSolidWhite()) { |
| 490 optFlags |= GrXferProcessor::kIgnoreCoverage_OptFlag; | 489 optFlags |= GrXferProcessor::kIgnoreCoverage_OptFlag; |
| 491 } | 490 } |
| 492 if (colorPOI.allStagesMultiplyInput() && | 491 if (optimizations.fColorPOI.allStagesMultiplyInput() && |
| 493 fBlendFormula.canTweakAlphaForCoverage() && | 492 fBlendFormula.canTweakAlphaForCoverage() && |
| 494 !coveragePOI.isFourChannelOutput()) { | 493 !optimizations.fCoveragePOI.isFourChannelOutput()) { |
| 495 optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; | 494 optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; |
| 496 } | 495 } |
| 497 } | 496 } |
| 498 return optFlags; | 497 return optFlags; |
| 499 } | 498 } |
| 500 | 499 |
| 501 /////////////////////////////////////////////////////////////////////////////// | 500 /////////////////////////////////////////////////////////////////////////////// |
| 502 | 501 |
| 503 class ShaderPDXferProcessor : public GrXferProcessor { | 502 class ShaderPDXferProcessor : public GrXferProcessor { |
| 504 public: | 503 public: |
| 505 ShaderPDXferProcessor(const DstTexture* dstTexture, | 504 ShaderPDXferProcessor(const DstTexture* dstTexture, |
| 506 bool hasMixedSamples, | 505 bool hasMixedSamples, |
| 507 SkXfermode::Mode xfermode) | 506 SkXfermode::Mode xfermode) |
| 508 : INHERITED(dstTexture, true, hasMixedSamples) | 507 : INHERITED(dstTexture, true, hasMixedSamples) |
| 509 , fXfermode(xfermode) { | 508 , fXfermode(xfermode) { |
| 510 this->initClassID<ShaderPDXferProcessor>(); | 509 this->initClassID<ShaderPDXferProcessor>(); |
| 511 } | 510 } |
| 512 | 511 |
| 513 const char* name() const override { return "Porter Duff Shader"; } | 512 const char* name() const override { return "Porter Duff Shader"; } |
| 514 | 513 |
| 515 GrGLSLXferProcessor* createGLSLInstance() const override; | 514 GrGLSLXferProcessor* createGLSLInstance() const override; |
| 516 | 515 |
| 517 SkXfermode::Mode getXfermode() const { return fXfermode; } | 516 SkXfermode::Mode getXfermode() const { return fXfermode; } |
| 518 | 517 |
| 519 private: | 518 private: |
| 520 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo&, const GrP
rocOptInfo&, | 519 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&,
bool, GrColor*, |
| 521 bool, GrColor*, const GrCaps&)
override { | 520 const GrCaps&) override { |
| 522 return kNone_OptFlags; | 521 return kNone_OptFlags; |
| 523 } | 522 } |
| 524 | 523 |
| 525 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; | 524 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; |
| 526 | 525 |
| 527 bool onIsEqual(const GrXferProcessor& xpBase) const override { | 526 bool onIsEqual(const GrXferProcessor& xpBase) const override { |
| 528 const ShaderPDXferProcessor& xp = xpBase.cast<ShaderPDXferProcessor>(); | 527 const ShaderPDXferProcessor& xp = xpBase.cast<ShaderPDXferProcessor>(); |
| 529 return fXfermode == xp.fXfermode; | 528 return fXfermode == xp.fXfermode; |
| 530 } | 529 } |
| 531 | 530 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 | 578 |
| 580 ~PDLCDXferProcessor() override; | 579 ~PDLCDXferProcessor() override; |
| 581 | 580 |
| 582 const char* name() const override { return "Porter Duff LCD"; } | 581 const char* name() const override { return "Porter Duff LCD"; } |
| 583 | 582 |
| 584 GrGLSLXferProcessor* createGLSLInstance() const override; | 583 GrGLSLXferProcessor* createGLSLInstance() const override; |
| 585 | 584 |
| 586 private: | 585 private: |
| 587 PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha); | 586 PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha); |
| 588 | 587 |
| 589 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, | 588 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&
optimizations, |
| 590 const GrProcOptInfo& coveragePO
I, | |
| 591 bool doesStencilWrite, | 589 bool doesStencilWrite, |
| 592 GrColor* overrideColor, | 590 GrColor* overrideColor, |
| 593 const GrCaps& caps) override; | 591 const GrCaps& caps) override; |
| 594 | 592 |
| 595 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; | 593 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; |
| 596 | 594 |
| 597 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { | 595 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { |
| 598 blendInfo->fSrcBlend = kConstC_GrBlendCoeff; | 596 blendInfo->fSrcBlend = kConstC_GrBlendCoeff; |
| 599 blendInfo->fDstBlend = kISC_GrBlendCoeff; | 597 blendInfo->fDstBlend = kISC_GrBlendCoeff; |
| 600 blendInfo->fBlendConstant = fBlendConstant; | 598 blendInfo->fBlendConstant = fBlendConstant; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 void PDLCDXferProcessor::onGetGLSLProcessorKey(const GrGLSLCaps& caps, | 667 void PDLCDXferProcessor::onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
| 670 GrProcessorKeyBuilder* b) const { | 668 GrProcessorKeyBuilder* b) const { |
| 671 GLPDLCDXferProcessor::GenKey(*this, caps, b); | 669 GLPDLCDXferProcessor::GenKey(*this, caps, b); |
| 672 } | 670 } |
| 673 | 671 |
| 674 GrGLSLXferProcessor* PDLCDXferProcessor::createGLSLInstance() const { | 672 GrGLSLXferProcessor* PDLCDXferProcessor::createGLSLInstance() const { |
| 675 return new GLPDLCDXferProcessor(*this); | 673 return new GLPDLCDXferProcessor(*this); |
| 676 } | 674 } |
| 677 | 675 |
| 678 GrXferProcessor::OptFlags | 676 GrXferProcessor::OptFlags |
| 679 PDLCDXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, | 677 PDLCDXferProcessor::onGetOptimizations(const GrPipelineOptimizations& optimizati
ons, |
| 680 const GrProcOptInfo& coveragePOI, | |
| 681 bool doesStencilWrite, | 678 bool doesStencilWrite, |
| 682 GrColor* overrideColor, | 679 GrColor* overrideColor, |
| 683 const GrCaps& caps) { | 680 const GrCaps& caps) { |
| 684 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha | 681 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha |
| 685 // value of the blend the constant. We should already have valid blend c
oeff's if we are at | 682 // value of the blend the constant. We should already have valid blend c
oeff's if we are at |
| 686 // a point where we have RGB coverage. We don't need any color stages si
nce the known color | 683 // a point where we have RGB coverage. We don't need any color stages si
nce the known color |
| 687 // output is already baked into the blendConstant. | 684 // output is already baked into the blendConstant. |
| 688 *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha); | 685 *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha); |
| 689 return GrXferProcessor::kOverrideColor_OptFlag; | 686 return GrXferProcessor::kOverrideColor_OptFlag; |
| 690 } | 687 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFactories) == SkXfermode::kLastCoeffMode +
1); | 719 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFactories) == SkXfermode::kLastCoeffMode +
1); |
| 723 | 720 |
| 724 if (xfermode < 0 || xfermode > SkXfermode::kLastCoeffMode) { | 721 if (xfermode < 0 || xfermode > SkXfermode::kLastCoeffMode) { |
| 725 return nullptr; | 722 return nullptr; |
| 726 } | 723 } |
| 727 return SkRef(gFactories[xfermode]); | 724 return SkRef(gFactories[xfermode]); |
| 728 } | 725 } |
| 729 | 726 |
| 730 GrXferProcessor* | 727 GrXferProcessor* |
| 731 GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, | 728 GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, |
| 732 const GrProcOptInfo& colorPOI, | 729 const GrPipelineOptimizations& opti
mizations, |
| 733 const GrProcOptInfo& covPOI, | |
| 734 bool hasMixedSamples, | 730 bool hasMixedSamples, |
| 735 const DstTexture* dstTexture) const
{ | 731 const DstTexture* dstTexture) const
{ |
| 736 BlendFormula blendFormula; | 732 BlendFormula blendFormula; |
| 737 if (covPOI.isFourChannelOutput()) { | 733 if (optimizations.fCoveragePOI.isFourChannelOutput()) { |
| 738 if (SkXfermode::kSrcOver_Mode == fXfermode && | 734 if (SkXfermode::kSrcOver_Mode == fXfermode && |
| 739 kRGBA_GrColorComponentFlags == colorPOI.validFlags() && | 735 kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& |
| 740 !caps.shaderCaps()->dualSourceBlendingSupport() && | 736 !caps.shaderCaps()->dualSourceBlendingSupport() && |
| 741 !caps.shaderCaps()->dstReadInShaderSupport()) { | 737 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 742 // If we don't have dual source blending or in shader dst reads, we
fall back to this | 738 // If we don't have dual source blending or in shader dst reads, we
fall back to this |
| 743 // trick for rendering SrcOver LCD text instead of doing a dst copy. | 739 // trick for rendering SrcOver LCD text instead of doing a dst copy. |
| 744 SkASSERT(!dstTexture || !dstTexture->texture()); | 740 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 745 return PDLCDXferProcessor::Create(fXfermode, colorPOI); | 741 return PDLCDXferProcessor::Create(fXfermode, optimizations.fColorPOI
); |
| 746 } | 742 } |
| 747 blendFormula = get_lcd_blend_formula(covPOI, fXfermode); | 743 blendFormula = get_lcd_blend_formula(optimizations.fCoveragePOI, fXfermo
de); |
| 748 } else { | 744 } else { |
| 749 blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfe
rmode); | 745 blendFormula = get_blend_formula(optimizations.fColorPOI, optimizations.
fCoveragePOI, |
| 746 hasMixedSamples, fXfermode); |
| 750 } | 747 } |
| 751 | 748 |
| 752 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { | 749 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { |
| 753 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode)
; | 750 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode)
; |
| 754 } | 751 } |
| 755 | 752 |
| 756 SkASSERT(!dstTexture || !dstTexture->texture()); | 753 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 757 return new PorterDuffXferProcessor(blendFormula); | 754 return new PorterDuffXferProcessor(blendFormula); |
| 758 } | 755 } |
| 759 | 756 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 782 blendedColor->fKnownColorFlags = colorPOI.validFlags(); | 779 blendedColor->fKnownColorFlags = colorPOI.validFlags(); |
| 783 return; | 780 return; |
| 784 | 781 |
| 785 default: | 782 default: |
| 786 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; | 783 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; |
| 787 return; | 784 return; |
| 788 } | 785 } |
| 789 } | 786 } |
| 790 | 787 |
| 791 bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, | 788 bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, |
| 792 const GrProcOptInfo& colorPOI, | 789 const GrPipelineOptimizations& opti
mizations, |
| 793 const GrProcOptInfo& covPOI, | |
| 794 bool hasMixedSamples) const { | 790 bool hasMixedSamples) const { |
| 795 if (caps.shaderCaps()->dualSourceBlendingSupport()) { | 791 if (caps.shaderCaps()->dualSourceBlendingSupport()) { |
| 796 return false; | 792 return false; |
| 797 } | 793 } |
| 798 | 794 |
| 799 // When we have four channel coverage we always need to read the dst in orde
r to correctly | 795 // When we have four channel coverage we always need to read the dst in orde
r to correctly |
| 800 // blend. The one exception is when we are using srcover mode and we know th
e input color into | 796 // blend. The one exception is when we are using srcover mode and we know th
e input color into |
| 801 // the XP. | 797 // the XP. |
| 802 if (covPOI.isFourChannelOutput()) { | 798 if (optimizations.fCoveragePOI.isFourChannelOutput()) { |
| 803 if (SkXfermode::kSrcOver_Mode == fXfermode && | 799 if (SkXfermode::kSrcOver_Mode == fXfermode && |
| 804 kRGBA_GrColorComponentFlags == colorPOI.validFlags() && | 800 kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& |
| 805 !caps.shaderCaps()->dstReadInShaderSupport()) { | 801 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 806 return false; | 802 return false; |
| 807 } | 803 } |
| 808 return get_lcd_blend_formula(covPOI, fXfermode).hasSecondaryOutput(); | 804 return get_lcd_blend_formula(optimizations.fCoveragePOI, fXfermode).hasS
econdaryOutput(); |
| 809 } | 805 } |
| 810 // We fallback on the shader XP when the blend formula would use dual source
blending but we | 806 // We fallback on the shader XP when the blend formula would use dual source
blending but we |
| 811 // don't have support for it. | 807 // don't have support for it. |
| 812 return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSe
condaryOutput(); | 808 return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI
, hasMixedSamples, |
| 809 fXfermode).hasSecondaryOutput(); |
| 813 } | 810 } |
| 814 | 811 |
| 815 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); | 812 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); |
| 816 | 813 |
| 817 const GrXPFactory* GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) { | 814 const GrXPFactory* GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) { |
| 818 SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermod
e::kLastCoeffMode)); | 815 SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermod
e::kLastCoeffMode)); |
| 819 return GrPorterDuffXPFactory::Create(mode); | 816 return GrPorterDuffXPFactory::Create(mode); |
| 820 } | 817 } |
| 821 | 818 |
| 822 void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, | 819 void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, |
| 823 int* outPrimary, | 820 int* outPrimary, |
| 824 int* outSecondary) { | 821 int* outSecondary) { |
| 825 if (!!strcmp(xp->name(), "Porter Duff")) { | 822 if (!!strcmp(xp->name(), "Porter Duff")) { |
| 826 *outPrimary = *outSecondary = -1; | 823 *outPrimary = *outSecondary = -1; |
| 827 return; | 824 return; |
| 828 } | 825 } |
| 829 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)-
>getBlendFormula(); | 826 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)-
>getBlendFormula(); |
| 830 *outPrimary = blendFormula.fPrimaryOutputType; | 827 *outPrimary = blendFormula.fPrimaryOutputType; |
| 831 *outSecondary = blendFormula.fSecondaryOutputType; | 828 *outSecondary = blendFormula.fSecondaryOutputType; |
| 832 } | 829 } |
| 833 | 830 |
| 834 | 831 |
| 835 ////////////////////////////////////////////////////////////////////////////////
//////////////// | 832 ////////////////////////////////////////////////////////////////////////////////
//////////////// |
| 836 // SrcOver Global functions | 833 // SrcOver Global functions |
| 837 ////////////////////////////////////////////////////////////////////////////////
//////////////// | 834 ////////////////////////////////////////////////////////////////////////////////
//////////////// |
| 838 | 835 |
| 839 GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor( | 836 GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor( |
| 840 const GrCaps& caps, | 837 const GrCaps& caps, |
| 841 const GrProcOptInfo& colorPOI, | 838 const GrPipelineOptimizations& optimizations, |
| 842 const GrProcOptInfo& covPOI, | |
| 843 bool hasMixedSamples, | 839 bool hasMixedSamples, |
| 844 const GrXferProcessor::DstTexture* dstTexture) { | 840 const GrXferProcessor::DstTexture* dstTexture) { |
| 845 BlendFormula blendFormula; | 841 BlendFormula blendFormula; |
| 846 if (covPOI.isFourChannelOutput()) { | 842 if (optimizations.fCoveragePOI.isFourChannelOutput()) { |
| 847 if (kRGBA_GrColorComponentFlags == colorPOI.validFlags() && | 843 if (kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& |
| 848 !caps.shaderCaps()->dualSourceBlendingSupport() && | 844 !caps.shaderCaps()->dualSourceBlendingSupport() && |
| 849 !caps.shaderCaps()->dstReadInShaderSupport()) { | 845 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 850 // If we don't have dual source blending or in shader dst reads, we
fall | 846 // If we don't have dual source blending or in shader dst reads, we
fall |
| 851 // back to this trick for rendering SrcOver LCD text instead of doin
g a | 847 // back to this trick for rendering SrcOver LCD text instead of doin
g a |
| 852 // dst copy. | 848 // dst copy. |
| 853 SkASSERT(!dstTexture || !dstTexture->texture()); | 849 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 854 return PDLCDXferProcessor::Create(SkXfermode::kSrcOver_Mode, colorPO
I); | 850 return PDLCDXferProcessor::Create(SkXfermode::kSrcOver_Mode, optimiz
ations.fColorPOI); |
| 855 } | 851 } |
| 856 blendFormula = get_lcd_blend_formula(covPOI, SkXfermode::kSrcOver_Mode); | 852 blendFormula = get_lcd_blend_formula(optimizations.fCoveragePOI, SkXferm
ode::kSrcOver_Mode); |
| 857 } else { | 853 } else { |
| 858 blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, | 854 blendFormula = get_blend_formula(optimizations.fColorPOI, optimizations.
fCoveragePOI, |
| 859 SkXfermode::kSrcOver_Mode); | 855 hasMixedSamples, SkXfermode::kSrcOver_M
ode); |
| 860 } | 856 } |
| 861 | 857 |
| 862 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { | 858 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { |
| 863 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkXfermode
::kSrcOver_Mode); | 859 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkXfermode
::kSrcOver_Mode); |
| 864 } | 860 } |
| 865 | 861 |
| 866 SkASSERT(!dstTexture || !dstTexture->texture()); | 862 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 867 return new PorterDuffXferProcessor(blendFormula); | 863 return new PorterDuffXferProcessor(blendFormula); |
| 868 } | 864 } |
| 869 | 865 |
| 870 bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, | 866 bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, |
| 871 const GrProcOptInfo& color
POI, | 867 const GrPipelineOptimizati
ons& optimizations, |
| 872 const GrProcOptInfo& covPO
I, | |
| 873 bool hasMixedSamples) { | 868 bool hasMixedSamples) { |
| 874 if (caps.shaderCaps()->dstReadInShaderSupport() || | 869 if (caps.shaderCaps()->dstReadInShaderSupport() || |
| 875 caps.shaderCaps()->dualSourceBlendingSupport()) { | 870 caps.shaderCaps()->dualSourceBlendingSupport()) { |
| 876 return false; | 871 return false; |
| 877 } | 872 } |
| 878 | 873 |
| 879 // When we have four channel coverage we always need to read the dst in orde
r to correctly | 874 // When we have four channel coverage we always need to read the dst in orde
r to correctly |
| 880 // blend. The one exception is when we are using srcover mode and we know th
e input color | 875 // blend. The one exception is when we are using srcover mode and we know th
e input color |
| 881 // into the XP. | 876 // into the XP. |
| 882 if (covPOI.isFourChannelOutput()) { | 877 if (optimizations.fCoveragePOI.isFourChannelOutput()) { |
| 883 if (kRGBA_GrColorComponentFlags == colorPOI.validFlags() && | 878 if (kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& |
| 884 !caps.shaderCaps()->dstReadInShaderSupport()) { | 879 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 885 return false; | 880 return false; |
| 886 } | 881 } |
| 887 return get_lcd_blend_formula(covPOI, SkXfermode::kSrcOver_Mode).hasSecon
daryOutput(); | 882 return get_lcd_blend_formula(optimizations.fCoveragePOI, |
| 883 SkXfermode::kSrcOver_Mode).hasSecondaryOutp
ut(); |
| 888 } | 884 } |
| 889 // We fallback on the shader XP when the blend formula would use dual source
blending but we | 885 // We fallback on the shader XP when the blend formula would use dual source
blending but we |
| 890 // don't have support for it. | 886 // don't have support for it. |
| 891 return get_blend_formula(colorPOI, covPOI, | 887 return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI
, |
| 892 hasMixedSamples, SkXfermode::kSrcOver_Mode).hasSeco
ndaryOutput(); | 888 hasMixedSamples, SkXfermode::kSrcOver_Mode).hasSeco
ndaryOutput(); |
| 893 } | 889 } |
| 894 | 890 |
| OLD | NEW |