| 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 |