Home | History | Annotate | Download | only in effects
      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  */
     23 class GrNonlinearColorSpaceXformEffect : public GrFragmentProcessor {
     24 public:
     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 
     55 private:
     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