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