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()) { |
bsalomon
2015/05/11 20:58:30
reverse this? if (isfour) { } else { }
| |
572 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, | 681 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, |
573 this->willReadDstColor(caps, colo rPOI, covPOI)); | 682 this->willReadDstColor(caps, colo rPOI, covPOI)); |
574 } else { | 683 } else { |
575 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) { | 684 return PDLCDXferProcessor::Create(fSrcCoeff, fDstCoeff, colorPOI); |
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 |