Bug 1291045 (Part 1) - Use a different IDecodingTask for animated images. r=dholbert,edwin
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user