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 |