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 #ifndef GrColorSpaceXform_DEFINED
9 #define GrColorSpaceXform_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "src/core/SkColorSpacePriv.h"
13 #include "src/core/SkColorSpaceXformSteps.h"
14 #include "src/gpu/GrFragmentProcessor.h"
15 
16 class GrColorInfo;
17 class SkColorSpace;
18 
19  /**
20   * Represents a color space transformation
21   */
22 class GrColorSpaceXform : public SkRefCnt {
23 public:
GrColorSpaceXform(const SkColorSpaceXformSteps & steps)24     GrColorSpaceXform(const SkColorSpaceXformSteps& steps) : fSteps(steps) {}
25 
26     static sk_sp<GrColorSpaceXform> Make(SkColorSpace* src, SkAlphaType srcAT,
27                                          SkColorSpace* dst, SkAlphaType dstAT);
28 
29     static sk_sp<GrColorSpaceXform> Make(const GrColorInfo& srcInfo, const GrColorInfo& dstInfo);
30 
steps()31     const SkColorSpaceXformSteps& steps() const { return fSteps; }
32 
33     /**
34      * GrGLSLFragmentProcessor::GenKey() must call this and include the returned value in its
35      * computed key.
36      */
XformKey(const GrColorSpaceXform * xform)37     static uint32_t XformKey(const GrColorSpaceXform* xform) {
38         // Code generation depends on which steps we apply,
39         // and the kinds of transfer functions (if we're applying those).
40         if (!xform) { return 0; }
41 
42         const SkColorSpaceXformSteps& steps(xform->fSteps);
43         uint32_t key = steps.flags.mask();
44         if (steps.flags.linearize) {
45             key |= classify_transfer_fn(steps.srcTF)    << 8;
46         }
47         if (steps.flags.encode) {
48             key |= classify_transfer_fn(steps.dstTFInv) << 16;
49         }
50         return key;
51     }
52 
53     static bool Equals(const GrColorSpaceXform* a, const GrColorSpaceXform* b);
54 
55     SkColor4f apply(const SkColor4f& srcColor);
56 
57 private:
58     friend class GrGLSLColorSpaceXformHelper;
59 
60     SkColorSpaceXformSteps fSteps;
61 };
62 
63 class GrColorSpaceXformEffect : public GrFragmentProcessor {
64 public:
65     /**
66      *  Returns a fragment processor that calls the passed in fragment processor, and then converts
67      *  the color space of the output from src to dst. If the child is null, fInputColor is used.
68      */
69     static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
70                                                      SkColorSpace* src, SkAlphaType srcAT,
71                                                      SkColorSpace* dst, SkAlphaType dstAT);
72     static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
73                                                      const GrColorInfo& srcInfo,
74                                                      const GrColorInfo& dstInfo);
75 
76     /**
77      * Returns a fragment processor that calls the passed in FP and then converts it with the given
78      * color xform. If the child is null, fInputColor is used. Returns child as-is if the xform is
79      * null (i.e. a no-op).
80      */
81     static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
82                                                      sk_sp<GrColorSpaceXform> colorXform);
83 
name()84     const char* name() const override { return "ColorSpaceXform"; }
85     std::unique_ptr<GrFragmentProcessor> clone() const override;
86 
colorXform()87     const GrColorSpaceXform* colorXform() const { return fColorXform.get(); }
88 
89 private:
90     GrColorSpaceXformEffect(std::unique_ptr<GrFragmentProcessor> child,
91                             sk_sp<GrColorSpaceXform> colorXform);
92 
93     GrColorSpaceXformEffect(const GrColorSpaceXformEffect& that);
94 
95     static OptimizationFlags OptFlags(const GrFragmentProcessor* child);
96     SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override;
97 
98     std::unique_ptr<GrGLSLFragmentProcessor> onMakeProgramImpl() const override;
99     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
100     bool onIsEqual(const GrFragmentProcessor&) const override;
101 
102     sk_sp<GrColorSpaceXform> fColorXform;
103 
104     using INHERITED = GrFragmentProcessor;
105 };
106 
107 #endif
108