diff options
author | mtklein <mtklein@chromium.org> | 2016-01-11 13:13:55 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-11 13:13:55 -0800 |
commit | 8604ca2d84cfa9527705c69d74a8449b532e0ee4 (patch) | |
tree | 44330c408f38205f98be442555f8a5dea0d66c20 /src/codec/SkSwizzler.cpp | |
parent | c7141eb8fba41f1e098499ef17d0bc79641d54c5 (diff) |
SkSwizzler: Factor skipping zeros out into a helper function.
I figure something like this lets us not worry about it in the new opts.
This skips only leading zeros per-scanline, not all zeros, but my bet is that
leading zeros are all that matters: it's got to be rare that a scanline is both
larger than 1024 pixels and has runs of 1024 transparent pixels in the middle.
I bet the big bang for the buck comes from skipping full scanlines (or even
multiple adjacent scanlines).
BUG=skia:4767
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1566653007
Review URL: https://codereview.chromium.org/1566653007
Diffstat (limited to 'src/codec/SkSwizzler.cpp')
-rw-r--r-- | src/codec/SkSwizzler.cpp | 65 |
1 files changed, 22 insertions, 43 deletions
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp index 3e7387795b..c9bdb50d10 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -395,21 +395,6 @@ static void swizzle_rgba_to_n32_unpremul( } } -static void swizzle_rgba_to_n32_premul_skipZ( - void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, - int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { - - src += offset; - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; - for (int x = 0; x < dstWidth; x++) { - unsigned alpha = src[3]; - if (0 != alpha) { - dst[x] = SkPremultiplyARGBInline(alpha, src[0], src[1], src[2]); - } - src += deltaSrc; - } -} - // kCMYK // // CMYK is stored as four bytes per pixel. @@ -487,33 +472,24 @@ static void swizzle_cmyk_to_565( } } -/** - 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; +template <SkSwizzler::RowProc proc> +void 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); + + auto src32 = (const uint32_t*)(src+offset); + auto dst32 = (uint32_t*)dstRow; + + // This may miss opportunities to skip when the output is premultiplied, + // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication. + while (dstWidth > 0 && *src32 == 0x00000000) { + dstWidth--; + dst32++; + src32 += deltaSrc/4; } - return alphaMask != 0xFF; + proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable); } -*/ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, const SkPMColor* ctable, @@ -649,11 +625,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; } |