Chromium Code Reviews| Index: src/codec/SkSwizzler.cpp |
| diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp |
| index d783380294ab81f18a5c67e2d66bf8e5a33db2d4..62b962b2faf40afe0b4b7c9256818a9c43dd8aa4 100644 |
| --- a/src/codec/SkSwizzler.cpp |
| +++ b/src/codec/SkSwizzler.cpp |
| @@ -462,22 +462,21 @@ static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul( |
| return COMPUTE_RESULT_ALPHA; |
| } |
| -static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ( |
| +template <SkSwizzler::RowProc proc> |
| +SkSwizzler::ResultAlpha SkSwizzler::SkipLeading8888ZerosThen( |
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
| int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { |
| + SkASSERT(!ctable); |
| - src += offset; |
| - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
| - INIT_RESULT_ALPHA; |
| - for (int x = 0; x < dstWidth; x++) { |
| - unsigned alpha = src[3]; |
| - UPDATE_RESULT_ALPHA(alpha); |
| - if (0 != alpha) { |
| - dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
| - } |
| - src += deltaSrc; |
| + auto src32 = (const uint32_t*)(src+offset); |
| + auto dst32 = (uint32_t*)dstRow; |
| + |
| + while (dstWidth > 0 && *src32 == 0) { |
|
scroggo
2016/01/08 21:33:20
FWIW, when we are premultiplying, we really only n
|
| + dstWidth--; |
| + dst32 += 1; |
| + src32 += deltaSrc/4; |
| } |
| - return COMPUTE_RESULT_ALPHA; |
| + return proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable); |
| } |
| // kCMYK |
| @@ -563,34 +562,6 @@ static SkSwizzler::ResultAlpha swizzle_cmyk_to_565( |
| return SkSwizzler::kOpaque_ResultAlpha; |
| } |
| -/** |
| - FIXME: This was my idea to cheat in order to continue taking advantage of skipping zeroes. |
| - This would be fine for drawing normally, but not for drawing with transfer modes. Being |
| - honest means we can draw correctly with transfer modes, with the cost of not being able |
| - to take advantage of Android's free unwritten pages. Something to keep in mind when we |
| - decide whether to switch to unpremul default. |
| -static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow, |
| - const uint8_t* SK_RESTRICT src, |
| - int dstWidth, int bitsPerPixel, int offset, |
| - const SkPMColor[]) { |
| - src += offset; |
| - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
| - unsigned alphaMask = 0xFF; |
| - for (int x = 0; x < dstWidth; x++) { |
| - unsigned alpha = src[3]; |
| - // NOTE: We cheat here. The caller requested unpremul and skip zeroes. It's possible |
| - // the color components are not zero, but we skip them anyway, meaning they'll remain |
| - // zero (implied by the request to skip zeroes). |
| - if (0 != alpha) { |
| - dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); |
| - } |
| - src += deltaSrc; |
| - alphaMask &= alpha; |
| - } |
| - return alphaMask != 0xFF; |
| -} |
| -*/ |
| - |
| SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
| const SkPMColor* ctable, |
| const SkImageInfo& dstInfo, |
| @@ -725,11 +696,14 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
| switch (dstInfo.colorType()) { |
| case kN32_SkColorType: |
| if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { |
| - // Respect zeroInit? |
| - proc = &swizzle_rgba_to_n32_unpremul; |
| + if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
| + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>; |
| + } else { |
| + proc = &swizzle_rgba_to_n32_unpremul; |
| + } |
| } else { |
| if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
| - proc = &swizzle_rgba_to_n32_premul_skipZ; |
| + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_premul>; |
| } else { |
| proc = &swizzle_rgba_to_n32_premul; |
| } |
| @@ -779,7 +753,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
| // Store bpp in bytes if it is an even multiple, otherwise use bits |
| int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc); |
| int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType()); |
| - |
| + |
| int srcOffset = 0; |
| int srcWidth = dstInfo.width(); |
| int dstOffset = 0; |