Index: src/codec/SkSwizzler.cpp |
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp |
index f9f212072e53e4bb2565e87aadb6fdff0213c1e6..36c3e684eb82a9cd0c8c4e5f31f4e7bcdeae808b 100644 |
--- a/src/codec/SkSwizzler.cpp |
+++ b/src/codec/SkSwizzler.cpp |
@@ -20,7 +20,7 @@ static void copy(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc |
memcpy(dst, src + offset, width * bpp); |
} |
-static void sample1(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, |
+static void sample_1bpp(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, |
const SkPMColor ctable[]) { |
src += offset; |
uint8_t* dst8 = (uint8_t*) dst; |
@@ -30,7 +30,7 @@ static void sample1(void* dst, const uint8_t* src, int width, int bpp, int delta |
} |
} |
-static void sample2(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, |
+static void sample_2bpp(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, |
const SkPMColor ctable[]) { |
src += offset; |
uint16_t* dst16 = (uint16_t*) dst; |
@@ -40,7 +40,7 @@ static void sample2(void* dst, const uint8_t* src, int width, int bpp, int delta |
} |
} |
-static void sample4(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, |
+static void sample_4bpp(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, |
const SkPMColor ctable[]) { |
src += offset; |
uint32_t* dst32 = (uint32_t*) dst; |
@@ -503,6 +503,48 @@ static void fast_swizzle_rgba_to_n32_premul( |
#endif |
} |
+static void fast_sample2_rgba_to_n32_premul( |
+ void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, |
+ int offset, const SkPMColor ctable[]) { |
+ |
+ // This function should only be called if the sampleSize is 2. |
+ SkASSERT(deltaSrc == 2*bpp); |
+ |
+#ifdef SK_PMCOLOR_IS_RGBA |
+ SkOpts::RGBA_to_rgbA_sample2((uint32_t*) dst, src + offset, width); |
+#else |
+ SkOpts::RGBA_to_bgrA_sample2((uint32_t*) dst, src + offset, width); |
+#endif |
+} |
+ |
+static void fast_sample4_rgba_to_n32_premul( |
+ void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, |
+ int offset, const SkPMColor ctable[]) { |
+ |
+ // This function should only be called if the sampleSize is 4. |
+ SkASSERT(deltaSrc == 4*bpp); |
+ |
+#ifdef SK_PMCOLOR_IS_RGBA |
+ SkOpts::RGBA_to_rgbA_sample4((uint32_t*) dst, src + offset, width); |
+#else |
+ SkOpts::RGBA_to_bgrA_sample4((uint32_t*) dst, src + offset, width); |
+#endif |
+} |
+ |
+static void fast_sample8_rgba_to_n32_premul( |
+ void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, |
+ int offset, const SkPMColor ctable[]) { |
+ |
+ // This function should only be called if the sampleSize is 8. |
+ SkASSERT(deltaSrc == 8*bpp); |
+ |
+#ifdef SK_PMCOLOR_IS_RGBA |
+ SkOpts::RGBA_to_rgbA_sample8((uint32_t*) dst, src + offset, width); |
+#else |
+ SkOpts::RGBA_to_bgrA_sample8((uint32_t*) dst, src + offset, width); |
+#endif |
+} |
+ |
static void swizzle_rgba_to_n32_unpremul( |
void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { |
@@ -673,8 +715,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
&& nullptr == ctable) { |
return nullptr; |
} |
- RowProc fastProc = nullptr; |
+ |
RowProc proc = nullptr; |
+ FastProcs fastProcs; |
SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized; |
switch (sc) { |
case kBit: |
@@ -728,8 +771,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
proc = &swizzle_index_to_565; |
break; |
case kIndex_8_SkColorType: |
- proc = &sample1; |
- fastProc = © |
+ proc = &sample_1bpp; |
+ fastProcs.fSampleSize1 = © |
break; |
default: |
break; |
@@ -739,11 +782,11 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_gray_to_n32; |
- fastProc = &fast_swizzle_gray_to_n32; |
+ fastProcs.fSampleSize1 = &fast_swizzle_gray_to_n32; |
break; |
case kGray_8_SkColorType: |
- proc = &sample1; |
- fastProc = © |
+ proc = &sample_1bpp; |
+ fastProcs.fSampleSize1 = © |
break; |
case kRGB_565_SkColorType: |
proc = &swizzle_gray_to_565; |
@@ -759,20 +802,20 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
proc = &SkipLeadingGrayAlphaZerosThen |
<swizzle_grayalpha_to_n32_unpremul>; |
- fastProc = &SkipLeadingGrayAlphaZerosThen |
+ fastProcs.fSampleSize1 = &SkipLeadingGrayAlphaZerosThen |
<fast_swizzle_grayalpha_to_n32_unpremul>; |
} else { |
proc = &swizzle_grayalpha_to_n32_unpremul; |
- fastProc = &fast_swizzle_grayalpha_to_n32_unpremul; |
+ fastProcs.fSampleSize1 = &fast_swizzle_grayalpha_to_n32_unpremul; |
} |
} else { |
if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
proc = &SkipLeadingGrayAlphaZerosThen<swizzle_grayalpha_to_n32_premul>; |
- fastProc = &SkipLeadingGrayAlphaZerosThen |
+ fastProcs.fSampleSize1 = &SkipLeadingGrayAlphaZerosThen |
<fast_swizzle_grayalpha_to_n32_premul>; |
} else { |
proc = &swizzle_grayalpha_to_n32_premul; |
- fastProc = &fast_swizzle_grayalpha_to_n32_premul; |
+ fastProcs.fSampleSize1 = &fast_swizzle_grayalpha_to_n32_premul; |
} |
} |
break; |
@@ -799,18 +842,20 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { |
if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_unpremul>; |
- fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_unpremul>; |
+ fastProcs.fSampleSize1 = &SkipLeading8888ZerosThen |
+ <fast_swizzle_bgra_to_n32_unpremul>; |
} else { |
proc = &swizzle_bgra_to_n32_unpremul; |
- fastProc = &fast_swizzle_bgra_to_n32_unpremul; |
+ fastProcs.fSampleSize1 = &fast_swizzle_bgra_to_n32_unpremul; |
} |
} else { |
if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_premul>; |
- fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_premul>; |
+ fastProcs.fSampleSize1 = &SkipLeading8888ZerosThen |
+ <fast_swizzle_bgra_to_n32_premul>; |
} else { |
proc = &swizzle_bgra_to_n32_premul; |
- fastProc = &fast_swizzle_bgra_to_n32_premul; |
+ fastProcs.fSampleSize1 = &fast_swizzle_bgra_to_n32_premul; |
} |
} |
break; |
@@ -822,7 +867,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_rgb_to_n32; |
- fastProc = &fast_swizzle_rgb_to_n32; |
+ fastProcs.fSampleSize1 = &fast_swizzle_rgb_to_n32; |
break; |
case kRGB_565_SkColorType: |
proc = &swizzle_rgb_to_565; |
@@ -837,18 +882,29 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { |
if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>; |
- fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_unpremul>; |
+ fastProcs.fSampleSize1 = &SkipLeading8888ZerosThen |
+ <fast_swizzle_rgba_to_n32_unpremul>; |
} else { |
proc = &swizzle_rgba_to_n32_unpremul; |
- fastProc = &fast_swizzle_rgba_to_n32_unpremul; |
+ fastProcs.fSampleSize1 = &fast_swizzle_rgba_to_n32_unpremul; |
} |
} else { |
if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_premul>; |
- fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_premul>; |
+ fastProcs.fSampleSize1 = &SkipLeading8888ZerosThen |
+ <fast_swizzle_rgba_to_n32_premul>; |
+ fastProcs.fSampleSize2 = &SkipLeading8888ZerosThen |
+ <fast_sample2_rgba_to_n32_premul>; |
+ fastProcs.fSampleSize4 = &SkipLeading8888ZerosThen |
+ <fast_sample4_rgba_to_n32_premul>; |
+ fastProcs.fSampleSize8 = &SkipLeading8888ZerosThen |
+ <fast_sample8_rgba_to_n32_premul>; |
} else { |
proc = &swizzle_rgba_to_n32_premul; |
- fastProc = &fast_swizzle_rgba_to_n32_premul; |
+ fastProcs.fSampleSize1 = &fast_swizzle_rgba_to_n32_premul; |
+ fastProcs.fSampleSize2 = &fast_sample2_rgba_to_n32_premul; |
+ fastProcs.fSampleSize4 = &fast_sample4_rgba_to_n32_premul; |
+ fastProcs.fSampleSize8 = &fast_sample8_rgba_to_n32_premul; |
} |
} |
break; |
@@ -860,7 +916,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_cmyk_to_n32; |
- fastProc = &fast_swizzle_cmyk_to_n32; |
+ fastProcs.fSampleSize1 = &fast_swizzle_cmyk_to_n32; |
break; |
case kRGB_565_SkColorType: |
proc = &swizzle_cmyk_to_565; |
@@ -870,16 +926,16 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
} |
break; |
case kNoOp8: |
- proc = &sample1; |
- fastProc = © |
+ proc = &sample_1bpp; |
+ fastProcs.fSampleSize1 = © |
break; |
case kNoOp16: |
- proc = sample2; |
- fastProc = © |
+ proc = sample_2bpp; |
+ fastProcs.fSampleSize1 = © |
break; |
case kNoOp32: |
- proc = &sample4; |
- fastProc = © |
+ proc = &sample_4bpp; |
+ fastProcs.fSampleSize1 = © |
break; |
default: |
break; |
@@ -905,15 +961,15 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
srcWidth = frame->width(); |
} |
- return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth, |
+ return new SkSwizzler(proc, fastProcs, ctable, srcOffset, srcWidth, dstOffset, dstWidth, |
srcBPP, dstBPP); |
} |
-SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset, |
- int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP) |
- : fFastProc(fastProc) |
- , fSlowProc(proc) |
- , fActualProc(fFastProc ? fFastProc : fSlowProc) |
+SkSwizzler::SkSwizzler(RowProc proc, const FastProcs& fastProcs, const SkPMColor* ctable, |
+ int srcOffset, int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP) |
+ : fSlowProc(proc) |
+ , fFastProcs(fastProcs) |
+ , fActualProc(fFastProcs.fSampleSize1 ? fFastProcs.fSampleSize1 : fSlowProc) |
, fColorTable(ctable) |
, fSrcOffset(srcOffset) |
, fDstOffset(dstOffset) |
@@ -937,10 +993,27 @@ int SkSwizzler::onSetSampleX(int sampleX) { |
fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX); |
fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX); |
- // The optimized swizzler routines do not (yet) support sampling. |
- if (1 == fSampleX && fFastProc) { |
- fActualProc = fFastProc; |
- } else { |
+ // Choose an optimized swizzler function (if it exists). |
+ fActualProc = nullptr; |
+ switch (fSampleX) { |
+ case 1: |
+ fActualProc = fFastProcs.fSampleSize1; |
+ break; |
+ case 2: |
+ fActualProc = fFastProcs.fSampleSize2; |
+ break; |
+ case 4: |
+ fActualProc = fFastProcs.fSampleSize4; |
+ break; |
+ case 8: |
+ fActualProc = fFastProcs.fSampleSize8; |
+ break; |
+ default: |
+ break; |
+ } |
+ |
+ // Otherwise, use fSlowProc. |
+ if (!fActualProc) { |
fActualProc = fSlowProc; |
} |