| 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 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 this->initClassID<ShaderPDXferProcessor>(); | 512 this->initClassID<ShaderPDXferProcessor>(); |
| 513 } | 513 } |
| 514 | 514 |
| 515 const char* name() const override { return "Porter Duff Shader"; } | 515 const char* name() const override { return "Porter Duff Shader"; } |
| 516 | 516 |
| 517 GrGLSLXferProcessor* createGLSLInstance() const override; | 517 GrGLSLXferProcessor* createGLSLInstance() const override; |
| 518 | 518 |
| 519 SkXfermode::Mode getXfermode() const { return fXfermode; } | 519 SkXfermode::Mode getXfermode() const { return fXfermode; } |
| 520 | 520 |
| 521 private: | 521 private: |
| 522 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&,
bool, GrColor*, | 522 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&,
bool, GrColor*, |
| 523 const GrCaps&) const override { | 523 const GrCaps&) const override { |
| 524 return kNone_OptFlags; | 524 return kNone_OptFlags; |
| 525 } | 525 } |
| 526 | 526 |
| 527 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; | 527 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; |
| 528 | 528 |
| 529 bool onIsEqual(const GrXferProcessor& xpBase) const override { | 529 bool onIsEqual(const GrXferProcessor& xpBase) const override { |
| 530 const ShaderPDXferProcessor& xp = xpBase.cast<ShaderPDXferProcessor>(); | 530 const ShaderPDXferProcessor& xp = xpBase.cast<ShaderPDXferProcessor>(); |
| 531 return fXfermode == xp.fXfermode; | 531 return fXfermode == xp.fXfermode; |
| 532 } | 532 } |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& | 748 kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& |
| 749 !caps.shaderCaps()->dualSourceBlendingSupport() && | 749 !caps.shaderCaps()->dualSourceBlendingSupport() && |
| 750 !caps.shaderCaps()->dstReadInShaderSupport()) { | 750 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 751 // If we don't have dual source blending or in shader dst reads, we
fall back to this | 751 // If we don't have dual source blending or in shader dst reads, we
fall back to this |
| 752 // trick for rendering SrcOver LCD text instead of doing a dst copy. | 752 // trick for rendering SrcOver LCD text instead of doing a dst copy. |
| 753 SkASSERT(!dstTexture || !dstTexture->texture()); | 753 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 754 return PDLCDXferProcessor::Create(fXfermode, optimizations.fColorPOI
); | 754 return PDLCDXferProcessor::Create(fXfermode, optimizations.fColorPOI
); |
| 755 } | 755 } |
| 756 blendFormula = get_lcd_blend_formula(optimizations.fCoveragePOI, fXfermo
de); | 756 blendFormula = get_lcd_blend_formula(optimizations.fCoveragePOI, fXfermo
de); |
| 757 } else { | 757 } else { |
| 758 blendFormula = get_blend_formula(optimizations.fColorPOI, optimizations.
fCoveragePOI, | 758 blendFormula = get_blend_formula(optimizations.fColorPOI, optimizations.
fCoveragePOI, |
| 759 hasMixedSamples, fXfermode); | 759 hasMixedSamples, fXfermode); |
| 760 } | 760 } |
| 761 | 761 |
| 762 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { | 762 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { |
| 763 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode)
; | 763 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode)
; |
| 764 } | 764 } |
| 765 | 765 |
| 766 SkASSERT(!dstTexture || !dstTexture->texture()); | 766 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 767 return new PorterDuffXferProcessor(blendFormula); | 767 return new PorterDuffXferProcessor(blendFormula); |
| 768 } | 768 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 797 return; | 797 return; |
| 798 } | 798 } |
| 799 } | 799 } |
| 800 | 800 |
| 801 bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps, | 801 bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps, |
| 802 const GrPipelineOptimizations& op
timizations, | 802 const GrPipelineOptimizations& op
timizations, |
| 803 bool hasMixedSamples) const { | 803 bool hasMixedSamples) const { |
| 804 if (caps.shaderCaps()->dualSourceBlendingSupport()) { | 804 if (caps.shaderCaps()->dualSourceBlendingSupport()) { |
| 805 return false; | 805 return false; |
| 806 } | 806 } |
| 807 | 807 |
| 808 // When we have four channel coverage we always need to read the dst in orde
r to correctly | 808 // When we have four channel coverage we always need to read the dst in orde
r to correctly |
| 809 // blend. The one exception is when we are using srcover mode and we know th
e input color into | 809 // blend. The one exception is when we are using srcover mode and we know th
e input color into |
| 810 // the XP. | 810 // the XP. |
| 811 if (optimizations.fCoveragePOI.isFourChannelOutput()) { | 811 if (optimizations.fCoveragePOI.isFourChannelOutput()) { |
| 812 if (SkXfermode::kSrcOver_Mode == fXfermode && | 812 if (SkXfermode::kSrcOver_Mode == fXfermode && |
| 813 kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& | 813 kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& |
| 814 !caps.shaderCaps()->dstReadInShaderSupport()) { | 814 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 815 return false; | 815 return false; |
| 816 } | 816 } |
| 817 return get_lcd_blend_formula(optimizations.fCoveragePOI, fXfermode).hasS
econdaryOutput(); | 817 return get_lcd_blend_formula(optimizations.fCoveragePOI, fXfermode).hasS
econdaryOutput(); |
| 818 } | 818 } |
| 819 // We fallback on the shader XP when the blend formula would use dual source
blending but we | 819 // We fallback on the shader XP when the blend formula would use dual source
blending but we |
| 820 // don't have support for it. | 820 // don't have support for it. |
| 821 return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI
, hasMixedSamples, | 821 return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI
, hasMixedSamples, |
| 822 fXfermode).hasSecondaryOutput(); | 822 fXfermode).hasSecondaryOutput(); |
| 823 } | 823 } |
| 824 | 824 |
| 825 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); | 825 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); |
| 826 | 826 |
| 827 const GrXPFactory* GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) { | 827 const GrXPFactory* GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) { |
| 828 SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermod
e::kLastCoeffMode)); | 828 SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermod
e::kLastCoeffMode)); |
| 829 return GrPorterDuffXPFactory::Create(mode); | 829 return GrPorterDuffXPFactory::Create(mode); |
| 830 } | 830 } |
| 831 | 831 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 !caps.shaderCaps()->dualSourceBlendingSupport() && | 877 !caps.shaderCaps()->dualSourceBlendingSupport() && |
| 878 !caps.shaderCaps()->dstReadInShaderSupport()) { | 878 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 879 // If we don't have dual source blending or in shader dst reads, we
fall | 879 // If we don't have dual source blending or in shader dst reads, we
fall |
| 880 // back to this trick for rendering SrcOver LCD text instead of doin
g a | 880 // back to this trick for rendering SrcOver LCD text instead of doin
g a |
| 881 // dst copy. | 881 // dst copy. |
| 882 SkASSERT(!dstTexture || !dstTexture->texture()); | 882 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 883 return PDLCDXferProcessor::Create(SkXfermode::kSrcOver_Mode, optimiz
ations.fColorPOI); | 883 return PDLCDXferProcessor::Create(SkXfermode::kSrcOver_Mode, optimiz
ations.fColorPOI); |
| 884 } | 884 } |
| 885 blendFormula = get_lcd_blend_formula(optimizations.fCoveragePOI, SkXferm
ode::kSrcOver_Mode); | 885 blendFormula = get_lcd_blend_formula(optimizations.fCoveragePOI, SkXferm
ode::kSrcOver_Mode); |
| 886 } else { | 886 } else { |
| 887 blendFormula = get_blend_formula(optimizations.fColorPOI, optimizations.
fCoveragePOI, | 887 blendFormula = get_blend_formula(optimizations.fColorPOI, optimizations.
fCoveragePOI, |
| 888 hasMixedSamples, SkXfermode::kSrcOver_M
ode); | 888 hasMixedSamples, SkXfermode::kSrcOver_M
ode); |
| 889 } | 889 } |
| 890 | 890 |
| 891 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { | 891 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { |
| 892 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkXfermode
::kSrcOver_Mode); | 892 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkXfermode
::kSrcOver_Mode); |
| 893 } | 893 } |
| 894 | 894 |
| 895 SkASSERT(!dstTexture || !dstTexture->texture()); | 895 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 896 return new PorterDuffXferProcessor(blendFormula); | 896 return new PorterDuffXferProcessor(blendFormula); |
| 897 } | 897 } |
| 898 | 898 |
| 899 bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, | 899 bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, |
| 900 const GrPipelineOptimizati
ons& optimizations, | 900 const GrPipelineOptimizati
ons& optimizations, |
| 901 bool hasMixedSamples) { | 901 bool hasMixedSamples) { |
| 902 if (caps.shaderCaps()->dstReadInShaderSupport() || | 902 if (caps.shaderCaps()->dstReadInShaderSupport() || |
| 903 caps.shaderCaps()->dualSourceBlendingSupport()) { | 903 caps.shaderCaps()->dualSourceBlendingSupport()) { |
| 904 return false; | 904 return false; |
| 905 } | 905 } |
| 906 | 906 |
| 907 // When we have four channel coverage we always need to read the dst in orde
r to correctly | 907 // When we have four channel coverage we always need to read the dst in orde
r to correctly |
| 908 // blend. The one exception is when we are using srcover mode and we know th
e input color | 908 // blend. The one exception is when we are using srcover mode and we know th
e input color |
| 909 // into the XP. | 909 // into the XP. |
| 910 if (optimizations.fCoveragePOI.isFourChannelOutput()) { | 910 if (optimizations.fCoveragePOI.isFourChannelOutput()) { |
| 911 if (kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& | 911 if (kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& |
| 912 !caps.shaderCaps()->dstReadInShaderSupport()) { | 912 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 913 return false; | 913 return false; |
| 914 } | 914 } |
| 915 return get_lcd_blend_formula(optimizations.fCoveragePOI, | 915 return get_lcd_blend_formula(optimizations.fCoveragePOI, |
| 916 SkXfermode::kSrcOver_Mode).hasSecondaryOutp
ut(); | 916 SkXfermode::kSrcOver_Mode).hasSecondaryOutp
ut(); |
| 917 } | 917 } |
| 918 // We fallback on the shader XP when the blend formula would use dual source
blending but we | 918 // We fallback on the shader XP when the blend formula would use dual source
blending but we |
| 919 // don't have support for it. | 919 // don't have support for it. |
| 920 return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI
, | 920 return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI
, |
| 921 hasMixedSamples, SkXfermode::kSrcOver_Mode).hasSeco
ndaryOutput(); | 921 hasMixedSamples, SkXfermode::kSrcOver_Mode).hasSeco
ndaryOutput(); |
| 922 } | 922 } |
| 923 | |
| OLD | NEW |