• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/gpu/GrColorSpaceXform.h"
9 
10 #include "include/core/SkColorSpace.h"
11 #include "src/core/SkColorSpacePriv.h"
12 #include "src/gpu/GrColorInfo.h"
13 #include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
14 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
15 
Make(SkColorSpace * src,SkAlphaType srcAT,SkColorSpace * dst,SkAlphaType dstAT)16 sk_sp<GrColorSpaceXform> GrColorSpaceXform::Make(SkColorSpace* src, SkAlphaType srcAT,
17                                                  SkColorSpace* dst, SkAlphaType dstAT) {
18     SkColorSpaceXformSteps steps(src, srcAT, dst, dstAT);
19     return steps.flags.mask() == 0 ? nullptr  /* Noop transform */
20                                    : sk_make_sp<GrColorSpaceXform>(steps);
21 }
22 
Make(const GrColorInfo & srcInfo,const GrColorInfo & dstInfo)23 sk_sp<GrColorSpaceXform> GrColorSpaceXform::Make(const GrColorInfo& srcInfo,
24                                                  const GrColorInfo& dstInfo) {
25     return Make(srcInfo.colorSpace(), srcInfo.alphaType(),
26                 dstInfo.colorSpace(), dstInfo.alphaType());
27 }
28 
Equals(const GrColorSpaceXform * a,const GrColorSpaceXform * b)29 bool GrColorSpaceXform::Equals(const GrColorSpaceXform* a, const GrColorSpaceXform* b) {
30     if (a == b) {
31         return true;
32     }
33 
34     if (!a || !b || a->fSteps.flags.mask() != b->fSteps.flags.mask()) {
35         return false;
36     }
37 
38     if (a->fSteps.flags.linearize &&
39         0 != memcmp(&a->fSteps.srcTF, &b->fSteps.srcTF, sizeof(a->fSteps.srcTF))) {
40         return false;
41     }
42 
43     if (a->fSteps.flags.gamut_transform &&
44         0 != memcmp(&a->fSteps.src_to_dst_matrix, &b->fSteps.src_to_dst_matrix,
45                     sizeof(a->fSteps.src_to_dst_matrix))) {
46         return false;
47     }
48 
49     if (a->fSteps.flags.encode &&
50         0 != memcmp(&a->fSteps.dstTFInv, &b->fSteps.dstTFInv, sizeof(a->fSteps.dstTFInv))) {
51         return false;
52     }
53 
54     return true;
55 }
56 
apply(const SkColor4f & srcColor)57 SkColor4f GrColorSpaceXform::apply(const SkColor4f& srcColor) {
58     SkColor4f result = srcColor;
59     fSteps.apply(result.vec());
60     return result;
61 }
62 
63 //////////////////////////////////////////////////////////////////////////////
64 
GrColorSpaceXformEffect(std::unique_ptr<GrFragmentProcessor> child,sk_sp<GrColorSpaceXform> colorXform)65 GrColorSpaceXformEffect::GrColorSpaceXformEffect(std::unique_ptr<GrFragmentProcessor> child,
66                                                  sk_sp<GrColorSpaceXform> colorXform)
67         : INHERITED(kGrColorSpaceXformEffect_ClassID, OptFlags(child.get()))
68         , fColorXform(std::move(colorXform)) {
69     this->registerChild(std::move(child));
70 }
71 
GrColorSpaceXformEffect(const GrColorSpaceXformEffect & that)72 GrColorSpaceXformEffect::GrColorSpaceXformEffect(const GrColorSpaceXformEffect& that)
73         : INHERITED(that)
74         , fColorXform(that.fColorXform) {}
75 
clone() const76 std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::clone() const {
77     return std::unique_ptr<GrFragmentProcessor>(new GrColorSpaceXformEffect(*this));
78 }
79 
onIsEqual(const GrFragmentProcessor & s) const80 bool GrColorSpaceXformEffect::onIsEqual(const GrFragmentProcessor& s) const {
81     const GrColorSpaceXformEffect& other = s.cast<GrColorSpaceXformEffect>();
82     return GrColorSpaceXform::Equals(fColorXform.get(), other.fColorXform.get());
83 }
84 
onAddToKey(const GrShaderCaps &,GrProcessorKeyBuilder * b) const85 void GrColorSpaceXformEffect::onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const {
86     b->add32(GrColorSpaceXform::XformKey(fColorXform.get()));
87 }
88 
89 std::unique_ptr<GrFragmentProcessor::ProgramImpl>
onMakeProgramImpl() const90 GrColorSpaceXformEffect::onMakeProgramImpl() const {
91     class Impl : public ProgramImpl {
92     public:
93         void emitCode(EmitArgs& args) override {
94             const GrColorSpaceXformEffect& proc = args.fFp.cast<GrColorSpaceXformEffect>();
95             GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
96             GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
97 
98             fColorSpaceHelper.emitCode(uniformHandler, proc.colorXform());
99 
100             SkString childColor = this->invokeChild(0, args);
101 
102             SkString xformedColor;
103             fragBuilder->appendColorGamutXform(
104                     &xformedColor, childColor.c_str(), &fColorSpaceHelper);
105             fragBuilder->codeAppendf("return %s;", xformedColor.c_str());
106         }
107 
108     private:
109         void onSetData(const GrGLSLProgramDataManager& pdman,
110                        const GrFragmentProcessor& fp) override {
111             const GrColorSpaceXformEffect& proc = fp.cast<GrColorSpaceXformEffect>();
112             fColorSpaceHelper.setData(pdman, proc.colorXform());
113         }
114 
115         GrGLSLColorSpaceXformHelper fColorSpaceHelper;
116     };
117 
118     return std::make_unique<Impl>();
119 }
120 
OptFlags(const GrFragmentProcessor * child)121 GrFragmentProcessor::OptimizationFlags GrColorSpaceXformEffect::OptFlags(
122         const GrFragmentProcessor* child) {
123     return ProcessorOptimizationFlags(child) & (kCompatibleWithCoverageAsAlpha_OptimizationFlag |
124                                                 kPreservesOpaqueInput_OptimizationFlag |
125                                                 kConstantOutputForConstantInput_OptimizationFlag);
126 }
127 
constantOutputForConstantInput(const SkPMColor4f & input) const128 SkPMColor4f GrColorSpaceXformEffect::constantOutputForConstantInput(
129         const SkPMColor4f& input) const {
130     const auto c0 = ConstantOutputForConstantInput(this->childProcessor(0), input);
131     return this->fColorXform->apply(c0.unpremul()).premul();
132 }
133 
Make(std::unique_ptr<GrFragmentProcessor> child,SkColorSpace * src,SkAlphaType srcAT,SkColorSpace * dst,SkAlphaType dstAT)134 std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::Make(
135         std::unique_ptr<GrFragmentProcessor> child,
136         SkColorSpace* src, SkAlphaType srcAT,
137         SkColorSpace* dst, SkAlphaType dstAT) {
138     return Make(std::move(child), GrColorSpaceXform::Make(src, srcAT, dst, dstAT));
139 }
140 
Make(std::unique_ptr<GrFragmentProcessor> child,const GrColorInfo & srcInfo,const GrColorInfo & dstInfo)141 std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::Make(
142         std::unique_ptr<GrFragmentProcessor> child,
143         const GrColorInfo& srcInfo,
144         const GrColorInfo& dstInfo) {
145     return Make(std::move(child), GrColorSpaceXform::Make(srcInfo, dstInfo));
146 }
147 
Make(std::unique_ptr<GrFragmentProcessor> child,sk_sp<GrColorSpaceXform> colorXform)148 std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::Make(
149         std::unique_ptr<GrFragmentProcessor> child,
150         sk_sp<GrColorSpaceXform> colorXform) {
151     if (!colorXform) {
152         return child;
153     }
154 
155     return std::unique_ptr<GrFragmentProcessor>(new GrColorSpaceXformEffect(std::move(child),
156                                                                             std::move(colorXform)));
157 }
158