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 Sk4fGradientPriv_DEFINED 9 #define Sk4fGradientPriv_DEFINED 10 11 #include "SkColor.h" 12 #include "SkHalf.h" 13 #include "SkImageInfo.h" 14 #include "SkNx.h" 15 #include "SkPM4f.h" 16 #include "SkPM4fPriv.h" 17 #include "SkUtils.h" 18 19 // Templates shared by various 4f gradient flavors. 20 21 namespace { 22 23 enum class ApplyPremul { True, False }; 24 25 template <ApplyPremul> 26 struct PremulTraits; 27 28 template <> 29 struct PremulTraits<ApplyPremul::False> { 30 static Sk4f apply(const Sk4f& c) { return c; } 31 }; 32 33 template <> 34 struct PremulTraits<ApplyPremul::True> { 35 static Sk4f apply(const Sk4f& c) { 36 const float alpha = c[SkPM4f::A]; 37 // FIXME: portable swizzle? 38 return c * Sk4f(alpha, alpha, alpha, 1); 39 } 40 }; 41 42 // Struct encapsulating various dest-dependent ops: 43 // 44 // - load() Load a SkPM4f value into Sk4f. Normally called once per interval 45 // advance. Also applies a scale and swizzle suitable for DstType. 46 // 47 // - store() Store one Sk4f to dest. Optionally handles premul, color space 48 // conversion, etc. 49 // 50 // - store(count) Store the Sk4f value repeatedly to dest, count times. 51 // 52 // - store4x() Store 4 Sk4f values to dest (opportunistic optimization). 53 // 54 template <ApplyPremul premul> 55 struct DstTraits { 56 using PM = PremulTraits<premul>; 57 58 static Sk4f load(const SkPM4f& c) { 59 return c.to4f(); 60 } 61 62 static void store(const Sk4f& c, SkPM4f* dst) { 63 PM::apply(c).store(dst->fVec); 64 } 65 66 static void store(const Sk4f& c, SkPM4f* dst, int n) { 67 const Sk4f pmc = PM::apply(c); 68 for (int i = 0; i < n; ++i) { 69 pmc.store(dst[i].fVec); 70 } 71 } 72 73 static void store4x(const Sk4f& c0, const Sk4f& c1, 74 const Sk4f& c2, const Sk4f& c3, 75 SkPM4f* dst) { 76 store(c0, dst + 0); 77 store(c1, dst + 1); 78 store(c2, dst + 2); 79 store(c3, dst + 3); 80 } 81 }; 82 83 } // anonymous namespace 84 85 #endif // Sk4fGradientPriv_DEFINED 86