Bug 1291045 (Part 1) - Use a different IDecodingTask for animated images. r=dholbert,edwin

This commit is contained in:
Seth Fowler
2016-08-01 17:02:16 -07:00
parent e2e1307cfa
commit 77d123ca25
3 changed files with 80 additions and 2 deletions

View File

@@ -187,7 +187,7 @@ DecoderFactory::CreateAnimationDecoder(DecoderType aType,
return nullptr;
}
RefPtr<IDecodingTask> task = new DecodingTask(WrapNotNull(decoder));
RefPtr<IDecodingTask> task = new AnimationDecodingTask(WrapNotNull(decoder));
return task.forget();
}

View File

@@ -92,6 +92,8 @@ DecodingTask::DecodingTask(NotNull<Decoder*> aDecoder)
{
MOZ_ASSERT(!mDecoder->IsMetadataDecode(),
"Use MetadataDecodingTask for metadata decodes");
MOZ_ASSERT(mDecoder->IsFirstFrameDecode(),
"Use AnimationDecodingTask for animation decodes");
}
void
@@ -131,6 +133,56 @@ DecodingTask::ShouldPreferSyncRun() const
}
///////////////////////////////////////////////////////////////////////////////
// AnimationDecodingTask implementation.
///////////////////////////////////////////////////////////////////////////////
AnimationDecodingTask::AnimationDecodingTask(NotNull<Decoder*> aDecoder)
: mDecoder(aDecoder)
{
MOZ_ASSERT(!mDecoder->IsMetadataDecode(),
"Use MetadataDecodingTask for metadata decodes");
MOZ_ASSERT(!mDecoder->IsFirstFrameDecode(),
"Use DecodingTask for single-frame image decodes");
}
void
AnimationDecodingTask::Run()
{
while (true) {
LexerResult result = mDecoder->Decode(WrapNotNull(this));
if (result.is<TerminalState>()) {
NotifyDecodeComplete(mDecoder);
return; // We're done.
}
MOZ_ASSERT(result.is<Yield>());
// Notify for the progress we've made so far.
if (mDecoder->HasProgress()) {
NotifyProgress(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;
}
// Right now we don't do anything special for other kinds of yields, so just
// keep working.
}
}
bool
AnimationDecodingTask::ShouldPreferSyncRun() const
{
return mDecoder->ShouldSyncDecode(gfxPrefs::ImageMemDecodeBytesAtATime());
}
///////////////////////////////////////////////////////////////////////////////
// MetadataDecodingTask implementation.
///////////////////////////////////////////////////////////////////////////////

View File

@@ -56,7 +56,7 @@ protected:
/**
* An IDecodingTask implementation for full decodes of images.
* An IDecodingTask implementation for full decodes of single frame images.
*/
class DecodingTask final : public IDecodingTask
{
@@ -81,6 +81,32 @@ private:
};
/**
* An IDecodingTask implementation for full decodes of animated images.
*/
class AnimationDecodingTask final : public IDecodingTask
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnimationDecodingTask, override)
explicit AnimationDecodingTask(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; }
NotNull<Decoder*> GetDecoder() const override { return mDecoder; }
private:
virtual ~AnimationDecodingTask() { }
NotNull<RefPtr<Decoder>> mDecoder;
};
/**
* An IDecodingTask implementation for metadata decodes of images.
*/