Chromium Code Reviews| Index: src/gpu/GrFragmentProcessor.cpp |
| diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp |
| index fcc9c74fa4ac5778870374f71ff6fbbbb5b1d257..0e75909faceb187d1ab232ee241db0e6ed9c2452 100644 |
| --- a/src/gpu/GrFragmentProcessor.cpp |
| +++ b/src/gpu/GrFragmentProcessor.cpp |
| @@ -8,6 +8,7 @@ |
| #include "GrFragmentProcessor.h" |
| #include "GrCoordTransform.h" |
| +#include "gl/builders/GrGLProgramBuilder.h" |
|
egdaniel
2015/09/25 20:01:55
this should go below the gl/*.cpp
bsalomon
2015/09/25 20:45:07
ok
|
| #include "gl/GrGLFragmentProcessor.h" |
| #include "effects/GrXfermodeFragmentProcessor.h" |
| @@ -122,8 +123,168 @@ bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) con |
| return true; |
| } |
| -const GrFragmentProcessor* GrFragmentProcessor::MulOuputByInputAlpha( |
| +const GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputAlpha( |
| const GrFragmentProcessor* fp) { |
| + if (!fp) { |
| + return nullptr; |
| + } |
| return GrXfermodeFragmentProcessor::CreateFromDstProcessor(fp, SkXfermode::kDstIn_Mode); |
| } |
| +const GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputUnpremulColor( |
| + const GrFragmentProcessor* fp) { |
| + |
| + class PremulFragmentProcessor : public GrFragmentProcessor { |
| + public: |
| + PremulFragmentProcessor(const GrFragmentProcessor* processor) { |
| + this->initClassID<PremulFragmentProcessor>(); |
| + this->registerChildProcessor(processor); |
| + } |
| + |
| + const char* name() const override { return "Premultiply"; } |
| + |
| + private: |
| + GrGLFragmentProcessor* onCreateGLInstance() const override { |
| + class GLFP : public GrGLFragmentProcessor { |
| + public: |
| + GLFP() {} |
| + |
| + void emitCode(EmitArgs& args) override { |
| + GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
| + this->emitChild(0, nullptr, args); |
| + fsBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor, |
| + args.fInputColor); |
| + fsBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor); |
| + } |
| + |
| + private: |
| + typedef GrGLFragmentProcessor INHERITED; |
| + }; |
| + return new GLFP; |
| + } |
| + |
| + void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override {} |
| + |
| + bool onIsEqual(const GrFragmentProcessor&) const override { return true; } |
| + |
| + void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| + // TODO: Add a helper to GrInvariantOutput that handles multiplying by color with flags? |
| + if (!(inout->validFlags() & kA_GrColorComponentFlag)) { |
| + inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); |
| + return; |
| + } |
| + |
| + GrInvariantOutput childOutput(GrColor_WHITE, kRGBA_GrColorComponentFlags, false); |
| + this->childProcessor(0).computeInvariantOutput(&childOutput); |
| + |
| + if (0 == GrColorUnpackA(inout->color()) || 0 == GrColorUnpackA(childOutput.color())) { |
| + inout->mulByKnownFourComponents(0x0); |
| + return; |
| + } |
| + GrColorComponentFlags commonFlags = childOutput.validFlags() & inout->validFlags(); |
| + GrColor c0 = GrPremulColor(inout->color()); |
| + GrColor c1 = childOutput.color(); |
| + GrColor color = 0x0; |
| + if (commonFlags & kR_GrColorComponentFlag) { |
| + color |= SkMulDiv255Round(GrColorUnpackR(c0), GrColorUnpackR(c1)) << |
| + GrColor_SHIFT_R; |
| + } |
| + if (commonFlags & kG_GrColorComponentFlag) { |
| + color |= SkMulDiv255Round(GrColorUnpackG(c0), GrColorUnpackG(c1)) << |
| + GrColor_SHIFT_G; |
| + } |
| + if (commonFlags & kB_GrColorComponentFlag) { |
| + color |= SkMulDiv255Round(GrColorUnpackB(c0), GrColorUnpackB(c1)) << |
| + GrColor_SHIFT_B; |
| + } |
| + inout->setToOther(commonFlags, color, GrInvariantOutput::kWill_ReadInput); |
| + } |
| + |
| + typedef GrFragmentProcessor INHERITED; |
| + }; |
| + if (!fp) { |
| + return nullptr; |
| + } |
| + return new PremulFragmentProcessor(fp); |
| +} |
| + |
| +////////////////////////////////////////////////////////////////////////////// |
| + |
| +const GrFragmentProcessor* GrFragmentProcessor::ReplaceInput(const GrFragmentProcessor* fp, |
| + GrColor color) { |
| + class ReplaceInputFragmentProcessor : public GrFragmentProcessor { |
| + public: |
| + ReplaceInputFragmentProcessor(const GrFragmentProcessor* child, GrColor color) |
| + : fColor(color) { |
| + this->initClassID<ReplaceInputFragmentProcessor>(); |
| + this->registerChildProcessor(child); |
| + } |
| + |
| + const char* name() const override { return "Replace Color"; } |
| + |
| + GrGLFragmentProcessor* onCreateGLInstance() const override { |
| + class GLFP : public GrGLFragmentProcessor { |
| + public: |
| + GLFP() : fHaveSetColor(false) {} |
| + void emitCode(EmitArgs& args) override { |
| + const char* colorName; |
| + fColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| + kVec4f_GrSLType, kDefault_GrSLPrecision, |
| + "Color", &colorName); |
| + this->emitChild(0, colorName, args); |
| + } |
| + |
| + private: |
| + void onSetData(const GrGLProgramDataManager& pdman, |
| + const GrProcessor& fp) override { |
| + GrColor color = fp.cast<ReplaceInputFragmentProcessor>().fColor; |
| + if (!fHaveSetColor || color != fPreviousColor) { |
| + static const GrGLfloat scale = 1.f / 255.f; |
| + GrGLfloat floatColor[4] = { |
| + GrColorUnpackR(color) * scale, |
| + GrColorUnpackG(color) * scale, |
| + GrColorUnpackB(color) * scale, |
| + GrColorUnpackA(color) * scale, |
| + }; |
| + pdman.set4fv(fColorUni, 1, floatColor); |
| + fPreviousColor = color; |
| + fHaveSetColor = true; |
| + } |
| + } |
| + |
| + GrGLProgramDataManager::UniformHandle fColorUni; |
| + bool fHaveSetColor; |
| + GrColor fPreviousColor; |
| + |
| + typedef GrGLFragmentProcessor INHERITED; |
| + }; |
| + |
| + return new GLFP; |
| + } |
| + |
| + private: |
| + void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {} |
| + |
| + bool onIsEqual(const GrFragmentProcessor& that) const override { |
| + return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor; |
| + } |
| + |
| + void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| + inout->setToOther(kRGBA_GrColorComponentFlags, fColor, |
| + GrInvariantOutput::kWillNot_ReadInput); |
| + this->childProcessor(0).computeInvariantOutput(inout); |
| + } |
| + |
| + GrColor fColor; |
| + |
| + typedef GrFragmentProcessor INHERITED; |
| + }; |
| + |
| + GrInvariantOutput childOut(0x0, kNone_GrColorComponentFlags, false); |
| + fp->computeInvariantOutput(&childOut); |
| + if (childOut.willUseInputColor()) { |
| + return new ReplaceInputFragmentProcessor(fp, color); |
| + } else { |
| + return SkRef(fp); |
| + } |
| +} |