1/*
2 * Copyright 2017 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 GrNonlinearColorSpaceXformEffect_DEFINED
9#define GrNonlinearColorSpaceXformEffect_DEFINED
10
11#include "GrFragmentProcessor.h"
12#include "SkColorSpace.h"
13#include "SkMatrix44.h"
14
15/**
16 * The output of this effect is the input, transformed into a different color space.
17 * This effect is used for nonlinear blending color space support - it does not assume HW sRGB
18 * capabilities, and performs both the source and destination transfer functions numerically in
19 * the shader. Any parametric transfer function is supported. Because of the nonlinear blending,
20 * premultiplication is also nonlinear - source pixels are unpremultiplied before the source
21 * transfer function, and then premultiplied after the destination transfer function.
22 */
23class GrNonlinearColorSpaceXformEffect : public GrFragmentProcessor {
24public:
25    /**
26     * The conversion effect is only well defined with a valid source and destination color space.
27     * This will return nullptr if either space is nullptr, if both spaces are equal, or if either
28     * space has a non-parametric transfer funcion (e.g. lookup table or A2B).
29     */
30    static std::unique_ptr<GrFragmentProcessor> Make(const SkColorSpace* src,
31                                                     const SkColorSpace* dst);
32
33    const char* name() const override { return "NonlinearColorSpaceXform"; }
34
35    std::unique_ptr<GrFragmentProcessor> clone() const override;
36
37    static const int kNumTransferFnCoeffs = 7;
38
39    /**
40     * Flags that specify which operations are performed for one particular conversion.
41     * Some color space pairs may not need all operations, if one or both transfer functions
42     * is linear, or if the gamuts are the same.
43     */
44    enum Ops {
45        kSrcTransfer_Op = 0x1,
46        kGamutXform_Op  = 0x2,
47        kDstTransfer_Op = 0x4,
48    };
49
50    uint32_t ops() const { return fOps; }
51    const float* srcTransferFnCoeffs() const { return fSrcTransferFnCoeffs; }
52    const float* dstTransferFnCoeffs() const { return fDstTransferFnCoeffs; }
53    const SkMatrix44& gamutXform() const { return fGamutXform; }
54
55private:
56    GrNonlinearColorSpaceXformEffect(uint32_t ops,
57                                     const SkColorSpaceTransferFn& srcTransferFn,
58                                     const SkColorSpaceTransferFn& dstTransferFn,
59                                     const SkMatrix44& gamutXform);
60    GrNonlinearColorSpaceXformEffect(const GrNonlinearColorSpaceXformEffect&);
61
62    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
63    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
64    bool onIsEqual(const GrFragmentProcessor&) const override;
65
66    float fSrcTransferFnCoeffs[kNumTransferFnCoeffs];
67    float fDstTransferFnCoeffs[kNumTransferFnCoeffs];
68    SkMatrix44 fGamutXform;
69    uint32_t fOps;
70
71    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
72
73    typedef GrFragmentProcessor INHERITED;
74};
75
76#endif
77