Index: src/codec/SkSwizzler.cpp |
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp |
index c9bdb50d100c99a634c0798acf935c90c2041a99..74d6c7f87fce8fea08e61ab33099a9d72e759a54 100644 |
--- a/src/codec/SkSwizzler.cpp |
+++ b/src/codec/SkSwizzler.cpp |
@@ -7,6 +7,7 @@ |
#include "SkCodecPriv.h" |
#include "SkColorPriv.h" |
+#include "SkOpts.h" |
#include "SkSwizzler.h" |
#include "SkTemplates.h" |
@@ -367,7 +368,6 @@ static void swizzle_rgbx_to_565( |
} |
} |
- |
// kRGBA |
static void swizzle_rgba_to_n32_premul( |
void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
@@ -382,6 +382,21 @@ static void swizzle_rgba_to_n32_premul( |
} |
} |
+static void fast_swizzle_rgba_to_n32_premul( |
+ void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, |
+ int offset, const SkPMColor ctable[]) { |
+ |
+ // This function must not be called if we are sampling. If we are not |
+ // sampling, deltaSrc should equal bpp. |
+ SkASSERT(deltaSrc == bpp); |
+ |
+#ifdef SK_PMCOLOR_IS_RGBA |
+ SkOpts::premul_xxxa((uint32_t*) dst, (const uint32_t*) (src + offset), width); |
+#else |
+ SkOpts::premul_swaprb_xxxa((uint32_t*) dst, (const uint32_t*) (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[]) { |
@@ -503,6 +518,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
&& nullptr == ctable) { |
return nullptr; |
} |
+ RowProc fastProc = nullptr; |
RowProc proc = nullptr; |
SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized; |
switch (sc) { |
@@ -610,7 +626,6 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
} |
break; |
case kRGBX: |
- // TODO: Support other swizzles. |
switch (dstInfo.colorType()) { |
case kN32_SkColorType: |
proc = &swizzle_rgbx_to_n32; |
@@ -633,8 +648,10 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
} else { |
if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_premul>; |
+ fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_premul>; |
} else { |
proc = &swizzle_rgba_to_n32_premul; |
+ fastProc = &fast_swizzle_rgba_to_n32_premul; |
} |
} |
break; |
@@ -675,9 +692,6 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
default: |
break; |
} |
- if (nullptr == proc) { |
- return nullptr; |
- } |
// Store bpp in bytes if it is an even multiple, otherwise use bits |
int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc); |
@@ -699,12 +713,14 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
srcWidth = frame->width(); |
} |
- return new SkSwizzler(proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth, srcBPP, dstBPP); |
+ return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth, |
+ srcBPP, dstBPP); |
} |
-SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcOffset, int srcWidth, |
- int dstOffset, int dstWidth, int srcBPP, int dstBPP) |
- : fRowProc(proc) |
+SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset, |
+ int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP) |
+ : fFastProc(fastProc) |
+ , fProc(proc) |
, fColorTable(ctable) |
, fSrcOffset(srcOffset) |
, fDstOffset(dstOffset) |
@@ -728,11 +744,15 @@ 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. |
+ fFastProc = nullptr; |
+ |
return fAllocatedWidth; |
} |
void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { |
SkASSERT(nullptr != dst && nullptr != src); |
- fRowProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP, |
+ RowProc proc = fFastProc ? fFastProc : fProc; |
+ proc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP, |
fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable); |
} |