Bug 1171356 - On B2G, retry image decodes that fail because allocation of the first frame failed. r=tn

This commit is contained in:
Seth Fowler 2015-06-04 11:08:17 -07:00
Родитель f60e403485
Коммит f52aaaa54b
4 изменённых файлов: 58 добавлений и 0 удалений

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

@ -332,6 +332,7 @@ pref("media.video-queue.default-size", 3);
pref("image.downscale-during-decode.enabled", true);
pref("image.decode-only-on-draw.enabled", false);
pref("image.mem.allow_locking_in_content_processes", true);
pref("image.decode.retry-on-alloc-failure", true);
// Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller.
// Almost everything that was factored into 'max_decoded_image_kb' is now stored
// in the surface cache. 1/8 of main memory is 32MB on a 256MB device, which is

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

@ -256,6 +256,7 @@ private:
DECL_GFX_PREF(Once, "image.cache.timeweight", ImageCacheTimeWeight, int32_t, 500);
DECL_GFX_PREF(Live, "image.decode-only-on-draw.enabled", ImageDecodeOnlyOnDrawEnabled, bool, true);
DECL_GFX_PREF(Live, "image.decode-immediately.enabled", ImageDecodeImmediatelyEnabled, bool, false);
DECL_GFX_PREF(Once, "image.decode.retry-on-alloc-failure", ImageDecodeRetryOnAllocFailure, bool, false);
DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, true);
DECL_GFX_PREF(Live, "image.high_quality_downscaling.enabled", ImageHQDownscalingEnabled, bool, false);
DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000);

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

@ -262,6 +262,7 @@ RasterImage::RasterImage(ImageURL* aURI /* = nullptr */) :
#endif
mSourceBuffer(new SourceBuffer()),
mFrameCount(0),
mRetryCount(0),
mHasSize(false),
mDecodeOnlyOnDraw(false),
mTransient(false),
@ -1342,6 +1343,31 @@ RasterImage::CanDiscard() {
!mAnim; // Can never discard animated images
}
class RetryDecodeRunnable : public nsRunnable
{
public:
RetryDecodeRunnable(RasterImage* aImage,
const IntSize& aSize,
uint32_t aFlags)
: mImage(aImage)
, mSize(aSize)
, mFlags(aFlags)
{
MOZ_ASSERT(aImage);
}
NS_IMETHOD Run()
{
mImage->RequestDecodeForSize(mSize, mFlags);
return NS_OK;
}
private:
nsRefPtr<RasterImage> mImage;
const IntSize mSize;
const uint32_t mFlags;
};
// Sets up a decoder for this image.
already_AddRefed<Decoder>
RasterImage::CreateDecoder(const Maybe<IntSize>& aSize, uint32_t aFlags)
@ -1418,6 +1444,33 @@ RasterImage::CreateDecoder(const Maybe<IntSize>& aSize, uint32_t aFlags)
SurfaceFormat::B8G8R8A8);
decoder->AllocateFrame(*aSize);
}
if (aSize && decoder->HasError()) {
if (gfxPrefs::ImageDecodeRetryOnAllocFailure() &&
mRetryCount < 10) {
// We couldn't allocate the first frame for this image. We're probably in
// a temporary low-memory situation, so fire off a runnable and hope that
// things have improved when it runs. (Unless we've already retried 10
// times in a row, in which case just give up.)
mRetryCount++;
if (decoder->ImageIsLocked()) {
UnlockImage();
}
decoder->TakeProgress();
decoder->TakeInvalidRect();
nsCOMPtr<nsIRunnable> runnable =
new RetryDecodeRunnable(this, *aSize, aFlags);
NS_DispatchToMainThread(runnable);
return nullptr;
}
} else {
// We didn't encounter an error when allocating the first frame.
mRetryCount = 0;
}
decoder->SetIterator(mSourceBuffer->Iterator());
// Set a target size for downscale-during-decode if applicable.

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

@ -400,6 +400,9 @@ private: // data
// The number of frames this image has.
uint32_t mFrameCount;
// The number of times we've retried decoding this image.
uint8_t mRetryCount;
// Boolean flags (clustered together to conserve space):
bool mHasSize:1; // Has SetSize() been called?
bool mDecodeOnlyOnDraw:1; // Decoding only on draw?