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 */ 20class GrColorSpaceXform : public SkRefCnt { 21public: 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 56private: 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 74class 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, 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 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 105#endif 106