Chromium Code Reviews| Index: src/core/SkComposeShader.cpp |
| diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp |
| index c16d7ffc578f352f948d432934c68c41851c6623..f038d5ecbe77285aa21ddc19cf28aeffa63af8fd 100644 |
| --- a/src/core/SkComposeShader.cpp |
| +++ b/src/core/SkComposeShader.cpp |
| @@ -194,6 +194,189 @@ void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re |
| } |
| } |
| +#if SK_SUPPORT_GPU |
| + |
| +#include "SkGr.h" |
| +#include "GrProcessor.h" |
| +#include "gl/GrGLBlend.h" |
| +#include "gl/builders/GrGLProgramBuilder.h" |
| + |
| +///////////////////////////////////////////////////////////////////// |
| + |
| +class GrComposeEffect : public GrFragmentProcessor { |
| +public: |
| + |
| + static GrFragmentProcessor* Create(GrFragmentProcessor* fpA, GrFragmentProcessor* fpB, |
| + SkXfermode::Mode mode) { |
| + return SkNEW_ARGS(GrComposeEffect, (fpA, fpB, mode)); |
| + } |
| + const char* name() const override {return fName.c_str(); } |
| + void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; |
| + |
| + SkXfermode::Mode getMode() const { return fMode; } |
| + |
| +protected: |
| + bool onIsEqual(const GrFragmentProcessor&) const override; |
| + void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
| + |
| +private: |
| + GrComposeEffect(GrFragmentProcessor* fpA, GrFragmentProcessor* fpB, SkXfermode::Mode mode) |
| + : fMode(mode) { |
| + this->initClassID<GrComposeEffect>(); |
| + this->registerChildProcessor(fpA); |
| + this->registerChildProcessor(fpB); |
| + fName.printf("Compose Shader <%s, %s> (Mode: %s)", fpA->name(), fpB->name(), |
| + SkXfermode::ModeName(fMode)); |
| + } |
| + |
| + GrGLFragmentProcessor* onCreateGLInstance() const override; |
| + |
| + SkString fName; |
| + SkXfermode::Mode fMode; |
| + |
| + //GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| + typedef GrFragmentProcessor INHERITED; |
| +}; |
| + |
| +///////////////////////////////////////////////////////////////////// |
| + |
| +class GrGLComposeEffect : public GrGLFragmentProcessor { |
| +public: |
| + GrGLComposeEffect(const GrProcessor& processor) { |
| + const GrComposeEffect& cs = processor.cast<GrComposeEffect>(); |
| + fMode = cs.getMode(); |
| + } |
| + |
| + void emitCode(EmitArgs&) override; |
| + |
| +private: |
| + SkXfermode::Mode fMode; |
| + |
| + typedef GrGLFragmentProcessor INHERITED; |
| +}; |
| + |
| +///////////////////////////////////////////////////////////////////// |
| + |
| +//GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrComposeShader); |
|
tomhudson
2015/08/18 14:58:38
Remove commented-out code before committing.
wangyix
2015/08/19 20:05:47
Done.
|
| + |
| +//GrFragmentProcessor* GrComposeShader::TestCreate(GrProcessorTestData* d) { |
| + //.... |
| +//} |
| + |
| +bool GrComposeEffect::onIsEqual(const GrFragmentProcessor& other) const { |
| + // GrFragmentProcessor::isEqual() currently does not automatically compare child procs |
| + const GrComposeEffect& cs = other.cast<GrComposeEffect>(); |
| + return this->childProcessor(0).isEqual(cs.childProcessor(0), false) |
| + && this->childProcessor(1).isEqual(cs.childProcessor(1), false) |
| + && fMode == cs.fMode; |
| +} |
| + |
| +void GrComposeEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { |
| + inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); |
| +} |
| + |
| +void GrComposeEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const{ |
|
tomhudson
2015/08/18 14:58:38
nit: space
wangyix
2015/08/19 20:05:47
Done.
|
| + b->add32(fMode); |
| +} |
| + |
| +GrGLFragmentProcessor* GrComposeEffect::onCreateGLInstance() const{ |
| + return SkNEW_ARGS(GrGLComposeEffect, (*this)); |
| +} |
| + |
| +///////////////////////////////////////////////////////////////////// |
| + |
| +void GrGLComposeEffect::emitCode(EmitArgs& args) { |
| + |
| + GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
| + |
| + SkString mangledOutputColorA; |
| + { |
| + const GrFragmentProcessor* childFp; |
| + TransformedCoordsArray childCoords; |
| + TextureSamplerArray childSamplers; |
| + |
| + GrGLFragmentBuilder::AutoFragmentChildProcAdvance adv(0, |
| + args.fBuilder, |
| + args.fFp, |
| + args.fOutputColor, |
| + args.fCoords, |
| + args.fSamplers, |
| + &childFp, |
| + &mangledOutputColorA, |
| + &childCoords, |
| + &childSamplers); |
| + |
| + EmitArgs argsA(args.fBuilder, *childFp, mangledOutputColorA.c_str(), args.fInputColor, |
| + childCoords, childSamplers); |
| + this->childProcessor(0)->emitCode(argsA); |
| + } |
| + SkString mangledOutputColorB; |
| + { |
| + const GrFragmentProcessor* childFp; |
| + TransformedCoordsArray childCoords; |
| + TextureSamplerArray childSamplers; |
| + |
| + GrGLFragmentBuilder::AutoFragmentChildProcAdvance adv(1, |
| + args.fBuilder, |
| + args.fFp, |
| + args.fOutputColor, |
| + args.fCoords, |
| + args.fSamplers, |
| + &childFp, |
| + &mangledOutputColorB, |
| + &childCoords, |
| + &childSamplers); |
| + |
| + EmitArgs argsB(args.fBuilder, *childFp, mangledOutputColorB.c_str(), args.fInputColor, |
| + childCoords, childSamplers); |
| + this->childProcessor(1)->emitCode(argsB); |
| + } |
| + |
| + // emit blend code |
| + fsBuilder->codeAppend("\t{\n"); |
| + fsBuilder->codeAppendf("\t\t// Compose Xfer Mode: %s\n", SkXfermode::ModeName(fMode)); |
| + GrGLBlend::AppendPorterDuffBlend(fsBuilder, mangledOutputColorB.c_str(), mangledOutputColorA.c_str(), |
|
tomhudson
2015/08/18 14:58:38
nit: line length?
wangyix
2015/08/19 20:05:47
Done.
|
| + args.fOutputColor, fMode); |
| + fsBuilder->codeAppend("\t}\n"); |
| +} |
| + |
| +///////////////////////////////////////////////////////////////////// |
| + |
| +bool SkComposeShader::asFragmentProcessor(GrContext* context, const SkPaint& paint, |
| + const SkMatrix& viewM, const SkMatrix* localMatrix, |
| + GrColor* paintColor, |
| + GrProcessorDataManager* procDataManager, |
| + GrFragmentProcessor** fp) const { |
| + GrFragmentProcessor* fpA; |
| + if (!fShaderA->asFragmentProcessor(context, paint, viewM, localMatrix, paintColor, |
| + procDataManager, &fpA)) |
| + return false; |
| + GrFragmentProcessor* fpB; |
| + if (!fShaderB->asFragmentProcessor(context, paint, viewM, localMatrix, paintColor, |
| + procDataManager, &fpB)) |
| + return false; |
| + SkXfermode::Mode mode; |
| + if (!fMode->asMode(&mode)) |
| + return false; |
| + |
| + *fp = GrComposeEffect::Create(fpA, fpB, mode); |
| + fpA->unref(); |
| + fpB->unref(); |
| + |
| + return true; |
| +} |
| + |
| + |
| + |
| +#else |
| +bool SkComposeShader::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix&, |
| + const SkMatrix*, GrColor*, GrProcessorDataManager*, |
| + GrFragmentProcessor**) const { |
| + SkDEBUGFAIL("Should not call in GPU-less build"); |
| + return false; |
| +} |
| +#endif |
| + |
| #ifndef SK_IGNORE_TO_STRING |
| void SkComposeShader::toString(SkString* str) const { |
| str->append("SkComposeShader: ("); |