aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec/SkSwizzler.cpp
diff options
context:
space:
mode:
authorGravatar msarett <msarett@google.com>2016-02-03 10:44:46 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-03 10:44:46 -0800
commit93e613d6bdea05d96e232ed261d7bf886c91bb8e (patch)
tree49ced33d7bb5e27f03b95af6bb4a5c9405fda854 /src/codec/SkSwizzler.cpp
parent65dfd2fe5d93d63b655663707c7233917e293acc (diff)
Handle gray alpha conversions in SkSwizzler
Nothing fancy here. By doing the entire conversion ourselves, we only need to make one conversion pass over each row. Additionally, we optimize the premultiply since we know each color component of the pixel is identical. This will also enable us to follow up with platform specific optimizations. PNG Decode Time Nexus 6P (for a test set of GrayAlpha encoded PNGs) Regular Unpremul 0.95x Zero Init Unpremul 0.94x Regular Premul 0.91x Zero Init Premul 0.90x BUG=skia:4767 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1665583002 Review URL: https://codereview.chromium.org/1665583002
Diffstat (limited to 'src/codec/SkSwizzler.cpp')
-rw-r--r--src/codec/SkSwizzler.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp
index fa93a6e928..ce6dd26093 100644
--- a/src/codec/SkSwizzler.cpp
+++ b/src/codec/SkSwizzler.cpp
@@ -295,6 +295,33 @@ static void swizzle_gray_to_565(
}
}
+// kGrayAlpha
+
+static void swizzle_grayalpha_to_n32_unpremul(
+ void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
+ const SkPMColor ctable[]) {
+
+ src += offset;
+ SkPMColor* dst32 = (SkPMColor*) dst;
+ for (int x = 0; x < width; x++) {
+ dst32[x] = SkPackARGB32NoCheck(src[1], src[0], src[0], src[0]);
+ src += deltaSrc;
+ }
+}
+
+static void swizzle_grayalpha_to_n32_premul(
+ void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
+ const SkPMColor ctable[]) {
+
+ src += offset;
+ SkPMColor* dst32 = (SkPMColor*) dst;
+ for (int x = 0; x < width; x++) {
+ uint8_t pmgray = SkMulDiv255Round(src[1], src[0]);
+ dst32[x] = SkPackARGB32NoCheck(src[1], pmgray, pmgray, pmgray);
+ src += deltaSrc;
+ }
+}
+
// kBGRX
static void swizzle_bgrx_to_n32(
@@ -556,6 +583,25 @@ static void swizzle_cmyk_to_565(
}
template <SkSwizzler::RowProc proc>
+void SkSwizzler::SkipLeadingGrayAlphaZerosThen(
+ void* dst, const uint8_t* src, int width,
+ int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
+ SkASSERT(!ctable);
+
+ const uint16_t* src16 = (const uint16_t*) (src + offset);
+ uint32_t* dst32 = (uint32_t*) dst;
+
+ // This may miss opportunities to skip when the output is premultiplied,
+ // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
+ while (width > 0 && *src16 == 0x0000) {
+ width--;
+ dst32++;
+ src16 += deltaSrc / 2;
+ }
+ proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
+}
+
+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[]) {
@@ -665,6 +711,28 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
break;
}
break;
+ case kGrayAlpha:
+ switch (dstInfo.colorType()) {
+ case kN32_SkColorType:
+ if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
+ if (SkCodec::kYes_ZeroInitialized == zeroInit) {
+ proc = &SkipLeadingGrayAlphaZerosThen
+ <swizzle_grayalpha_to_n32_unpremul>;
+ } else {
+ proc = &swizzle_grayalpha_to_n32_unpremul;
+ }
+ } else {
+ if (SkCodec::kYes_ZeroInitialized == zeroInit) {
+ proc = &SkipLeadingGrayAlphaZerosThen<swizzle_grayalpha_to_n32_premul>;
+ } else {
+ proc = &swizzle_grayalpha_to_n32_premul;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
case kBGR:
case kBGRX:
switch (dstInfo.colorType()) {