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 |