blob: f63b1660f36119929bd70d9b58fb63cd9eb576c4 [file] [log] [blame]
brianosman54f30c12016-07-18 10:53:52 -07001/*
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
brianosman5a7ae7e2016-09-12 12:07:25 -070011#include "GrColor.h"
Brian Osmanc4f93ca2017-10-17 17:15:52 -040012#include "GrFragmentProcessor.h"
Brian Osmanf06ead92017-10-30 13:47:41 -040013#include "SkColorSpace.h"
brianosman51924752016-09-12 08:50:19 -070014#include "SkMatrix44.h"
brianosman54f30c12016-07-18 10:53:52 -070015#include "SkRefCnt.h"
16
brianosman54f30c12016-07-18 10:53:52 -070017 /**
Brian Osmanf06ead92017-10-30 13:47:41 -040018 * Represents a color space transformation
brianosman54f30c12016-07-18 10:53:52 -070019 */
20class GrColorSpaceXform : public SkRefCnt {
21public:
Brian Osmanf06ead92017-10-30 13:47:41 -040022 GrColorSpaceXform(const SkColorSpaceTransferFn&, const SkMatrix44&, uint32_t);
brianosman54f30c12016-07-18 10:53:52 -070023
Brian Osmanf06ead92017-10-30 13:47:41 -040024 static sk_sp<GrColorSpaceXform> Make(const SkColorSpace* src,
25 GrPixelConfig srcConfig,
26 const SkColorSpace* dst);
27 static sk_sp<GrColorSpaceXform> MakeGamutXform(const SkColorSpace* src,
28 const SkColorSpace* dst) {
29 auto result = Make(src, kUnknown_GrPixelConfig, dst);
30 SkASSERT(!result || 0 == (result->fFlags & ~kApplyGamutXform_Flag));
31 return result;
32 }
brianosman54f30c12016-07-18 10:53:52 -070033
Brian Osmanf06ead92017-10-30 13:47:41 -040034 const SkColorSpaceTransferFn& transferFn() const { return fSrcTransferFn; }
35 const float* transferFnCoeffs() const {
36 static_assert(0 == offsetof(SkColorSpaceTransferFn, fG), "TransferFn layout");
37 return &fSrcTransferFn.fG;
38 }
39
40 const SkMatrix44& gamutXform() const { return fGamutXform; }
brianosman77320db2016-09-07 08:09:10 -070041
42 /**
43 * GrGLSLFragmentProcessor::GenKey() must call this and include the returned value in its
44 * computed key.
45 */
Brian Osmane411a072017-03-14 10:26:58 -040046 static uint32_t XformKey(const GrColorSpaceXform* xform) {
Brian Osmanf06ead92017-10-30 13:47:41 -040047 // Code generation depends on which steps we apply (as encoded by fFlags)
48 return SkToBool(xform) ? xform->fFlags : 0;
brianosman77320db2016-09-07 08:09:10 -070049 }
brianosman54f30c12016-07-18 10:53:52 -070050
brianosmanb9c51372016-09-15 11:09:45 -070051 static bool Equals(const GrColorSpaceXform* a, const GrColorSpaceXform* b);
52
Brian Osmanfe3e8582017-10-20 11:27:49 -040053 GrColor4f unclampedXform(const GrColor4f& srcColor);
54 GrColor4f clampedXform(const GrColor4f& srcColor);
brianosman5a7ae7e2016-09-12 12:07:25 -070055
brianosman54f30c12016-07-18 10:53:52 -070056private:
Brian Osmanf06ead92017-10-30 13:47:41 -040057 friend class GrGLSLColorSpaceXformHelper;
58
59 enum Flags {
60 kApplyTransferFn_Flag = 0x1,
61 kApplyGamutXform_Flag = 0x2,
62
63 // Almost never used. This handles the case where the src data is sRGB pixel config,
64 // but the color space has a different transfer function. In that case, we first undo
65 // the HW sRGB -> Linear conversion, before applying any other steps.
66 kApplyInverseSRGB_Flag = 0x4,
67 };
68
69 SkColorSpaceTransferFn fSrcTransferFn;
70 SkMatrix44 fGamutXform;
71 uint32_t fFlags;
brianosman54f30c12016-07-18 10:53:52 -070072};
73
Brian Osmanc4f93ca2017-10-17 17:15:52 -040074class GrColorSpaceXformEffect : public GrFragmentProcessor {
75public:
76 /**
77 * Returns a fragment processor that calls the passed in fragment processor, and then converts
78 * the color space of the output from src to dst.
79 */
80 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
81 const SkColorSpace* src,
Brian Osmanf06ead92017-10-30 13:47:41 -040082 GrPixelConfig srcConfig,
Brian Osmanc4f93ca2017-10-17 17:15:52 -040083 const SkColorSpace* dst);
84
85 const char* name() const override { return "ColorSpaceXform"; }
86 std::unique_ptr<GrFragmentProcessor> clone() const override;
87
88 const GrColorSpaceXform* colorXform() const { return fColorXform.get(); }
89
90private:
91 GrColorSpaceXformEffect(std::unique_ptr<GrFragmentProcessor> child,
92 sk_sp<GrColorSpaceXform> colorXform);
93
94 static OptimizationFlags OptFlags(const GrFragmentProcessor* child);
95
96 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
97 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
98 bool onIsEqual(const GrFragmentProcessor&) const override;
99
100 sk_sp<GrColorSpaceXform> fColorXform;
101
102 typedef GrFragmentProcessor INHERITED;
103};
104
brianosman54f30c12016-07-18 10:53:52 -0700105#endif