| 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 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode); | 334 SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode); |
| 335 SkASSERT(coveragePOI.isFourChannelOutput()); | 335 SkASSERT(coveragePOI.isFourChannelOutput()); |
| 336 | 336 |
| 337 return gLCDBlendTable[xfermode]; | 337 return gLCDBlendTable[xfermode]; |
| 338 } | 338 } |
| 339 | 339 |
| 340 /////////////////////////////////////////////////////////////////////////////// | 340 /////////////////////////////////////////////////////////////////////////////// |
| 341 | 341 |
| 342 class PorterDuffXferProcessor : public GrXferProcessor { | 342 class PorterDuffXferProcessor : public GrXferProcessor { |
| 343 public: | 343 public: |
| 344 PorterDuffXferProcessor(BlendFormula blendFormula) : fBlendFormula(blendForm
ula) { | 344 PorterDuffXferProcessor(BlendFormula blendFormula, GrRenderTarget* dst) : IN
HERITED(dst), fBlendFormula(blendFormula) { |
| 345 this->initClassID<PorterDuffXferProcessor>(); | 345 this->initClassID<PorterDuffXferProcessor>(); |
| 346 } | 346 } |
| 347 | 347 |
| 348 const char* name() const override { return "Porter Duff"; } | 348 const char* name() const override { return "Porter Duff"; } |
| 349 | 349 |
| 350 GrGLXferProcessor* createGLInstance() const override; | 350 GrGLXferProcessor* createGLInstance() const override; |
| 351 | 351 |
| 352 BlendFormula getBlendFormula() const { return fBlendFormula; } | 352 BlendFormula getBlendFormula() const { return fBlendFormula; } |
| 353 | 353 |
| 354 private: | 354 private: |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, | 472 PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, |
| 473 const GrProcOptInfo& coveragePOI, | 473 const GrProcOptInfo& coveragePOI, |
| 474 bool doesStencilWrite, | 474 bool doesStencilWrite, |
| 475 GrColor* overrideColor, | 475 GrColor* overrideColor, |
| 476 const GrCaps& caps) { | 476 const GrCaps& caps) { |
| 477 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; | 477 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; |
| 478 if (!fBlendFormula.modifiesDst()) { | 478 if (!fBlendFormula.modifiesDst()) { |
| 479 if (!doesStencilWrite) { | 479 if (!doesStencilWrite) { |
| 480 optFlags |= GrXferProcessor::kSkipDraw_OptFlag; | 480 optFlags |= GrXferProcessor::kSkipDraw_OptFlag; |
| 481 } | 481 } |
| 482 optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag | | 482 optFlags |= (//GrXferProcessor::kIgnoreColor_OptFlag | |
| 483 GrXferProcessor::kIgnoreCoverage_OptFlag | | 483 //GrXferProcessor::kIgnoreCoverage_OptFlag | |
| 484 GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag); | 484 GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag); |
| 485 } else { | 485 } else { |
| 486 if (!fBlendFormula.usesInputColor()) { | 486 if (!fBlendFormula.usesInputColor()) { |
| 487 optFlags |= GrXferProcessor::kIgnoreColor_OptFlag; | 487 // This optimization winds up having the texture access counted |
| 488 // but the pipe-line access not - this is good but messes up the ass
erts |
| 489 //optFlags |= GrXferProcessor::kIgnoreColor_OptFlag; |
| 488 } | 490 } |
| 489 if (coveragePOI.isSolidWhite()) { | 491 if (coveragePOI.isSolidWhite()) { |
| 490 optFlags |= GrXferProcessor::kIgnoreCoverage_OptFlag; | 492 //optFlags |= GrXferProcessor::kIgnoreCoverage_OptFlag; |
| 491 } | 493 } |
| 492 if (colorPOI.allStagesMultiplyInput() && | 494 if (colorPOI.allStagesMultiplyInput() && |
| 493 fBlendFormula.canTweakAlphaForCoverage() && | 495 fBlendFormula.canTweakAlphaForCoverage() && |
| 494 !coveragePOI.isFourChannelOutput()) { | 496 !coveragePOI.isFourChannelOutput()) { |
| 495 optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; | 497 optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; |
| 496 } | 498 } |
| 497 } | 499 } |
| 498 return optFlags; | 500 return optFlags; |
| 499 } | 501 } |
| 500 | 502 |
| 501 /////////////////////////////////////////////////////////////////////////////// | 503 /////////////////////////////////////////////////////////////////////////////// |
| 502 | 504 |
| 503 class ShaderPDXferProcessor : public GrXferProcessor { | 505 class ShaderPDXferProcessor : public GrXferProcessor { |
| 504 public: | 506 public: |
| 505 ShaderPDXferProcessor(const DstTexture* dstTexture, | 507 ShaderPDXferProcessor(const DstTexture* dstTexture, |
| 506 bool hasMixedSamples, | 508 bool hasMixedSamples, |
| 507 SkXfermode::Mode xfermode) | 509 SkXfermode::Mode xfermode, GrRenderTarget* dst) |
| 508 : INHERITED(dstTexture, true, hasMixedSamples) | 510 : INHERITED(dstTexture, true, hasMixedSamples, dst) |
| 509 , fXfermode(xfermode) { | 511 , fXfermode(xfermode) { |
| 510 this->initClassID<ShaderPDXferProcessor>(); | 512 this->initClassID<ShaderPDXferProcessor>(); |
| 511 } | 513 } |
| 512 | 514 |
| 513 const char* name() const override { return "Porter Duff Shader"; } | 515 const char* name() const override { return "Porter Duff Shader"; } |
| 514 | 516 |
| 515 GrGLXferProcessor* createGLInstance() const override; | 517 GrGLXferProcessor* createGLInstance() const override; |
| 516 | 518 |
| 517 SkXfermode::Mode getXfermode() const { return fXfermode; } | 519 SkXfermode::Mode getXfermode() const { return fXfermode; } |
| 518 | 520 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 } | 567 } |
| 566 | 568 |
| 567 GrGLXferProcessor* ShaderPDXferProcessor::createGLInstance() const { | 569 GrGLXferProcessor* ShaderPDXferProcessor::createGLInstance() const { |
| 568 return new GLShaderPDXferProcessor; | 570 return new GLShaderPDXferProcessor; |
| 569 } | 571 } |
| 570 | 572 |
| 571 /////////////////////////////////////////////////////////////////////////////// | 573 /////////////////////////////////////////////////////////////////////////////// |
| 572 | 574 |
| 573 class PDLCDXferProcessor : public GrXferProcessor { | 575 class PDLCDXferProcessor : public GrXferProcessor { |
| 574 public: | 576 public: |
| 575 static GrXferProcessor* Create(SkXfermode::Mode xfermode, const GrProcOptInf
o& colorPOI); | 577 static GrXferProcessor* Create(SkXfermode::Mode xfermode, const GrProcOptInf
o& colorPOI, GrRenderTarget* dst); |
| 576 | 578 |
| 577 ~PDLCDXferProcessor() override; | 579 ~PDLCDXferProcessor() override; |
| 578 | 580 |
| 579 const char* name() const override { return "Porter Duff LCD"; } | 581 const char* name() const override { return "Porter Duff LCD"; } |
| 580 | 582 |
| 581 GrGLXferProcessor* createGLInstance() const override; | 583 GrGLXferProcessor* createGLInstance() const override; |
| 582 | 584 |
| 583 private: | 585 private: |
| 584 PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha); | 586 PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha, GrRenderTarget* dst
); |
| 585 | 587 |
| 586 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, | 588 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, |
| 587 const GrProcOptInfo& coveragePO
I, | 589 const GrProcOptInfo& coveragePO
I, |
| 588 bool doesStencilWrite, | 590 bool doesStencilWrite, |
| 589 GrColor* overrideColor, | 591 GrColor* overrideColor, |
| 590 const GrCaps& caps) override; | 592 const GrCaps& caps) override; |
| 591 | 593 |
| 592 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c
onst override; | 594 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c
onst override; |
| 593 | 595 |
| 594 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { | 596 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 args.fInputCoverage); | 632 args.fInputCoverage); |
| 631 } | 633 } |
| 632 | 634 |
| 633 void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) over
ride {}; | 635 void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) over
ride {}; |
| 634 | 636 |
| 635 typedef GrGLXferProcessor INHERITED; | 637 typedef GrGLXferProcessor INHERITED; |
| 636 }; | 638 }; |
| 637 | 639 |
| 638 /////////////////////////////////////////////////////////////////////////////// | 640 /////////////////////////////////////////////////////////////////////////////// |
| 639 | 641 |
| 640 PDLCDXferProcessor::PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha) | 642 PDLCDXferProcessor::PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha, GrR
enderTarget* dst) |
| 641 : fBlendConstant(blendConstant) | 643 : INHERITED(dst), fBlendConstant(blendConstant) |
| 642 , fAlpha(alpha) { | 644 , fAlpha(alpha) { |
| 643 this->initClassID<PDLCDXferProcessor>(); | 645 this->initClassID<PDLCDXferProcessor>(); |
| 644 } | 646 } |
| 645 | 647 |
| 646 GrXferProcessor* PDLCDXferProcessor::Create(SkXfermode::Mode xfermode, | 648 GrXferProcessor* PDLCDXferProcessor::Create(SkXfermode::Mode xfermode, |
| 647 const GrProcOptInfo& colorPOI) { | 649 const GrProcOptInfo& colorPOI, GrRen
derTarget* dst) { |
| 648 if (SkXfermode::kSrcOver_Mode != xfermode) { | 650 if (SkXfermode::kSrcOver_Mode != xfermode) { |
| 649 return nullptr; | 651 return nullptr; |
| 650 } | 652 } |
| 651 | 653 |
| 652 if (kRGBA_GrColorComponentFlags != colorPOI.validFlags()) { | 654 if (kRGBA_GrColorComponentFlags != colorPOI.validFlags()) { |
| 653 return nullptr; | 655 return nullptr; |
| 654 } | 656 } |
| 655 | 657 |
| 656 GrColor blendConstant = GrUnpremulColor(colorPOI.color()); | 658 GrColor blendConstant = GrUnpremulColor(colorPOI.color()); |
| 657 uint8_t alpha = GrColorUnpackA(blendConstant); | 659 uint8_t alpha = GrColorUnpackA(blendConstant); |
| 658 blendConstant |= (0xff << GrColor_SHIFT_A); | 660 blendConstant |= (0xff << GrColor_SHIFT_A); |
| 659 | 661 |
| 660 return new PDLCDXferProcessor(blendConstant, alpha); | 662 return new PDLCDXferProcessor(blendConstant, alpha, dst); |
| 661 } | 663 } |
| 662 | 664 |
| 663 PDLCDXferProcessor::~PDLCDXferProcessor() { | 665 PDLCDXferProcessor::~PDLCDXferProcessor() { |
| 664 } | 666 } |
| 665 | 667 |
| 666 void PDLCDXferProcessor::onGetGLProcessorKey(const GrGLSLCaps& caps, | 668 void PDLCDXferProcessor::onGetGLProcessorKey(const GrGLSLCaps& caps, |
| 667 GrProcessorKeyBuilder* b) const { | 669 GrProcessorKeyBuilder* b) const { |
| 668 GLPDLCDXferProcessor::GenKey(*this, caps, b); | 670 GLPDLCDXferProcessor::GenKey(*this, caps, b); |
| 669 } | 671 } |
| 670 | 672 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 return nullptr; | 724 return nullptr; |
| 723 } | 725 } |
| 724 return SkRef(gFactories[xfermode]); | 726 return SkRef(gFactories[xfermode]); |
| 725 } | 727 } |
| 726 | 728 |
| 727 GrXferProcessor* | 729 GrXferProcessor* |
| 728 GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, | 730 GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, |
| 729 const GrProcOptInfo& colorPOI, | 731 const GrProcOptInfo& colorPOI, |
| 730 const GrProcOptInfo& covPOI, | 732 const GrProcOptInfo& covPOI, |
| 731 bool hasMixedSamples, | 733 bool hasMixedSamples, |
| 732 const DstTexture* dstTexture) const
{ | 734 const DstTexture* dstTexture, GrRen
derTarget* dst) const { |
| 733 BlendFormula blendFormula; | 735 BlendFormula blendFormula; |
| 734 if (covPOI.isFourChannelOutput()) { | 736 if (covPOI.isFourChannelOutput()) { |
| 735 if (SkXfermode::kSrcOver_Mode == fXfermode && | 737 if (SkXfermode::kSrcOver_Mode == fXfermode && |
| 736 kRGBA_GrColorComponentFlags == colorPOI.validFlags() && | 738 kRGBA_GrColorComponentFlags == colorPOI.validFlags() && |
| 737 !caps.shaderCaps()->dualSourceBlendingSupport() && | 739 !caps.shaderCaps()->dualSourceBlendingSupport() && |
| 738 !caps.shaderCaps()->dstReadInShaderSupport()) { | 740 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 739 // If we don't have dual source blending or in shader dst reads, we
fall back to this | 741 // If we don't have dual source blending or in shader dst reads, we
fall back to this |
| 740 // trick for rendering SrcOver LCD text instead of doing a dst copy. | 742 // trick for rendering SrcOver LCD text instead of doing a dst copy. |
| 741 SkASSERT(!dstTexture || !dstTexture->texture()); | 743 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 742 return PDLCDXferProcessor::Create(fXfermode, colorPOI); | 744 return PDLCDXferProcessor::Create(fXfermode, colorPOI, dst); |
| 743 } | 745 } |
| 744 blendFormula = get_lcd_blend_formula(covPOI, fXfermode); | 746 blendFormula = get_lcd_blend_formula(covPOI, fXfermode); |
| 745 } else { | 747 } else { |
| 746 blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfe
rmode); | 748 blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfe
rmode); |
| 747 } | 749 } |
| 748 | 750 |
| 749 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { | 751 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend
ingSupport()) { |
| 750 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode)
; | 752 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode,
dst); |
| 751 } | 753 } |
| 752 | 754 |
| 753 SkASSERT(!dstTexture || !dstTexture->texture()); | 755 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 754 return new PorterDuffXferProcessor(blendFormula); | 756 return new PorterDuffXferProcessor(blendFormula, dst); |
| 755 } | 757 } |
| 756 | 758 |
| 757 void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP
OI, | 759 void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP
OI, |
| 758 InvariantBlendedColor* blen
dedColor) const { | 760 InvariantBlendedColor* blen
dedColor) const { |
| 759 // Find the blended color info based on the formula that does not have cover
age. | 761 // Find the blended color info based on the formula that does not have cover
age. |
| 760 BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][fXfermode]; | 762 BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][fXfermode]; |
| 761 if (colorFormula.usesDstColor()) { | 763 if (colorFormula.usesDstColor()) { |
| 762 blendedColor->fWillBlendWithDst = true; | 764 blendedColor->fWillBlendWithDst = true; |
| 763 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; | 765 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; |
| 764 return; | 766 return; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 int* outPrimary, | 822 int* outPrimary, |
| 821 int* outSecondary) { | 823 int* outSecondary) { |
| 822 if (!!strcmp(xp->name(), "Porter Duff")) { | 824 if (!!strcmp(xp->name(), "Porter Duff")) { |
| 823 *outPrimary = *outSecondary = -1; | 825 *outPrimary = *outSecondary = -1; |
| 824 return; | 826 return; |
| 825 } | 827 } |
| 826 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)-
>getBlendFormula(); | 828 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)-
>getBlendFormula(); |
| 827 *outPrimary = blendFormula.fPrimaryOutputType; | 829 *outPrimary = blendFormula.fPrimaryOutputType; |
| 828 *outSecondary = blendFormula.fSecondaryOutputType; | 830 *outSecondary = blendFormula.fSecondaryOutputType; |
| 829 } | 831 } |
| OLD | NEW |