• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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