aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec/SkSwizzler.cpp
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2016-01-11 13:13:55 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-01-11 13:13:55 -0800
commit8604ca2d84cfa9527705c69d74a8449b532e0ee4 (patch)
tree44330c408f38205f98be442555f8a5dea0d66c20 /src/codec/SkSwizzler.cpp
parentc7141eb8fba41f1e098499ef17d0bc79641d54c5 (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.cpp65
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;
}