| 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 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 const char* name() const override { return "Porter Duff"; } | 349 const char* name() const override { return "Porter Duff"; } |
| 350 | 350 |
| 351 GrGLSLXferProcessor* createGLSLInstance() const override; | 351 GrGLSLXferProcessor* createGLSLInstance() const override; |
| 352 | 352 |
| 353 BlendFormula getBlendFormula() const { return fBlendFormula; } | 353 BlendFormula getBlendFormula() const { return fBlendFormula; } |
| 354 | 354 |
| 355 private: | 355 private: |
| 356 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&
optimizations, | 356 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&
optimizations, |
| 357 bool doesStencilWrite, | 357 bool doesStencilWrite, |
| 358 GrColor* overrideColor, | 358 GrColor* overrideColor, |
| 359 const GrCaps& caps) override; | 359 const GrCaps& caps) const overr
ide; |
| 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; |
| 367 blendInfo->fSrcBlend = fBlendFormula.fSrcCoeff; | 367 blendInfo->fSrcBlend = fBlendFormula.fSrcCoeff; |
| 368 blendInfo->fDstBlend = fBlendFormula.fDstCoeff; | 368 blendInfo->fDstBlend = fBlendFormula.fDstCoeff; |
| 369 blendInfo->fWriteColor = fBlendFormula.modifiesDst(); | 369 blendInfo->fWriteColor = fBlendFormula.modifiesDst(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 384 static void append_color_output(const PorterDuffXferProcessor& xp, | 384 static void append_color_output(const PorterDuffXferProcessor& xp, |
| 385 GrGLSLXPFragmentBuilder* fragBuilder, | 385 GrGLSLXPFragmentBuilder* fragBuilder, |
| 386 BlendFormula::OutputType outputType, const char*
output, | 386 BlendFormula::OutputType outputType, const char*
output, |
| 387 const char* inColor, const char* inCoverage) { | 387 const char* inColor, const char* inCoverage) { |
| 388 switch (outputType) { | 388 switch (outputType) { |
| 389 case BlendFormula::kNone_OutputType: | 389 case BlendFormula::kNone_OutputType: |
| 390 fragBuilder->codeAppendf("%s = vec4(0.0);", output); | 390 fragBuilder->codeAppendf("%s = vec4(0.0);", output); |
| 391 break; | 391 break; |
| 392 case BlendFormula::kCoverage_OutputType: | 392 case BlendFormula::kCoverage_OutputType: |
| 393 // We can have a coverage formula while not reading coverage if ther
e are mixed samples. | 393 // We can have a coverage formula while not reading coverage if ther
e are mixed samples. |
| 394 fragBuilder->codeAppendf("%s = %s;", | 394 if (inCoverage) { |
| 395 output, xp.readsCoverage() ? inCoverage : "ve
c4(1.0)"); | 395 fragBuilder->codeAppendf("%s = %s;", output, inCoverage); |
| 396 } else { |
| 397 fragBuilder->codeAppendf("%s = vec4(1.0);", output); |
| 398 } |
| 396 break; | 399 break; |
| 397 case BlendFormula::kModulate_OutputType: | 400 case BlendFormula::kModulate_OutputType: |
| 398 if (xp.readsCoverage()) { | 401 if (inCoverage) { |
| 399 fragBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCov
erage); | 402 fragBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCov
erage); |
| 400 } else { | 403 } else { |
| 401 fragBuilder->codeAppendf("%s = %s;", output, inColor); | 404 fragBuilder->codeAppendf("%s = %s;", output, inColor); |
| 402 } | 405 } |
| 403 break; | 406 break; |
| 404 case BlendFormula::kSAModulate_OutputType: | 407 case BlendFormula::kSAModulate_OutputType: |
| 405 if (xp.readsCoverage()) { | 408 if (inCoverage) { |
| 406 fragBuilder->codeAppendf("%s = %s.a * %s;", output, inColor, inC
overage); | 409 fragBuilder->codeAppendf("%s = %s.a * %s;", output, inColor, inC
overage); |
| 407 } else { | 410 } else { |
| 408 fragBuilder->codeAppendf("%s = %s;", output, inColor); | 411 fragBuilder->codeAppendf("%s = %s;", output, inColor); |
| 409 } | 412 } |
| 410 break; | 413 break; |
| 411 case BlendFormula::kISAModulate_OutputType: | 414 case BlendFormula::kISAModulate_OutputType: |
| 412 if (xp.readsCoverage()) { | 415 if (inCoverage) { |
| 413 fragBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inCo
lor, inCoverage); | 416 fragBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inCo
lor, inCoverage); |
| 414 } else { | 417 } else { |
| 415 fragBuilder->codeAppendf("%s = vec4(1.0 - %s.a);", output, inCol
or); | 418 fragBuilder->codeAppendf("%s = vec4(1.0 - %s.a);", output, inCol
or); |
| 416 } | 419 } |
| 417 break; | 420 break; |
| 418 case BlendFormula::kISCModulate_OutputType: | 421 case BlendFormula::kISCModulate_OutputType: |
| 419 if (xp.readsCoverage()) { | 422 if (inCoverage) { |
| 420 fragBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", output,
inColor, inCoverage); | 423 fragBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", output,
inColor, inCoverage); |
| 421 } else { | 424 } else { |
| 422 fragBuilder->codeAppendf("%s = vec4(1.0) - %s;", output, inColor
); | 425 fragBuilder->codeAppendf("%s = vec4(1.0) - %s;", output, inColor
); |
| 423 } | 426 } |
| 424 break; | 427 break; |
| 425 default: | 428 default: |
| 426 SkFAIL("Unsupported output type."); | 429 SkFAIL("Unsupported output type."); |
| 427 break; | 430 break; |
| 428 } | 431 } |
| 429 } | 432 } |
| 430 | 433 |
| 431 class GLPorterDuffXferProcessor : public GrGLSLXferProcessor { | 434 class GLPorterDuffXferProcessor : public GrGLSLXferProcessor { |
| 432 public: | 435 public: |
| 433 static void GenKey(const GrProcessor& processor, GrProcessorKeyBuilder* b) { | 436 static void GenKey(const GrProcessor& processor, GrProcessorKeyBuilder* b) { |
| 434 const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcess
or>(); | 437 const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcess
or>(); |
| 435 b->add32(SkToInt(xp.readsCoverage()) | | 438 b->add32(xp.getBlendFormula().fPrimaryOutputType | |
| 436 (xp.getBlendFormula().fPrimaryOutputType << 1) | | 439 (xp.getBlendFormula().fSecondaryOutputType << 3)); |
| 437 (xp.getBlendFormula().fSecondaryOutputType << 4)); | |
| 438 GR_STATIC_ASSERT(BlendFormula::kLast_OutputType < 8); | 440 GR_STATIC_ASSERT(BlendFormula::kLast_OutputType < 8); |
| 439 }; | 441 }; |
| 440 | 442 |
| 441 private: | 443 private: |
| 442 void emitOutputsForBlendState(const EmitArgs& args) override { | 444 void emitOutputsForBlendState(const EmitArgs& args) override { |
| 443 const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcesso
r>(); | 445 const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcesso
r>(); |
| 444 GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder; | 446 GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder; |
| 445 | 447 |
| 446 BlendFormula blendFormula = xp.getBlendFormula(); | 448 BlendFormula blendFormula = xp.getBlendFormula(); |
| 447 if (blendFormula.hasSecondaryOutput()) { | 449 if (blendFormula.hasSecondaryOutput()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 465 } | 467 } |
| 466 | 468 |
| 467 GrGLSLXferProcessor* PorterDuffXferProcessor::createGLSLInstance() const { | 469 GrGLSLXferProcessor* PorterDuffXferProcessor::createGLSLInstance() const { |
| 468 return new GLPorterDuffXferProcessor; | 470 return new GLPorterDuffXferProcessor; |
| 469 } | 471 } |
| 470 | 472 |
| 471 GrXferProcessor::OptFlags | 473 GrXferProcessor::OptFlags |
| 472 PorterDuffXferProcessor::onGetOptimizations(const GrPipelineOptimizations& optim
izations, | 474 PorterDuffXferProcessor::onGetOptimizations(const GrPipelineOptimizations& optim
izations, |
| 473 bool doesStencilWrite, | 475 bool doesStencilWrite, |
| 474 GrColor* overrideColor, | 476 GrColor* overrideColor, |
| 475 const GrCaps& caps) { | 477 const GrCaps& caps) const { |
| 476 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; | 478 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; |
| 477 if (!fBlendFormula.modifiesDst()) { | 479 if (!fBlendFormula.modifiesDst()) { |
| 478 if (!doesStencilWrite) { | 480 if (!doesStencilWrite) { |
| 479 optFlags |= GrXferProcessor::kSkipDraw_OptFlag; | 481 optFlags |= GrXferProcessor::kSkipDraw_OptFlag; |
| 480 } | 482 } |
| 481 optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag | | 483 optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag | |
| 482 GrXferProcessor::kIgnoreCoverage_OptFlag | | 484 GrXferProcessor::kIgnoreCoverage_OptFlag | |
| 483 GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag); | 485 GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag); |
| 484 } else { | 486 } else { |
| 485 if (!fBlendFormula.usesInputColor()) { | 487 if (!fBlendFormula.usesInputColor()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 510 } | 512 } |
| 511 | 513 |
| 512 const char* name() const override { return "Porter Duff Shader"; } | 514 const char* name() const override { return "Porter Duff Shader"; } |
| 513 | 515 |
| 514 GrGLSLXferProcessor* createGLSLInstance() const override; | 516 GrGLSLXferProcessor* createGLSLInstance() const override; |
| 515 | 517 |
| 516 SkXfermode::Mode getXfermode() const { return fXfermode; } | 518 SkXfermode::Mode getXfermode() const { return fXfermode; } |
| 517 | 519 |
| 518 private: | 520 private: |
| 519 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&,
bool, GrColor*, | 521 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&,
bool, GrColor*, |
| 520 const GrCaps&) override { | 522 const GrCaps&) const override { |
| 521 return kNone_OptFlags; | 523 return kNone_OptFlags; |
| 522 } | 524 } |
| 523 | 525 |
| 524 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; | 526 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; |
| 525 | 527 |
| 526 bool onIsEqual(const GrXferProcessor& xpBase) const override { | 528 bool onIsEqual(const GrXferProcessor& xpBase) const override { |
| 527 const ShaderPDXferProcessor& xp = xpBase.cast<ShaderPDXferProcessor>(); | 529 const ShaderPDXferProcessor& xp = xpBase.cast<ShaderPDXferProcessor>(); |
| 528 return fXfermode == xp.fXfermode; | 530 return fXfermode == xp.fXfermode; |
| 529 } | 531 } |
| 530 | 532 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 const char* name() const override { return "Porter Duff LCD"; } | 583 const char* name() const override { return "Porter Duff LCD"; } |
| 582 | 584 |
| 583 GrGLSLXferProcessor* createGLSLInstance() const override; | 585 GrGLSLXferProcessor* createGLSLInstance() const override; |
| 584 | 586 |
| 585 private: | 587 private: |
| 586 PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha); | 588 PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha); |
| 587 | 589 |
| 588 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&
optimizations, | 590 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&
optimizations, |
| 589 bool doesStencilWrite, | 591 bool doesStencilWrite, |
| 590 GrColor* overrideColor, | 592 GrColor* overrideColor, |
| 591 const GrCaps& caps) override; | 593 const GrCaps& caps) const overr
ide; |
| 592 | 594 |
| 593 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; | 595 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; |
| 594 | 596 |
| 595 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { | 597 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { |
| 596 blendInfo->fSrcBlend = kConstC_GrBlendCoeff; | 598 blendInfo->fSrcBlend = kConstC_GrBlendCoeff; |
| 597 blendInfo->fDstBlend = kISC_GrBlendCoeff; | 599 blendInfo->fDstBlend = kISC_GrBlendCoeff; |
| 598 blendInfo->fBlendConstant = fBlendConstant; | 600 blendInfo->fBlendConstant = fBlendConstant; |
| 599 } | 601 } |
| 600 | 602 |
| 601 bool onIsEqual(const GrXferProcessor& xpBase) const override { | 603 bool onIsEqual(const GrXferProcessor& xpBase) const override { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 620 GLPDLCDXferProcessor(const GrProcessor&) {} | 622 GLPDLCDXferProcessor(const GrProcessor&) {} |
| 621 | 623 |
| 622 virtual ~GLPDLCDXferProcessor() {} | 624 virtual ~GLPDLCDXferProcessor() {} |
| 623 | 625 |
| 624 static void GenKey(const GrProcessor& processor, const GrGLSLCaps& caps, | 626 static void GenKey(const GrProcessor& processor, const GrGLSLCaps& caps, |
| 625 GrProcessorKeyBuilder* b) {} | 627 GrProcessorKeyBuilder* b) {} |
| 626 | 628 |
| 627 private: | 629 private: |
| 628 void emitOutputsForBlendState(const EmitArgs& args) override { | 630 void emitOutputsForBlendState(const EmitArgs& args) override { |
| 629 GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder; | 631 GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder; |
| 632 SkASSERT(args.fInputCoverage); |
| 630 fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInp
utColor, | 633 fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInp
utColor, |
| 631 args.fInputCoverage); | 634 args.fInputCoverage); |
| 632 } | 635 } |
| 633 | 636 |
| 634 void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) over
ride {}; | 637 void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) over
ride {}; |
| 635 | 638 |
| 636 typedef GrGLSLXferProcessor INHERITED; | 639 typedef GrGLSLXferProcessor INHERITED; |
| 637 }; | 640 }; |
| 638 | 641 |
| 639 /////////////////////////////////////////////////////////////////////////////// | 642 /////////////////////////////////////////////////////////////////////////////// |
| (...skipping 30 matching lines...) Expand all Loading... |
| 670 } | 673 } |
| 671 | 674 |
| 672 GrGLSLXferProcessor* PDLCDXferProcessor::createGLSLInstance() const { | 675 GrGLSLXferProcessor* PDLCDXferProcessor::createGLSLInstance() const { |
| 673 return new GLPDLCDXferProcessor(*this); | 676 return new GLPDLCDXferProcessor(*this); |
| 674 } | 677 } |
| 675 | 678 |
| 676 GrXferProcessor::OptFlags | 679 GrXferProcessor::OptFlags |
| 677 PDLCDXferProcessor::onGetOptimizations(const GrPipelineOptimizations& optimizati
ons, | 680 PDLCDXferProcessor::onGetOptimizations(const GrPipelineOptimizations& optimizati
ons, |
| 678 bool doesStencilWrite, | 681 bool doesStencilWrite, |
| 679 GrColor* overrideColor, | 682 GrColor* overrideColor, |
| 680 const GrCaps& caps) { | 683 const GrCaps& caps) const { |
| 681 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha | 684 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha |
| 682 // value of the blend the constant. We should already have valid blend c
oeff's if we are at | 685 // value of the blend the constant. We should already have valid blend c
oeff's if we are at |
| 683 // a point where we have RGB coverage. We don't need any color stages si
nce the known color | 686 // a point where we have RGB coverage. We don't need any color stages si
nce the known color |
| 684 // output is already baked into the blendConstant. | 687 // output is already baked into the blendConstant. |
| 685 *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha); | 688 *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha); |
| 686 return GrXferProcessor::kOverrideColor_OptFlag; | 689 return GrXferProcessor::kOverrideColor_OptFlag; |
| 687 } | 690 } |
| 688 | 691 |
| 689 /////////////////////////////////////////////////////////////////////////////// | 692 /////////////////////////////////////////////////////////////////////////////// |
| 690 | 693 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 | 834 |
| 832 ////////////////////////////////////////////////////////////////////////////////
//////////////// | 835 ////////////////////////////////////////////////////////////////////////////////
//////////////// |
| 833 // SrcOver Global functions | 836 // SrcOver Global functions |
| 834 ////////////////////////////////////////////////////////////////////////////////
//////////////// | 837 ////////////////////////////////////////////////////////////////////////////////
//////////////// |
| 835 | 838 |
| 836 GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor( | 839 GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor( |
| 837 const GrCaps& caps, | 840 const GrCaps& caps, |
| 838 const GrPipelineOptimizations& optimizations, | 841 const GrPipelineOptimizations& optimizations, |
| 839 bool hasMixedSamples, | 842 bool hasMixedSamples, |
| 840 const GrXferProcessor::DstTexture* dstTexture) { | 843 const GrXferProcessor::DstTexture* dstTexture) { |
| 844 if (!optimizations.fCoveragePOI.isFourChannelOutput() && |
| 845 !(optimizations.fCoveragePOI.isSolidWhite() && |
| 846 !hasMixedSamples && |
| 847 optimizations.fColorPOI.isOpaque())) { |
| 848 static BlendFormula gSrcOverBlendFormula = COEFF_FORMULA(kOne_GrBlendCoe
ff, |
| 849 kISA_GrBlendCoe
ff); |
| 850 static PorterDuffXferProcessor gSrcOverXP(gSrcOverBlendFormula); |
| 851 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 852 gSrcOverXP.ref(); |
| 853 return &gSrcOverXP; |
| 854 } |
| 855 |
| 841 BlendFormula blendFormula; | 856 BlendFormula blendFormula; |
| 842 if (optimizations.fCoveragePOI.isFourChannelOutput()) { | 857 if (optimizations.fCoveragePOI.isFourChannelOutput()) { |
| 843 if (kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& | 858 if (kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags()
&& |
| 844 !caps.shaderCaps()->dualSourceBlendingSupport() && | 859 !caps.shaderCaps()->dualSourceBlendingSupport() && |
| 845 !caps.shaderCaps()->dstReadInShaderSupport()) { | 860 !caps.shaderCaps()->dstReadInShaderSupport()) { |
| 846 // If we don't have dual source blending or in shader dst reads, we
fall | 861 // If we don't have dual source blending or in shader dst reads, we
fall |
| 847 // back to this trick for rendering SrcOver LCD text instead of doin
g a | 862 // back to this trick for rendering SrcOver LCD text instead of doin
g a |
| 848 // dst copy. | 863 // dst copy. |
| 849 SkASSERT(!dstTexture || !dstTexture->texture()); | 864 SkASSERT(!dstTexture || !dstTexture->texture()); |
| 850 return PDLCDXferProcessor::Create(SkXfermode::kSrcOver_Mode, optimiz
ations.fColorPOI); | 865 return PDLCDXferProcessor::Create(SkXfermode::kSrcOver_Mode, optimiz
ations.fColorPOI); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 881 } | 896 } |
| 882 return get_lcd_blend_formula(optimizations.fCoveragePOI, | 897 return get_lcd_blend_formula(optimizations.fCoveragePOI, |
| 883 SkXfermode::kSrcOver_Mode).hasSecondaryOutp
ut(); | 898 SkXfermode::kSrcOver_Mode).hasSecondaryOutp
ut(); |
| 884 } | 899 } |
| 885 // We fallback on the shader XP when the blend formula would use dual source
blending but we | 900 // We fallback on the shader XP when the blend formula would use dual source
blending but we |
| 886 // don't have support for it. | 901 // don't have support for it. |
| 887 return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI
, | 902 return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI
, |
| 888 hasMixedSamples, SkXfermode::kSrcOver_Mode).hasSeco
ndaryOutput(); | 903 hasMixedSamples, SkXfermode::kSrcOver_Mode).hasSeco
ndaryOutput(); |
| 889 } | 904 } |
| 890 | 905 |
| OLD | NEW |