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