зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1291045 (Part 7) - Replace DecodingTask with DecodedSurfaceProvider. r=dholbert,edwin
This commit is contained in:
Родитель
1cd0225e12
Коммит
f5495f0fd1
|
@ -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.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче