Use SkRasterPipeline to blend GIF frames and use proper offset
Mimics SkWebpCodec, but it is simpler, because each pixel is either
opaque or transparent, so blending just means using the new pixel if not
transparent.
Correct the offset when blending f16 frames. It needs to be doubled,
since the swizzler used a 4-byte format while f16 is 8-byte.
Remove an unnecessary call to sk_bzero.
Bug: skia:6750
Change-Id: I8b88d1d66bff660c98c2083031231678a7be5460
Reviewed-on: https://skia-review.googlesource.com/24240
Commit-Queue: Leon Scroggins <scroggo@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp
index 879297d..9b3d4b5 100644
--- a/src/codec/SkGifCodec.cpp
+++ b/src/codec/SkGifCodec.cpp
@@ -35,6 +35,7 @@
#include "SkColorPriv.h"
#include "SkColorTable.h"
#include "SkGifCodec.h"
+#include "SkRasterPipeline.h"
#include "SkStream.h"
#include "SkSwizzler.h"
@@ -508,43 +509,38 @@
if (writeTransparentPixels) {
this->applyXformRow(dstInfo, dstLine, rowBegin);
} else {
- sk_bzero(fTmpBuffer.get(), dstInfo.minRowBytes());
this->applyXformRow(dstInfo, fTmpBuffer.get(), rowBegin);
- const size_t offsetBytes = fSwizzler->swizzleOffsetBytes();
+ size_t offsetBytes = fSwizzler->swizzleOffsetBytes();
+ if (dstInfo.colorType() == kRGBA_F16_SkColorType) {
+ // Account for the fact that post-swizzling we converted to F16,
+ // which is twice as wide.
+ offsetBytes *= 2;
+ }
+ SkRasterPipeline_<256> p;
+ SkRasterPipeline::StockStage storeDst;
+ void* src = SkTAddOffset<void>(fTmpBuffer.get(), offsetBytes);
+ void* dst = SkTAddOffset<void>(dstLine, offsetBytes);
switch (dstInfo.colorType()) {
case kBGRA_8888_SkColorType:
- case kRGBA_8888_SkColorType: {
- uint32_t* dstPixel = SkTAddOffset<uint32_t>(dstLine, offsetBytes);
- uint32_t* srcPixel = SkTAddOffset<uint32_t>(fTmpBuffer.get(), offsetBytes);
- for (int i = 0; i < fSwizzler->swizzleWidth(); i++) {
- // Technically SK_ColorTRANSPARENT is an SkPMColor, and srcPixel would have
- // the opposite swizzle for the non-native swizzle, but TRANSPARENT is all
- // zeroes, which is the same either way.
- if (*srcPixel != SK_ColorTRANSPARENT) {
- *dstPixel = *srcPixel;
- }
- dstPixel++;
- srcPixel++;
- }
+ case kRGBA_8888_SkColorType:
+ p.append(SkRasterPipeline::load_8888_dst, &dst);
+ p.append(SkRasterPipeline::load_8888, &src);
+ storeDst = SkRasterPipeline::store_8888;
break;
- }
- case kRGBA_F16_SkColorType: {
- uint64_t* dstPixel = SkTAddOffset<uint64_t>(dstLine, offsetBytes);
- uint64_t* srcPixel = SkTAddOffset<uint64_t>(fTmpBuffer.get(), offsetBytes);
- for (int i = 0; i < fSwizzler->swizzleWidth(); i++) {
- if (*srcPixel != 0) {
- *dstPixel = *srcPixel;
- }
- dstPixel++;
- srcPixel++;
- }
+ case kRGBA_F16_SkColorType:
+ p.append(SkRasterPipeline::load_f16_dst, &dst);
+ p.append(SkRasterPipeline::load_f16, &src);
+ storeDst = SkRasterPipeline::store_f16;
break;
- }
default:
SkASSERT(false);
+ return false;
break;
}
+ p.append(SkRasterPipeline::srcover);
+ p.append(storeDst, &dst);
+ p.run(0, 0, fSwizzler->swizzleWidth());
}
// Tell the frame to copy the row data if need be.