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