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 "include/core/SkRefCnt.h" 12 #include "src/core/SkColorSpacePriv.h" 13 #include "src/core/SkColorSpaceXformSteps.h" 14 #include "src/gpu/GrFragmentProcessor.h" 15 16 class SkColorSpace; 17 18 /** 19 * Represents a color space transformation 20 */ 21 class GrColorSpaceXform : public SkRefCnt { 22 public: GrColorSpaceXform(const SkColorSpaceXformSteps & steps)23 GrColorSpaceXform(const SkColorSpaceXformSteps& steps) : fSteps(steps) {} 24 25 static sk_sp<GrColorSpaceXform> Make(SkColorSpace* src, SkAlphaType srcAT, 26 SkColorSpace* dst, SkAlphaType dstAT); 27 steps()28 const SkColorSpaceXformSteps& steps() const { return fSteps; } 29 30 /** 31 * GrGLSLFragmentProcessor::GenKey() must call this and include the returned value in its 32 * computed key. 33 */ XformKey(const GrColorSpaceXform * xform)34 static uint32_t XformKey(const GrColorSpaceXform* xform) { 35 // Code generation depends on which steps we apply, 36 // and the kinds of transfer functions (if we're applying those). 37 if (!xform) { return 0; } 38 39 const SkColorSpaceXformSteps& steps(xform->fSteps); 40 uint32_t key = steps.flags.mask(); 41 if (steps.flags.linearize) { 42 key |= classify_transfer_fn(steps.srcTF) << 8; 43 } 44 if (steps.flags.encode) { 45 key |= classify_transfer_fn(steps.dstTFInv) << 16; 46 } 47 return key; 48 } 49 50 static bool Equals(const GrColorSpaceXform* a, const GrColorSpaceXform* b); 51 52 SkColor4f apply(const SkColor4f& srcColor); 53 54 private: 55 friend class GrGLSLColorSpaceXformHelper; 56 57 SkColorSpaceXformSteps fSteps; 58 }; 59 60 class GrColorSpaceXformEffect : public GrFragmentProcessor { 61 public: 62 /** 63 * Returns a fragment processor that converts the input's color space from src to dst. 64 */ 65 static std::unique_ptr<GrFragmentProcessor> Make(SkColorSpace* src, SkAlphaType srcAT, 66 SkColorSpace* dst, SkAlphaType dstAT); 67 68 /** 69 * Returns a fragment processor that calls the passed in fragment processor, and then converts 70 * the color space of the output from src to dst. 71 */ 72 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child, 73 SkColorSpace* src, SkAlphaType srcAT, 74 SkColorSpace* dst); 75 76 /** 77 * Returns a fragment processor that calls the passed in FP and then converts it with the given 78 * color xform. Returns null if child is null, returns child if the xform is null (e.g. noop). 79 */ 80 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child, 81 sk_sp<GrColorSpaceXform> colorXform); 82 name()83 const char* name() const override { return "ColorSpaceXform"; } 84 std::unique_ptr<GrFragmentProcessor> clone() const override; 85 colorXform()86 const GrColorSpaceXform* colorXform() const { return fColorXform.get(); } 87 88 private: 89 GrColorSpaceXformEffect(std::unique_ptr<GrFragmentProcessor> child, 90 sk_sp<GrColorSpaceXform> colorXform); 91 92 static OptimizationFlags OptFlags(const GrFragmentProcessor* child); 93 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override; 94 95 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; 96 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 97 bool onIsEqual(const GrFragmentProcessor&) const override; 98 99 sk_sp<GrColorSpaceXform> fColorXform; 100 101 typedef GrFragmentProcessor INHERITED; 102 }; 103 104 #endif 105