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: ("); |