Bug 1291045 (Part 7) - Replace DecodingTask with DecodedSurfaceProvider. r=dholbert,edwin

This commit is contained in:
Seth Fowler 2016-08-05 15:18:52 -07:00
Родитель 1cd0225e12
Коммит f5495f0fd1
4 изменённых файлов: 13 добавлений и 131 удалений

Просмотреть файл

@ -249,14 +249,6 @@ public:
*/
bool WasAborted() const { return mDecodeAborted; }
/**
* Mark this decoder as aborted.
*
* XXX(seth): This is a temporary method which just exists to allow this patch
* series to be split into smaller patches. It'll be removed in a later patch.
*/
void Abort() { mDecodeAborted = true; }
enum DecodeStyle {
PROGRESSIVE, // produce intermediate frames representing the partial
// state of the image

Просмотреть файл

@ -119,7 +119,7 @@ DecoderFactory::CreateDecoder(DecoderType aType,
}
// Create an anonymous decoder. Interaction with the SurfaceCache and the
// owning RasterImage will be mediated by DecodingTask.
// owning RasterImage will be mediated by DecodedSurfaceProvider.
RefPtr<Decoder> decoder =
GetDecoder(aType, nullptr, bool(aDecoderFlags & DecoderFlags::IS_REDECODE));
MOZ_ASSERT(decoder, "Should have a decoder now");
@ -136,17 +136,25 @@ DecoderFactory::CreateDecoder(DecoderType aType,
return nullptr;
}
// Add a placeholder to the SurfaceCache so we won't trigger any more decoders
// with the same parameters.
// 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);
NotNull<RefPtr<DecodedSurfaceProvider>> provider =
WrapNotNull(new DecodedSurfaceProvider(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 DecodingTask(aImage, WrapNotNull(decoder));
// Return the surface provider in its IDecodingTask guise.
RefPtr<IDecodingTask> task = provider.get();
return task.forget();
}

Просмотреть файл

@ -6,7 +6,6 @@
#include "IDecodingTask.h"
#include "gfxPrefs.h"
#include "nsProxyRelease.h"
#include "nsThreadUtils.h"
#include "Decoder.h"
@ -88,96 +87,6 @@ IDecodingTask::Resume()
}
///////////////////////////////////////////////////////////////////////////////
// DecodingTask implementation.
///////////////////////////////////////////////////////////////////////////////
DecodingTask::DecodingTask(NotNull<RasterImage*> aImage,
NotNull<Decoder*> aDecoder)
: mImage(aImage)
, mDecoder(aDecoder)
{
MOZ_ASSERT(!mDecoder->IsMetadataDecode(),
"Use MetadataDecodingTask for metadata decodes");
MOZ_ASSERT(mDecoder->IsFirstFrameDecode(),
"Use AnimationDecodingTask for animation decodes");
}
DecodingTask::~DecodingTask()
{
// RasterImage objects need to be destroyed on the main thread.
RefPtr<RasterImage> image = mImage;
NS_ReleaseOnMainThread(image.forget());
}
void
DecodingTask::Run()
{
LexerResult result = mDecoder->Decode(WrapNotNull(this));
// If the decoder hadn't produced a surface up to this point, see if a surface
// is now available.
if (!mSurface) {
mSurface = mDecoder->GetCurrentFrameRef().get();
if (mSurface) {
// There's a new surface available; insert it into the SurfaceCache.
NotNull<RefPtr<ISurfaceProvider>> provider =
WrapNotNull(new SimpleSurfaceProvider(WrapNotNull(mSurface.get())));
InsertOutcome outcome =
SurfaceCache::Insert(provider, ImageKey(mImage.get()),
RasterSurfaceKey(mDecoder->OutputSize(),
mDecoder->GetSurfaceFlags(),
/* aFrameNum = */ 0));
if (outcome == InsertOutcome::FAILURE) {
// We couldn't insert the surface, almost certainly due to low memory. We
// treat this as a permanent error to help the system recover; otherwise,
// we might just end up attempting to decode this image again immediately.
result = mDecoder->TerminateFailure();
} else if (outcome == InsertOutcome::FAILURE_ALREADY_PRESENT) {
// Another decoder beat us to decoding this frame. We abort this decoder
// rather than treat this as a real error.
mDecoder->Abort();
result = mDecoder->TerminateFailure();
}
}
}
MOZ_ASSERT(mSurface.get() == mDecoder->GetCurrentFrameRef().get(),
"DecodingTask and Decoder have different surfaces?");
if (result.is<TerminalState>()) {
NotifyDecodeComplete(mImage, mDecoder);
return; // We're done.
}
MOZ_ASSERT(result.is<Yield>());
// Notify for the progress we've made so far.
if (mDecoder->HasProgress()) {
NotifyProgress(mImage, mDecoder);
}
if (result == LexerResult(Yield::NEED_MORE_DATA)) {
// We can't make any more progress right now. The decoder itself will ensure
// that we get reenqueued when more data is available; just return for now.
return;
}
// Other kinds of yields shouldn't happen during single-frame image decodes.
MOZ_ASSERT_UNREACHABLE("Unexpected yield during single-frame image decode");
mDecoder->TerminateFailure();
NotifyDecodeComplete(mImage, mDecoder);
}
bool
DecodingTask::ShouldPreferSyncRun() const
{
return mDecoder->ShouldSyncDecode(gfxPrefs::ImageMemDecodeBytesAtATime());
}
///////////////////////////////////////////////////////////////////////////////
// AnimationDecodingTask implementation.
///////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -62,33 +62,6 @@ protected:
};
/**
* An IDecodingTask implementation for full decodes of single frame images.
*/
class DecodingTask final : public IDecodingTask
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecodingTask, override)
DecodingTask(NotNull<RasterImage*> aImage,
NotNull<Decoder*> aDecoder);
void Run() override;
bool ShouldPreferSyncRun() const override;
// Full decodes are low priority compared to metadata decodes because they
// don't block layout or page load.
TaskPriority Priority() const override { return TaskPriority::eLow; }
private:
virtual ~DecodingTask();
NotNull<RefPtr<RasterImage>> mImage;
NotNull<RefPtr<Decoder>> mDecoder;
RefPtr<imgFrame> mSurface;
};
/**
* An IDecodingTask implementation for full decodes of animated images.
*/