Chromium Code Reviews| Index: src/core/SkMipMap.cpp |
| diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp |
| index 6e921c7942d98f596c193052a5d308ff9dee06c8..428eace15790a58e28f0daf228b9ca0ef290b87d 100644 |
| --- a/src/core/SkMipMap.cpp |
| +++ b/src/core/SkMipMap.cpp |
| @@ -383,22 +383,29 @@ template <typename T> T add_121(T a, T b, T c) { |
| // we need to sample in each dimension to produce 1 dst pixel. |
| // |
| -template <typename F> void downsample_2_2(void* dst, const void* src, size_t srcRB) { |
| +template <typename F> void downsample_2_2(void* dst, const void* src, size_t srcRB, int count) { |
| auto p0 = static_cast<const typename F::Type*>(src); |
| auto p1 = (const typename F::Type*)((const char*)p0 + srcRB); |
| + auto d = static_cast<typename F::Type*>(dst); |
| - auto c00 = F::Expand(p0[0]); |
| - auto c01 = F::Expand(p0[1]); |
| - auto c10 = F::Expand(p1[0]); |
| - auto c11 = F::Expand(p1[1]); |
| + for (int i = 0; i < count; ++i) { |
| + auto c00 = F::Expand(p0[0]); |
| + auto c01 = F::Expand(p0[1]); |
| + auto c10 = F::Expand(p1[0]); |
| + auto c11 = F::Expand(p1[1]); |
| + auto c = c00 + c10 + c01 + c11; |
| - auto c = c00 + c10 + c01 + c11; |
| - *(typename F::Type*)dst = F::Compact(c >> 2); |
| + d[i] = F::Compact(c >> 2); |
| + p0 += 2; |
| + p1 += 2; |
| + } |
| } |
| -template <typename F> void downsample_3_2(void* dst, const void* src, size_t srcRB) { |
| +template <typename F> void downsample_3_2(void* dst, const void* src, size_t srcRB, int count) { |
| + SkASSERT(count > 0); |
| auto p0 = static_cast<const typename F::Type*>(src); |
| auto p1 = (const typename F::Type*)((const char*)p0 + srcRB); |
| + auto d = static_cast<typename F::Type*>(dst); |
| auto c00 = F::Expand(p0[0]); |
| auto c01 = F::Expand(p0[1]); |
| @@ -406,31 +413,51 @@ template <typename F> void downsample_3_2(void* dst, const void* src, size_t src |
| auto c10 = F::Expand(p1[0]); |
| auto c11 = F::Expand(p1[1]); |
| auto c12 = F::Expand(p1[2]); |
| - |
| auto c = add_121(c00, c01, c02) + add_121(c10, c11, c12); |
| - *(typename F::Type*)dst = F::Compact(c >> 3); |
| + d[0] = F::Compact(c >> 3); |
| + |
| + for (int i = 1; i < count; ++i) { |
| + p0 += 2; |
| + p1 += 2; |
| + c00 = c02; |
| + c01 = F::Expand(p0[1]); |
| + c02 = F::Expand(p0[2]); |
| + c10 = c12; |
| + c11 = F::Expand(p1[1]); |
| + c12 = F::Expand(p1[2]); |
| + auto c = add_121(c00, c01, c02) + add_121(c10, c11, c12); |
| + d[i] = F::Compact(c >> 3); |
| + } |
|
f(malita)
2016/01/16 16:46:10
Instead of unrolling a full iteration, could we se
reed1
2016/01/16 17:03:10
Good catch! Thanks.
|
| } |
| -template <typename F> void downsample_2_3(void* dst, const void* src, size_t srcRB) { |
| +template <typename F> void downsample_2_3(void* dst, const void* src, size_t srcRB, int count) { |
| auto p0 = static_cast<const typename F::Type*>(src); |
| auto p1 = (const typename F::Type*)((const char*)p0 + srcRB); |
| auto p2 = (const typename F::Type*)((const char*)p1 + srcRB); |
| - |
| - auto c00 = F::Expand(p0[0]); |
| - auto c01 = F::Expand(p0[1]); |
| - auto c10 = F::Expand(p1[0]); |
| - auto c11 = F::Expand(p1[1]); |
| - auto c20 = F::Expand(p2[0]); |
| - auto c21 = F::Expand(p2[1]); |
| - auto c = add_121(c00, c10, c20) + add_121(c01, c11, c21); |
| - *(typename F::Type*)dst = F::Compact(c >> 3); |
| + auto d = static_cast<typename F::Type*>(dst); |
| + |
| + for (int i = 0; i < count; ++i) { |
| + auto c00 = F::Expand(p0[0]); |
| + auto c01 = F::Expand(p0[1]); |
| + auto c10 = F::Expand(p1[0]); |
| + auto c11 = F::Expand(p1[1]); |
| + auto c20 = F::Expand(p2[0]); |
| + auto c21 = F::Expand(p2[1]); |
| + auto c = add_121(c00, c10, c20) + add_121(c01, c11, c21); |
| + |
| + d[i] = F::Compact(c >> 3); |
| + p0 += 2; |
| + p1 += 2; |
| + p2 += 2; |
| + } |
| } |
| -template <typename F> void downsample_3_3(void* dst, const void* src, size_t srcRB) { |
| +template <typename F> void downsample_3_3(void* dst, const void* src, size_t srcRB, int count) { |
| auto p0 = static_cast<const typename F::Type*>(src); |
| auto p1 = (const typename F::Type*)((const char*)p0 + srcRB); |
| auto p2 = (const typename F::Type*)((const char*)p1 + srcRB); |
| - |
| + auto d = static_cast<typename F::Type*>(dst); |
| + |
| auto c00 = F::Expand(p0[0]); |
| auto c01 = F::Expand(p0[1]); |
| auto c02 = F::Expand(p0[2]); |
| @@ -440,9 +467,26 @@ template <typename F> void downsample_3_3(void* dst, const void* src, size_t src |
| auto c20 = F::Expand(p2[0]); |
| auto c21 = F::Expand(p2[1]); |
| auto c22 = F::Expand(p2[2]); |
| - |
| auto c = add_121(c00, c01, c02) + (add_121(c10, c11, c12) << 1) + add_121(c20, c21, c22); |
| - *(typename F::Type*)dst = F::Compact(c >> 4); |
| + d[0] = F::Compact(c >> 4); |
| + |
| + for (int i = 1; i < count; ++i) { |
| + c00 = c02; |
| + c01 = F::Expand(p0[1]); |
| + c02 = F::Expand(p0[2]); |
| + c10 = c12; |
| + c11 = F::Expand(p1[1]); |
| + c12 = F::Expand(p1[2]); |
| + c20 = c22; |
| + c21 = F::Expand(p2[1]); |
| + c22 = F::Expand(p2[2]); |
| + c = add_121(c00, c01, c02) + (add_121(c10, c11, c12) << 1) + add_121(c20, c21, c22); |
| + |
| + d[i] = F::Compact(c >> 4); |
| + p0 += 2; |
| + p1 += 2; |
| + p2 += 2; |
| + } |
|
f(malita)
2016/01/16 16:46:10
Ditto.
reed1
2016/01/16 17:03:10
Done.
|
| } |
| /////////////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -459,7 +503,7 @@ size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) { |
| } |
| SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { |
| - typedef void FilterProc(void*, const void* srcPtr, size_t srcRB); |
| + typedef void FilterProc(void*, const void* srcPtr, size_t srcRB, int count); |
| FilterProc* proc_2_2 = nullptr; |
| FilterProc* proc_2_3 = nullptr; |
| @@ -574,8 +618,6 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { |
| SkPixmap dstPM(SkImageInfo::Make(width, height, ct, at), addr, rowBytes); |
| - const size_t pixelSize = srcPM.info().bytesPerPixel(); |
| - |
| const void* srcBasePtr = srcPM.addr(); |
| void* dstBasePtr = dstPM.writable_addr(); |
| @@ -596,15 +638,7 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { |
| const size_t srcRB = srcPM.rowBytes(); |
| for (int y = 0; y < height; y++) { |
| - const void* srcPtr = srcBasePtr; |
| - void* dstPtr = dstBasePtr; |
| - |
| - for (int x = 0; x < width; x++) { |
| - proc(dstPtr, srcPtr, srcRB); |
| - srcPtr = (char*)srcPtr + pixelSize * 2; |
| - dstPtr = (char*)dstPtr + pixelSize; |
| - } |
| - |
| + proc(dstBasePtr, srcBasePtr, srcRB, width); |
| srcBasePtr = (char*)srcBasePtr + srcRB * 2; // jump two rows |
| dstBasePtr = (char*)dstBasePtr + dstPM.rowBytes(); |
| } |