diff options
author | egdaniel <egdaniel@google.com> | 2015-05-12 06:11:35 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-12 06:11:35 -0700 |
commit | 0d5fd110e0b7ce9b892833d874145a79ca67da8d (patch) | |
tree | 695df6cd02ef4cdecc08528fbb36500449260db4 /src | |
parent | d2ffd36eb62e99abe2920369d1e040954cc2044f (diff) |
Make Porter Duff LCD XP its own XferProcessor
BUG=skia:
Review URL: https://codereview.chromium.org/1134093003
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/effects/GrPorterDuffXferProcessor.cpp | 153 |
1 files changed, 127 insertions, 26 deletions
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index 543a515e90..c1db0ca091 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -306,21 +306,9 @@ PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, bool doesStencilWrite, GrColor* overrideColor, const GrDrawTargetCaps& caps) { - GrXferProcessor::OptFlags optFlags; - // Optimizations when doing RGB Coverage - if (coveragePOI.isFourChannelOutput()) { - // We want to force our primary output to be alpha * Coverage, where alpha is the alpha - // value of the blend the constant. We should already have valid blend coeff's if we are at - // a point where we have RGB coverage. We don't need any color stages since the known color - // output is already baked into the blendConstant. - uint8_t alpha = GrColorUnpackA(fBlendConstant); - *overrideColor = GrColorPackRGBA(alpha, alpha, alpha, alpha); - optFlags = GrXferProcessor::kOverrideColor_OptFlag; - } else { - optFlags = this->internalGetOptimizations(colorPOI, - coveragePOI, - doesStencilWrite); - } + GrXferProcessor::OptFlags optFlags = this->internalGetOptimizations(colorPOI, + coveragePOI, + doesStencilWrite); this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite()); return optFlags; } @@ -476,6 +464,127 @@ bool PorterDuffXferProcessor::hasSecondaryOutput() const { /////////////////////////////////////////////////////////////////////////////// +class PDLCDXferProcessor : public GrXferProcessor { +public: + static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, + const GrProcOptInfo& colorPOI); + + ~PDLCDXferProcessor() override; + + const char* name() const override { return "Porter Duff LCD"; } + + GrGLXferProcessor* createGLInstance() const override; + + bool hasSecondaryOutput() const override { return false; } + +private: + PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha); + + GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) override; + + void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; + + void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { + blendInfo->fSrcBlend = kConstC_GrBlendCoeff; + blendInfo->fDstBlend = kISC_GrBlendCoeff; + blendInfo->fBlendConstant = fBlendConstant; + } + + bool onIsEqual(const GrXferProcessor& xpBase) const override { + const PDLCDXferProcessor& xp = xpBase.cast<PDLCDXferProcessor>(); + if (fBlendConstant != xp.fBlendConstant || + fAlpha != xp.fAlpha) { + return false; + } + return true; + } + + GrColor fBlendConstant; + uint8_t fAlpha; + + typedef GrXferProcessor INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +class GLPDLCDXferProcessor : public GrGLXferProcessor { +public: + GLPDLCDXferProcessor(const GrProcessor&) {} + + virtual ~GLPDLCDXferProcessor() {} + + static void GenKey(const GrProcessor& processor, const GrGLSLCaps& caps, + GrProcessorKeyBuilder* b) {} + +private: + void onEmitCode(const EmitArgs& args) override { + GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); + + fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor, + args.fInputCoverage); + } + + void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) override {}; + + typedef GrGLXferProcessor INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +PDLCDXferProcessor::PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha) + : fBlendConstant(blendConstant) + , fAlpha(alpha) { + this->initClassID<PDLCDXferProcessor>(); +} + +GrXferProcessor* PDLCDXferProcessor::Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, + const GrProcOptInfo& colorPOI) { + if (kOne_GrBlendCoeff != srcBlend || kISA_GrBlendCoeff != dstBlend) { + return NULL; + } + + if (kRGBA_GrColorComponentFlags != colorPOI.validFlags()) { + return NULL; + } + + GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); + uint8_t alpha = GrColorUnpackA(blendConstant); + blendConstant |= (0xff << GrColor_SHIFT_A); + + return SkNEW_ARGS(PDLCDXferProcessor, (blendConstant, alpha)); +} + +PDLCDXferProcessor::~PDLCDXferProcessor() { +} + +void PDLCDXferProcessor::onGetGLProcessorKey(const GrGLSLCaps& caps, + GrProcessorKeyBuilder* b) const { + GLPorterDuffXferProcessor::GenKey(*this, caps, b); +} + +GrGLXferProcessor* PDLCDXferProcessor::createGLInstance() const { + return SkNEW_ARGS(GLPDLCDXferProcessor, (*this)); +} + +GrXferProcessor::OptFlags +PDLCDXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) { + // We want to force our primary output to be alpha * Coverage, where alpha is the alpha + // value of the blend the constant. We should already have valid blend coeff's if we are at + // a point where we have RGB coverage. We don't need any color stages since the known color + // output is already baked into the blendConstant. + *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha); + return GrXferProcessor::kOverrideColor_OptFlag; +} + +/////////////////////////////////////////////////////////////////////////////// GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst) : fSrcCoeff(src), fDstCoeff(dst) { this->initClassID<GrPorterDuffXPFactory>(); @@ -568,19 +677,11 @@ GrPorterDuffXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, const GrDeviceCoordTexture* dstCopy) const { - if (!covPOI.isFourChannelOutput()) { + if (covPOI.isFourChannelOutput()) { + return PDLCDXferProcessor::Create(fSrcCoeff, fDstCoeff, colorPOI); + } else { return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, this->willReadDstColor(caps, colorPOI, covPOI)); - } else { - if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) { - SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); - GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); - return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_GrBlendCoeff, - blendConstant, dstCopy, - this->willReadDstColor(caps, colorPOI, covPOI)); - } else { - return NULL; - } } } |