Home | History | Annotate | Download | only in gpu
      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 "GrColor.h"
     12 #include "GrFragmentProcessor.h"
     13 #include "SkColorSpace.h"
     14 #include "SkMatrix44.h"
     15 #include "SkRefCnt.h"
     16 
     17  /**
     18   * Represents a color space transformation
     19   */
     20 class GrColorSpaceXform : public SkRefCnt {
     21 public:
     22     GrColorSpaceXform(const SkColorSpaceTransferFn&, const SkMatrix44&, uint32_t);
     23 
     24     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     }
     33 
     34     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; }
     41 
     42     /**
     43      * GrGLSLFragmentProcessor::GenKey() must call this and include the returned value in its
     44      * computed key.
     45      */
     46     static uint32_t XformKey(const GrColorSpaceXform* xform) {
     47         // Code generation depends on which steps we apply (as encoded by fFlags)
     48         return SkToBool(xform) ? xform->fFlags : 0;
     49     }
     50 
     51     static bool Equals(const GrColorSpaceXform* a, const GrColorSpaceXform* b);
     52 
     53     GrColor4f unclampedXform(const GrColor4f& srcColor);
     54     GrColor4f clampedXform(const GrColor4f& srcColor);
     55 
     56 private:
     57     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;
     72 };
     73 
     74 class GrColorSpaceXformEffect : public GrFragmentProcessor {
     75 public:
     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,
     82                                                      GrPixelConfig srcConfig,
     83                                                      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 
     90 private:
     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 
    105 #endif
    106