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