diff options
author | Brian Osman <brianosman@google.com> | 2017-10-17 17:15:52 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-10-18 13:27:46 +0000 |
commit | c4f93cab667b022bbaa196bddcbca23592ad2e6c (patch) | |
tree | f9d18a953013b5249b8dc36c76d24ddc76dbd9dd /src/gpu/GrColorSpaceXform.cpp | |
parent | 43938b8533dbee75816726b54737e410097428ce (diff) |
Add GrColorSpaceXformEffect
This is an FP that just applies a GrColorSpaceXform. I have a long string
of follow-up changes that use this, which greatly simplifies many other
FPs, and ultimately eliminates the need for color space xforms to be a
first-class type in SkSL.
Bug: skia:
Change-Id: I070d8bab81c9a620a2173c83b0013c63ad53bc8e
Reviewed-on: https://skia-review.googlesource.com/60726
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/gpu/GrColorSpaceXform.cpp')
-rw-r--r-- | src/gpu/GrColorSpaceXform.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/gpu/GrColorSpaceXform.cpp b/src/gpu/GrColorSpaceXform.cpp index 58f160cd18..0e98a87f6c 100644 --- a/src/gpu/GrColorSpaceXform.cpp +++ b/src/gpu/GrColorSpaceXform.cpp @@ -10,6 +10,9 @@ #include "SkColorSpace_Base.h" #include "SkMatrix44.h" #include "SkSpinlock.h" +#include "glsl/GrGLSLColorSpaceXformHelper.h" +#include "glsl/GrGLSLFragmentProcessor.h" +#include "glsl/GrGLSLFragmentShaderBuilder.h" class GrColorSpaceXformCache { public: @@ -127,3 +130,95 @@ GrColor4f GrColorSpaceXform::apply(const GrColor4f& srcColor) { } return result; } + +////////////////////////////////////////////////////////////////////////////// + +class GrGLColorSpaceXformEffect : public GrGLSLFragmentProcessor { +public: + void emitCode(EmitArgs& args) override { + const GrColorSpaceXformEffect& csxe = args.fFp.cast<GrColorSpaceXformEffect>(); + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; + GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; + + fColorSpaceHelper.emitCode(uniformHandler, csxe.colorXform()); + + SkString childColor("src_color"); + this->emitChild(0, &childColor, args); + + SkString xformedColor; + fragBuilder->appendColorGamutXform(&xformedColor, childColor.c_str(), &fColorSpaceHelper); + fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputColor, xformedColor.c_str(), + args.fInputColor); + } + +private: + void onSetData(const GrGLSLProgramDataManager& pdman, + const GrFragmentProcessor& processor) override { + const GrColorSpaceXformEffect& csxe = processor.cast<GrColorSpaceXformEffect>(); + if (fColorSpaceHelper.isValid()) { + fColorSpaceHelper.setData(pdman, csxe.colorXform()); + } + } + + GrGLSLColorSpaceXformHelper fColorSpaceHelper; + + typedef GrGLSLFragmentProcessor INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +GrColorSpaceXformEffect::GrColorSpaceXformEffect(std::unique_ptr<GrFragmentProcessor> child, + sk_sp<GrColorSpaceXform> colorXform) + : INHERITED(kGrColorSpaceXformEffect_ClassID, OptFlags(child.get())) + , fColorXform(std::move(colorXform)) { + this->registerChildProcessor(std::move(child)); +} + +std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::clone() const { + return std::unique_ptr<GrFragmentProcessor>( + new GrColorSpaceXformEffect(this->childProcessor(0).clone(), fColorXform)); +} + +bool GrColorSpaceXformEffect::onIsEqual(const GrFragmentProcessor& s) const { + const GrColorSpaceXformEffect& other = s.cast<GrColorSpaceXformEffect>(); + return GrColorSpaceXform::Equals(fColorXform.get(), other.fColorXform.get()); +} + +void GrColorSpaceXformEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, + GrProcessorKeyBuilder* b) const { + b->add32(GrColorSpaceXform::XformKey(fColorXform.get())); +} + +GrGLSLFragmentProcessor* GrColorSpaceXformEffect::onCreateGLSLInstance() const { + return new GrGLColorSpaceXformEffect(); +} + +GrFragmentProcessor::OptimizationFlags GrColorSpaceXformEffect::OptFlags( + const GrFragmentProcessor* child) { + // TODO: Implement constant output for constant input + OptimizationFlags flags = kNone_OptimizationFlags; + if (child->compatibleWithCoverageAsAlpha()) { + flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag; + } + if (child->preservesOpaqueInput()) { + flags |= kPreservesOpaqueInput_OptimizationFlag; + } + return flags; +} + +std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::Make( + std::unique_ptr<GrFragmentProcessor> child, + const SkColorSpace* src, + const SkColorSpace* dst) { + if (!child) { + return nullptr; + } + + auto colorXform = GrColorSpaceXform::Make(src, dst); + if (colorXform) { + return std::unique_ptr<GrFragmentProcessor>( + new GrColorSpaceXformEffect(std::move(child), std::move(colorXform))); + } else { + return child; + } +} |