| 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 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 GrGLXferProcessor* PorterDuffXferProcessor::createGLInstance() const { | 299 GrGLXferProcessor* PorterDuffXferProcessor::createGLInstance() const { |
| 300 return SkNEW_ARGS(GLPorterDuffXferProcessor, (*this)); | 300 return SkNEW_ARGS(GLPorterDuffXferProcessor, (*this)); |
| 301 } | 301 } |
| 302 | 302 |
| 303 GrXferProcessor::OptFlags | 303 GrXferProcessor::OptFlags |
| 304 PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, | 304 PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, |
| 305 const GrProcOptInfo& coveragePOI, | 305 const GrProcOptInfo& coveragePOI, |
| 306 bool doesStencilWrite, | 306 bool doesStencilWrite, |
| 307 GrColor* overrideColor, | 307 GrColor* overrideColor, |
| 308 const GrDrawTargetCaps& caps) { | 308 const GrDrawTargetCaps& caps) { |
| 309 GrXferProcessor::OptFlags optFlags; | 309 GrXferProcessor::OptFlags optFlags = this->internalGetOptimizations(colorPOI
, |
| 310 // Optimizations when doing RGB Coverage | 310 coverage
POI, |
| 311 if (coveragePOI.isFourChannelOutput()) { | 311 doesSten
cilWrite); |
| 312 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha | |
| 313 // value of the blend the constant. We should already have valid blend c
oeff's if we are at | |
| 314 // a point where we have RGB coverage. We don't need any color stages si
nce the known color | |
| 315 // output is already baked into the blendConstant. | |
| 316 uint8_t alpha = GrColorUnpackA(fBlendConstant); | |
| 317 *overrideColor = GrColorPackRGBA(alpha, alpha, alpha, alpha); | |
| 318 optFlags = GrXferProcessor::kOverrideColor_OptFlag; | |
| 319 } else { | |
| 320 optFlags = this->internalGetOptimizations(colorPOI, | |
| 321 coveragePOI, | |
| 322 doesStencilWrite); | |
| 323 } | |
| 324 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite()); | 312 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite()); |
| 325 return optFlags; | 313 return optFlags; |
| 326 } | 314 } |
| 327 | 315 |
| 328 void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags
, | 316 void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags
, |
| 329 const GrDrawTargetCaps& caps, | 317 const GrDrawTargetCaps& caps, |
| 330 bool hasSolidCoverage) { | 318 bool hasSolidCoverage) { |
| 331 if (this->willReadDstColor()) { | 319 if (this->willReadDstColor()) { |
| 332 fPrimaryOutputType = kCustom_PrimaryOutputType; | 320 fPrimaryOutputType = kCustom_PrimaryOutputType; |
| 333 return; | 321 return; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 | 457 |
| 470 return GrXferProcessor::kNone_Opt; | 458 return GrXferProcessor::kNone_Opt; |
| 471 } | 459 } |
| 472 | 460 |
| 473 bool PorterDuffXferProcessor::hasSecondaryOutput() const { | 461 bool PorterDuffXferProcessor::hasSecondaryOutput() const { |
| 474 return kNone_SecondaryOutputType != fSecondaryOutputType; | 462 return kNone_SecondaryOutputType != fSecondaryOutputType; |
| 475 } | 463 } |
| 476 | 464 |
| 477 /////////////////////////////////////////////////////////////////////////////// | 465 /////////////////////////////////////////////////////////////////////////////// |
| 478 | 466 |
| 467 class PDLCDXferProcessor : public GrXferProcessor { |
| 468 public: |
| 469 static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, |
| 470 const GrProcOptInfo& colorPOI); |
| 471 |
| 472 ~PDLCDXferProcessor() override; |
| 473 |
| 474 const char* name() const override { return "Porter Duff LCD"; } |
| 475 |
| 476 GrGLXferProcessor* createGLInstance() const override; |
| 477 |
| 478 bool hasSecondaryOutput() const override { return false; } |
| 479 |
| 480 private: |
| 481 PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha); |
| 482 |
| 483 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, |
| 484 const GrProcOptInfo& coveragePO
I, |
| 485 bool doesStencilWrite, |
| 486 GrColor* overrideColor, |
| 487 const GrDrawTargetCaps& caps) o
verride; |
| 488 |
| 489 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c
onst override; |
| 490 |
| 491 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { |
| 492 blendInfo->fSrcBlend = kConstC_GrBlendCoeff; |
| 493 blendInfo->fDstBlend = kISC_GrBlendCoeff; |
| 494 blendInfo->fBlendConstant = fBlendConstant; |
| 495 } |
| 496 |
| 497 bool onIsEqual(const GrXferProcessor& xpBase) const override { |
| 498 const PDLCDXferProcessor& xp = xpBase.cast<PDLCDXferProcessor>(); |
| 499 if (fBlendConstant != xp.fBlendConstant || |
| 500 fAlpha != xp.fAlpha) { |
| 501 return false; |
| 502 } |
| 503 return true; |
| 504 } |
| 505 |
| 506 GrColor fBlendConstant; |
| 507 uint8_t fAlpha; |
| 508 |
| 509 typedef GrXferProcessor INHERITED; |
| 510 }; |
| 511 |
| 512 /////////////////////////////////////////////////////////////////////////////// |
| 513 |
| 514 class GLPDLCDXferProcessor : public GrGLXferProcessor { |
| 515 public: |
| 516 GLPDLCDXferProcessor(const GrProcessor&) {} |
| 517 |
| 518 virtual ~GLPDLCDXferProcessor() {} |
| 519 |
| 520 static void GenKey(const GrProcessor& processor, const GrGLSLCaps& caps, |
| 521 GrProcessorKeyBuilder* b) {} |
| 522 |
| 523 private: |
| 524 void onEmitCode(const EmitArgs& args) override { |
| 525 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 526 |
| 527 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInput
Color, |
| 528 args.fInputCoverage); |
| 529 } |
| 530 |
| 531 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri
de {}; |
| 532 |
| 533 typedef GrGLXferProcessor INHERITED; |
| 534 }; |
| 535 |
| 536 /////////////////////////////////////////////////////////////////////////////// |
| 537 |
| 538 PDLCDXferProcessor::PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha) |
| 539 : fBlendConstant(blendConstant) |
| 540 , fAlpha(alpha) { |
| 541 this->initClassID<PDLCDXferProcessor>(); |
| 542 } |
| 543 |
| 544 GrXferProcessor* PDLCDXferProcessor::Create(GrBlendCoeff srcBlend, GrBlendCoeff
dstBlend, |
| 545 const GrProcOptInfo& colorPOI) { |
| 546 if (kOne_GrBlendCoeff != srcBlend || kISA_GrBlendCoeff != dstBlend) { |
| 547 return NULL; |
| 548 } |
| 549 |
| 550 if (kRGBA_GrColorComponentFlags != colorPOI.validFlags()) { |
| 551 return NULL; |
| 552 } |
| 553 |
| 554 GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); |
| 555 uint8_t alpha = GrColorUnpackA(blendConstant); |
| 556 blendConstant |= (0xff << GrColor_SHIFT_A); |
| 557 |
| 558 return SkNEW_ARGS(PDLCDXferProcessor, (blendConstant, alpha)); |
| 559 } |
| 560 |
| 561 PDLCDXferProcessor::~PDLCDXferProcessor() { |
| 562 } |
| 563 |
| 564 void PDLCDXferProcessor::onGetGLProcessorKey(const GrGLSLCaps& caps, |
| 565 GrProcessorKeyBuilder* b) const { |
| 566 GLPorterDuffXferProcessor::GenKey(*this, caps, b); |
| 567 } |
| 568 |
| 569 GrGLXferProcessor* PDLCDXferProcessor::createGLInstance() const { |
| 570 return SkNEW_ARGS(GLPDLCDXferProcessor, (*this)); |
| 571 } |
| 572 |
| 573 GrXferProcessor::OptFlags |
| 574 PDLCDXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, |
| 575 const GrProcOptInfo& coveragePOI, |
| 576 bool doesStencilWrite, |
| 577 GrColor* overrideColor, |
| 578 const GrDrawTargetCaps& caps) { |
| 579 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha |
| 580 // value of the blend the constant. We should already have valid blend c
oeff's if we are at |
| 581 // a point where we have RGB coverage. We don't need any color stages si
nce the known color |
| 582 // output is already baked into the blendConstant. |
| 583 *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha); |
| 584 return GrXferProcessor::kOverrideColor_OptFlag; |
| 585 } |
| 586 |
| 587 /////////////////////////////////////////////////////////////////////////////// |
| 479 GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst) | 588 GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst) |
| 480 : fSrcCoeff(src), fDstCoeff(dst) { | 589 : fSrcCoeff(src), fDstCoeff(dst) { |
| 481 this->initClassID<GrPorterDuffXPFactory>(); | 590 this->initClassID<GrPorterDuffXPFactory>(); |
| 482 } | 591 } |
| 483 | 592 |
| 484 GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) { | 593 GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) { |
| 485 switch (mode) { | 594 switch (mode) { |
| 486 case SkXfermode::kClear_Mode: { | 595 case SkXfermode::kClear_Mode: { |
| 487 static GrPorterDuffXPFactory gClearPDXPF(kZero_GrBlendCoeff, kZero_G
rBlendCoeff); | 596 static GrPorterDuffXPFactory gClearPDXPF(kZero_GrBlendCoeff, kZero_G
rBlendCoeff); |
| 488 return SkRef(&gClearPDXPF); | 597 return SkRef(&gClearPDXPF); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 default: | 670 default: |
| 562 return NULL; | 671 return NULL; |
| 563 } | 672 } |
| 564 } | 673 } |
| 565 | 674 |
| 566 GrXferProcessor* | 675 GrXferProcessor* |
| 567 GrPorterDuffXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, | 676 GrPorterDuffXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, |
| 568 const GrProcOptInfo& colorPOI, | 677 const GrProcOptInfo& colorPOI, |
| 569 const GrProcOptInfo& covPOI, | 678 const GrProcOptInfo& covPOI, |
| 570 const GrDeviceCoordTexture* dstCopy
) const { | 679 const GrDeviceCoordTexture* dstCopy
) const { |
| 571 if (!covPOI.isFourChannelOutput()) { | 680 if (covPOI.isFourChannelOutput()) { |
| 681 return PDLCDXferProcessor::Create(fSrcCoeff, fDstCoeff, colorPOI); |
| 682 } else { |
| 572 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, | 683 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, |
| 573 this->willReadDstColor(caps, colo
rPOI, covPOI)); | 684 this->willReadDstColor(caps, colo
rPOI, covPOI)); |
| 574 } else { | |
| 575 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags()))
{ | |
| 576 SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); | |
| 577 GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); | |
| 578 return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_Gr
BlendCoeff, | |
| 579 blendConstant, dstCopy, | |
| 580 this->willReadDstColor(caps,
colorPOI, covPOI)); | |
| 581 } else { | |
| 582 return NULL; | |
| 583 } | |
| 584 } | 685 } |
| 585 } | 686 } |
| 586 | 687 |
| 587 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, | 688 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, |
| 588 uint32_t knownColorFlags) const
{ | 689 uint32_t knownColorFlags) const
{ |
| 589 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff && | 690 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff && |
| 590 kRGBA_GrColorComponentFlags == knownColorFlags) { | 691 kRGBA_GrColorComponentFlags == knownColorFlags) { |
| 591 return true; | 692 return true; |
| 592 } | 693 } |
| 593 return false; | 694 return false; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); | 799 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); |
| 699 | 800 |
| 700 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, | 801 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, |
| 701 GrContext*, | 802 GrContext*, |
| 702 const GrDrawTargetCaps&, | 803 const GrDrawTargetCaps&, |
| 703 GrTexture*[]) { | 804 GrTexture*[]) { |
| 704 SkXfermode::Mode mode = SkXfermode::Mode(random->nextULessThan(SkXfermode::k
LastCoeffMode)); | 805 SkXfermode::Mode mode = SkXfermode::Mode(random->nextULessThan(SkXfermode::k
LastCoeffMode)); |
| 705 return GrPorterDuffXPFactory::Create(mode); | 806 return GrPorterDuffXPFactory::Create(mode); |
| 706 } | 807 } |
| 707 | 808 |
| OLD | NEW |