Bug 1293472 (Part 3) - Store animated images in the surface cache as a sequence of frames, rather than each frame getting its own cache entry. r=dholbert,edwin,njn

This commit is contained in:
Seth Fowler
2016-08-18 00:06:41 -07:00
parent f00dc2d228
commit ed50277add
21 changed files with 308 additions and 301 deletions

View File

@@ -8,6 +8,7 @@
#include "nsMimeTypes.h"
#include "mozilla/RefPtr.h"
#include "AnimationSurfaceProvider.h"
#include "Decoder.h"
#include "IDecodingTask.h"
#include "nsPNGDecoder.h"
@@ -141,7 +142,7 @@ DecoderFactory::CreateDecoder(DecoderType aType,
// Create a DecodedSurfaceProvider which will manage the decoding process and
// make this decoder's output available in the surface cache.
SurfaceKey surfaceKey =
RasterSurfaceKey(aOutputSize, aSurfaceFlags, /* aFrameNum = */ 0);
RasterSurfaceKey(aOutputSize, aSurfaceFlags, PlaybackType::eStatic);
NotNull<RefPtr<DecodedSurfaceProvider>> provider =
WrapNotNull(new DecodedSurfaceProvider(aImage,
WrapNotNull(decoder),
@@ -175,8 +176,9 @@ DecoderFactory::CreateAnimationDecoder(DecoderType aType,
MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG,
"Calling CreateAnimationDecoder for non-animating DecoderType");
RefPtr<Decoder> decoder =
GetDecoder(aType, aImage, /* aIsRedecode = */ true);
// Create an anonymous decoder. Interaction with the SurfaceCache and the
// owning RasterImage will be mediated by AnimationSurfaceProvider.
RefPtr<Decoder> decoder = GetDecoder(aType, nullptr, /* aIsRedecode = */ true);
MOZ_ASSERT(decoder, "Should have a decoder now");
// Initialize the decoder.
@@ -189,17 +191,25 @@ DecoderFactory::CreateAnimationDecoder(DecoderType aType,
return nullptr;
}
// Add a placeholder for the first frame to the SurfaceCache so we won't
// trigger any more decoders with the same parameters.
// Create an AnimationSurfaceProvider which will manage the decoding process
// and make this decoder's output available in the surface cache.
SurfaceKey surfaceKey =
RasterSurfaceKey(aIntrinsicSize, aSurfaceFlags, /* aFrameNum = */ 0);
RasterSurfaceKey(aIntrinsicSize, aSurfaceFlags, PlaybackType::eAnimated);
NotNull<RefPtr<AnimationSurfaceProvider>> provider =
WrapNotNull(new AnimationSurfaceProvider(aImage,
WrapNotNull(decoder),
surfaceKey));
// Attempt to insert the surface provider into the surface cache right away so
// we won't trigger any more decoders with the same parameters.
InsertOutcome outcome =
SurfaceCache::InsertPlaceholder(ImageKey(aImage.get()), surfaceKey);
SurfaceCache::Insert(provider, ImageKey(aImage.get()), surfaceKey);
if (outcome != InsertOutcome::SUCCESS) {
return nullptr;
}
RefPtr<IDecodingTask> task = new AnimationDecodingTask(WrapNotNull(decoder));
// Return the surface provider in its IDecodingTask guise.
RefPtr<IDecodingTask> task = provider.get();
return task.forget();
}