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 calls the passed in fragment processor, and then converts
64 * the color space of the output from src to dst. If the child is null, sk_InColor is used.
65 */
66 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
67 SkColorSpace* src, SkAlphaType srcAT,
68 SkColorSpace* dst, SkAlphaType dstAT);
69
70 /**
71 * Returns a fragment processor that calls the passed in FP and then converts it with the given
72 * color xform. If the child is null, sk_InColor is used. Returns child as-is if the xform is
73 * null (i.e. a no-op).
74 */
75 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
76 sk_sp<GrColorSpaceXform> colorXform);
77
78 const char* name() const override { return "ColorSpaceXform"; }
79 std::unique_ptr<GrFragmentProcessor> clone() const override;
80
81 const GrColorSpaceXform* colorXform() const { return fColorXform.get(); }
82
83private:
84 GrColorSpaceXformEffect(std::unique_ptr<GrFragmentProcessor> child,
85 sk_sp<GrColorSpaceXform> colorXform);
86
87 GrColorSpaceXformEffect(const GrColorSpaceXformEffect& that);
88
89 static OptimizationFlags OptFlags(const GrFragmentProcessor* child);
90 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override;
91
92 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
93 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
94 bool onIsEqual(const GrFragmentProcessor&) const override;
95
96 sk_sp<GrColorSpaceXform> fColorXform;
97
98 typedef GrFragmentProcessor INHERITED;
99};
100
101#endif
102