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