aboutsummaryrefslogtreecommitdiffhomepage
path: root/dm
diff options
context:
space:
mode:
authorGravatar Leon Scroggins III <scroggo@google.com>2017-05-23 09:37:21 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-23 15:28:37 +0000
commit557fbbe05ba48bcc20be684d11fe0edfc24c87ba (patch)
treede83760e6e67a0866578056b4091091cef29cc53 /dm
parente980174d0f3af8e497d9c38851114cc6a3c02e9a (diff)
Add animation support to SkWebpCodec
TBR=reed@google.com (No change to the public API, but changed a header file) SkWebpCodec: - Implement onGetFrameCount, onGetFrameInfo, and onGetRepetitionCount - Respect the alpha reported by libwebp. Although the spec states that it is only a hint, the libwebp encoder uses it properly. Respecting allows us to draw opaque images faster and decode them to 565. This also matches other SkCodecs (and Chromium). - onGetPixels: - Decode the frame requested, recursively decoding required frame if necessary - When blending with a prior frame, use SkRasterPipeline SkCodec: - Move check for negative index to getFrameInfo - Reset the colorXform if one is not needed SkCodecAnimation: - Add new blend enum, for WebP's (and APNG's) non-blending option SkFrameHolder: - New base classes for frames and the owner of the frames, allowing code sharing between SkWebpCodec and SkGifCodec (particularly for determining whether a frame has alpha and what frame it depends on) - When moving items from SkGIFFrameContext, use Skia conventions (i.e. int instead of unsigned) - Rename "delay time" to "duration", to match e.g. SkFrameInfo:: fDuration SkGifImageReader: - Move pieces to SkFrameHolder, and adapt to changes made in the process - Make setAlphaAndRequiredFrame (now on the base class SkFrameHolder) more general to support webp, and add support for frames that do not blend - Change SkGIFFrameContext from a struct to a class, to match how we use the distinction elsewhere (i.e. struct is a small object with public fields) - Rework hasTransparentPixel (now hasTransparency, since it returns true in some cases where there is not a transparent pixel) to better fit with the modified setAlphaAndRequiredFrame. Also be more consistent when there is no transparent pixel but no color map. - Simplify an if condition that was previously simplified in 2d61e717 but accidentally got reverted in a4db9be6 CodecAnimTest: - Test new animated webp files - Rearrange the test to more cleanly print alpha type mismatches for the first frame resources: - webp-animated.webp - animated webp from Chromium - blendBG.webp - new webp file using bits of webp-animated-semitransparent4.webp from Chromium - tests required frame and alpha when using the non-blending mode - frames have the following properties: - Frame 0: no alpha, fills screen - Frame 1: alpha, fills screen - Frame 2: no alpha, fills screen - Frame 3: alpha, fills screen, blendBG - Frame 4: no alpha, fills screen, blendBG - Frame 5: alpha, blendBG - Frame 6: covers 4, has alpha, blendBG - also used to test decoding to 565 if the new frame data has alpha but blends onto an opaque frame DM.cpp: - Test animated images to non-native 8888 and unpremul DMSrcSink.cpp: - Do not test non-native 8888 decodes to f16 dst - Test unpremul decodes to f16 - Copy a frame of an animated image prior to drawing, since in unpremul mode, the DM code will premultiply first. Bug: skia: 3315 Change-Id: I4e55ae2ee5bc095b37a743bdcfac644be603b980 Reviewed-on: https://skia-review.googlesource.com/16707 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Leon Scroggins <scroggo@google.com> Reviewed-by: Matt Sarett <msarett@google.com>
Diffstat (limited to 'dm')
-rw-r--r--dm/DM.cpp8
-rw-r--r--dm/DMSrcSink.cpp28
2 files changed, 20 insertions, 16 deletions
diff --git a/dm/DM.cpp b/dm/DM.cpp
index aa2b081fb1..2f7dd21e34 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -603,8 +603,12 @@ static void push_codec_srcs(Path path) {
{
std::vector<SkCodec::FrameInfo> frameInfos = codec->getFrameInfo();
if (frameInfos.size() > 1) {
- push_codec_src(path, CodecSrc::kAnimated_Mode, CodecSrc::kGetFromCanvas_DstColorType,
- kPremul_SkAlphaType, 1.0f);
+ for (auto dstCT : { CodecSrc::kNonNative8888_Always_DstColorType,
+ CodecSrc::kGetFromCanvas_DstColorType }) {
+ for (auto at : { kUnpremul_SkAlphaType, kPremul_SkAlphaType }) {
+ push_codec_src(path, CodecSrc::kAnimated_Mode, dstCT, at, 1.0f);
+ }
+ }
}
}
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 752ab2e4ae..8979d2d285 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -364,7 +364,8 @@ static bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType
*decodeInfo = decodeInfo->makeColorType(kGray_8_SkColorType);
break;
case CodecSrc::kNonNative8888_Always_DstColorType:
- if (kRGB_565_SkColorType == canvasColorType) {
+ if (kRGB_565_SkColorType == canvasColorType
+ || kRGBA_F16_SkColorType == canvasColorType) {
return false;
}
#ifdef SK_PMCOLOR_IS_RGBA
@@ -380,11 +381,6 @@ static bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType
}
if (kRGBA_F16_SkColorType == canvasColorType) {
- if (kUnpremul_SkAlphaType == dstAlphaType) {
- // Testing kPremul is enough for adequate coverage of F16 decoding.
- return false;
- }
-
sk_sp<SkColorSpace> linearSpace =
as_CSB(decodeInfo->colorSpace())->makeLinearGamma();
*decodeInfo = decodeInfo->makeColorSpace(std::move(linearSpace));
@@ -499,6 +495,18 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
switch (result) {
case SkCodec::kSuccess:
case SkCodec::kIncompleteInput: {
+ // If the next frame depends on this one, store it in priorFrame.
+ // It is possible that we may discard a frame that future frames depend on,
+ // but the codec will simply redecode the discarded frame.
+ // Do this before calling draw_to_canvas, which premultiplies in place. If
+ // we're decoding to unpremul, we want to pass the unmodified frame to the
+ // codec for decoding the next frame.
+ if (static_cast<size_t>(i+1) < frameInfos.size()
+ && frameInfos[i+1].fRequiredFrame == i) {
+ memcpy(priorFramePixels.reset(safeSize), pixels.get(), safeSize);
+ cachedFrame = i;
+ }
+
SkAutoCanvasRestore acr(canvas, true);
const int xTranslate = (i % factor) * decodeInfo.width();
const int yTranslate = (i / factor) * decodeInfo.height();
@@ -521,14 +529,6 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
return SkStringPrintf("Couldn't getPixels for frame %i in %s.",
i, fPath.c_str());
}
-
- // If a future frame depends on this one, store it in priorFrame.
- // (Note that if i+1 does *not* depend on i, then no future frame can.)
- if (static_cast<size_t>(i+1) < frameInfos.size()
- && frameInfos[i+1].fRequiredFrame == i) {
- memcpy(priorFramePixels.reset(safeSize), pixels.get(), safeSize);
- cachedFrame = i;
- }
}
break;
}