aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrColorSpaceXform.cpp
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-10-17 17:15:52 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-18 13:27:46 +0000
commitc4f93cab667b022bbaa196bddcbca23592ad2e6c (patch)
treef9d18a953013b5249b8dc36c76d24ddc76dbd9dd /src/gpu/GrColorSpaceXform.cpp
parent43938b8533dbee75816726b54737e410097428ce (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.cpp95
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;
+ }
+}