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 |