OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkMipMap.h" | 8 #include "SkMipMap.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| 11 #include "SkNx.h" |
11 | 12 |
12 // | 13 // |
13 // ColorTypeFilter is the "Type" we pass to some downsample template functions. | 14 // ColorTypeFilter is the "Type" we pass to some downsample template functions. |
14 // It controls how we expand a pixel into a large type, with space between each
component, | 15 // It controls how we expand a pixel into a large type, with space between each
component, |
15 // so we can then perform our simple filter (either box or triangle) and store t
he intermediates | 16 // so we can then perform our simple filter (either box or triangle) and store t
he intermediates |
16 // in the expanded type. | 17 // in the expanded type. |
17 // | 18 // |
18 | 19 |
19 struct ColorTypeFilter_8888 { | 20 struct ColorTypeFilter_8888 { |
20 typedef uint32_t Type; | 21 typedef uint32_t Type; |
| 22 #if defined(SKNX_IS_FAST) |
| 23 static Sk4h Expand(uint32_t x) { |
| 24 return SkNx_cast<uint16_t>(Sk4b::Load((const uint8_t*)&x)); |
| 25 } |
| 26 static uint32_t Compact(const Sk4h& x) { |
| 27 uint32_t r; |
| 28 SkNx_cast<uint8_t>(x).store((uint8_t*)&r); |
| 29 return r; |
| 30 } |
| 31 #else |
21 static uint64_t Expand(uint32_t x) { | 32 static uint64_t Expand(uint32_t x) { |
22 return (x & 0xFF00FF) | ((uint64_t)(x & 0xFF00FF00) << 24); | 33 return (x & 0xFF00FF) | ((uint64_t)(x & 0xFF00FF00) << 24); |
23 } | 34 } |
24 static uint32_t Compact(uint64_t x) { | 35 static uint32_t Compact(uint64_t x) { |
25 return (uint32_t)((x & 0xFF00FF) | ((x >> 24) & 0xFF00FF00)); | 36 return (uint32_t)((x & 0xFF00FF) | ((x >> 24) & 0xFF00FF00)); |
26 } | 37 } |
| 38 #endif |
27 }; | 39 }; |
28 | 40 |
29 struct ColorTypeFilter_565 { | 41 struct ColorTypeFilter_565 { |
30 typedef uint16_t Type; | 42 typedef uint16_t Type; |
31 static uint32_t Expand(uint16_t x) { | 43 static uint32_t Expand(uint16_t x) { |
32 return (x & ~SK_G16_MASK_IN_PLACE) | ((x & SK_G16_MASK_IN_PLACE) << 16); | 44 return (x & ~SK_G16_MASK_IN_PLACE) | ((x & SK_G16_MASK_IN_PLACE) << 16); |
33 } | 45 } |
34 static uint16_t Compact(uint32_t x) { | 46 static uint16_t Compact(uint32_t x) { |
35 return (x & ~SK_G16_MASK_IN_PLACE) | ((x >> 16) & SK_G16_MASK_IN_PLACE); | 47 return (x & ~SK_G16_MASK_IN_PLACE) | ((x >> 16) & SK_G16_MASK_IN_PLACE); |
36 } | 48 } |
(...skipping 12 matching lines...) Expand all Loading... |
49 struct ColorTypeFilter_8 { | 61 struct ColorTypeFilter_8 { |
50 typedef uint8_t Type; | 62 typedef uint8_t Type; |
51 static unsigned Expand(unsigned x) { | 63 static unsigned Expand(unsigned x) { |
52 return x; | 64 return x; |
53 } | 65 } |
54 static uint8_t Compact(unsigned x) { | 66 static uint8_t Compact(unsigned x) { |
55 return (uint8_t)x; | 67 return (uint8_t)x; |
56 } | 68 } |
57 }; | 69 }; |
58 | 70 |
59 template <typename T> T add_121(T a, T b, T c) { | 71 template <typename T> T add_121(const T& a, const T& b, const T& c) { |
60 return a + b + b + c; | 72 return a + b + b + c; |
61 } | 73 } |
62 | 74 |
63 // | 75 // |
64 // To produce each mip level, we need to filter down by 1/2 (e.g. 100x100 -> 50
,50) | 76 // To produce each mip level, we need to filter down by 1/2 (e.g. 100x100 -> 50
,50) |
65 // If the starting dimension is odd, we floor the size of the lower level (e.g.
101 -> 50) | 77 // If the starting dimension is odd, we floor the size of the lower level (e.g.
101 -> 50) |
66 // In those (odd) cases, we use a triangle filter, with 1-pixel overlap between
samplings, | 78 // In those (odd) cases, we use a triangle filter, with 1-pixel overlap between
samplings, |
67 // else for even cases, we just use a 2x box filter. | 79 // else for even cases, we just use a 2x box filter. |
68 // | 80 // |
69 // This produces 4 possible filters: 2x2 2x3 3x2 3x3 where WxH indicates the nu
mber of src pixels | 81 // This produces 4 possible filters: 2x2 2x3 3x2 3x3 where WxH indicates the nu
mber of src pixels |
(...skipping 16 matching lines...) Expand all Loading... |
86 p0 += 2; | 98 p0 += 2; |
87 p1 += 2; | 99 p1 += 2; |
88 } | 100 } |
89 } | 101 } |
90 | 102 |
91 template <typename F> void downsample_3_2(void* dst, const void* src, size_t src
RB, int count) { | 103 template <typename F> void downsample_3_2(void* dst, const void* src, size_t src
RB, int count) { |
92 SkASSERT(count > 0); | 104 SkASSERT(count > 0); |
93 auto p0 = static_cast<const typename F::Type*>(src); | 105 auto p0 = static_cast<const typename F::Type*>(src); |
94 auto p1 = (const typename F::Type*)((const char*)p0 + srcRB); | 106 auto p1 = (const typename F::Type*)((const char*)p0 + srcRB); |
95 auto d = static_cast<typename F::Type*>(dst); | 107 auto d = static_cast<typename F::Type*>(dst); |
96 | 108 |
97 auto c02 = F::Expand(p0[0]); | 109 auto c02 = F::Expand(p0[0]); |
98 auto c12 = F::Expand(p1[0]); | 110 auto c12 = F::Expand(p1[0]); |
99 for (int i = 0; i < count; ++i) { | 111 for (int i = 0; i < count; ++i) { |
100 auto c00 = c02; | 112 auto c00 = c02; |
101 auto c01 = F::Expand(p0[1]); | 113 auto c01 = F::Expand(p0[1]); |
102 c02 = F::Expand(p0[2]); | 114 c02 = F::Expand(p0[2]); |
103 auto c10 = c12; | 115 auto c10 = c12; |
104 auto c11 = F::Expand(p1[1]); | 116 auto c11 = F::Expand(p1[1]); |
105 c12 = F::Expand(p1[2]); | 117 c12 = F::Expand(p1[2]); |
106 | 118 |
107 auto c = add_121(c00, c01, c02) + add_121(c10, c11, c12); | 119 auto c = add_121(c00, c01, c02) + add_121(c10, c11, c12); |
108 d[i] = F::Compact(c >> 3); | 120 d[i] = F::Compact(c >> 3); |
109 p0 += 2; | 121 p0 += 2; |
110 p1 += 2; | 122 p1 += 2; |
111 } | 123 } |
112 } | 124 } |
113 | 125 |
114 template <typename F> void downsample_2_3(void* dst, const void* src, size_t src
RB, int count) { | 126 template <typename F> void downsample_2_3(void* dst, const void* src, size_t src
RB, int count) { |
115 auto p0 = static_cast<const typename F::Type*>(src); | 127 auto p0 = static_cast<const typename F::Type*>(src); |
116 auto p1 = (const typename F::Type*)((const char*)p0 + srcRB); | 128 auto p1 = (const typename F::Type*)((const char*)p0 + srcRB); |
117 auto p2 = (const typename F::Type*)((const char*)p1 + srcRB); | 129 auto p2 = (const typename F::Type*)((const char*)p1 + srcRB); |
118 auto d = static_cast<typename F::Type*>(dst); | 130 auto d = static_cast<typename F::Type*>(dst); |
119 | 131 |
120 for (int i = 0; i < count; ++i) { | 132 for (int i = 0; i < count; ++i) { |
121 auto c00 = F::Expand(p0[0]); | 133 auto c00 = F::Expand(p0[0]); |
122 auto c01 = F::Expand(p0[1]); | 134 auto c01 = F::Expand(p0[1]); |
123 auto c10 = F::Expand(p1[0]); | 135 auto c10 = F::Expand(p1[0]); |
124 auto c11 = F::Expand(p1[1]); | 136 auto c11 = F::Expand(p1[1]); |
125 auto c20 = F::Expand(p2[0]); | 137 auto c20 = F::Expand(p2[0]); |
126 auto c21 = F::Expand(p2[1]); | 138 auto c21 = F::Expand(p2[1]); |
127 | 139 |
128 auto c = add_121(c00, c10, c20) + add_121(c01, c11, c21); | 140 auto c = add_121(c00, c10, c20) + add_121(c01, c11, c21); |
129 d[i] = F::Compact(c >> 3); | 141 d[i] = F::Compact(c >> 3); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 return nullptr; | 359 return nullptr; |
348 } | 360 } |
349 const SkPixmap& srcPixmap = srcUnlocker.pixmap(); | 361 const SkPixmap& srcPixmap = srcUnlocker.pixmap(); |
350 // Try to catch where we might have returned nullptr for src crbug.com/49281
8 | 362 // Try to catch where we might have returned nullptr for src crbug.com/49281
8 |
351 if (nullptr == srcPixmap.addr()) { | 363 if (nullptr == srcPixmap.addr()) { |
352 sk_throw(); | 364 sk_throw(); |
353 } | 365 } |
354 return Build(srcPixmap, fact); | 366 return Build(srcPixmap, fact); |
355 } | 367 } |
356 | 368 |
OLD | NEW |