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
16class SkColorSpace;
17
18 /**
19 * Represents a color space transformation
20 */
21class GrColorSpaceXform : public SkRefCnt {
22public:
23 GrColorSpaceXform(const SkColorSpaceXformSteps& steps) : fSteps(steps) {}
24
25 static sk_sp<GrColorSpaceXform> Make(SkColorSpace* src, SkAlphaType srcAT,
26 SkColorSpace* dst, SkAlphaType dstAT);
27
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 */
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
54private:
55 friend class GrGLSLColorSpaceXformHelper;
56
57 SkColorSpaceXformSteps fSteps;
58};
59
60class GrColorSpaceXformEffect : public GrFragmentProcessor {
61public:
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
83 const char* name() const override { return "ColorSpaceXform"; }
84 std::unique_ptr<GrFragmentProcessor> clone() const override;
85
86 const GrColorSpaceXform* colorXform() const { return fColorXform.get(); }
87
88private:
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