зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1171356 - On B2G, retry image decodes that fail because allocation of the first frame failed. r=tn
This commit is contained in:
Родитель
f60e403485
Коммит
f52aaaa54b
|
@ -332,6 +332,7 @@ pref("media.video-queue.default-size", 3);
|
||||||
pref("image.downscale-during-decode.enabled", true);
|
pref("image.downscale-during-decode.enabled", true);
|
||||||
pref("image.decode-only-on-draw.enabled", false);
|
pref("image.decode-only-on-draw.enabled", false);
|
||||||
pref("image.mem.allow_locking_in_content_processes", true);
|
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.
|
// 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
|
// 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
|
// 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(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-only-on-draw.enabled", ImageDecodeOnlyOnDrawEnabled, bool, true);
|
||||||
DECL_GFX_PREF(Live, "image.decode-immediately.enabled", ImageDecodeImmediatelyEnabled, bool, false);
|
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.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.enabled", ImageHQDownscalingEnabled, bool, false);
|
||||||
DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000);
|
DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000);
|
||||||
|
|
|
@ -262,6 +262,7 @@ RasterImage::RasterImage(ImageURL* aURI /* = nullptr */) :
|
||||||
#endif
|
#endif
|
||||||
mSourceBuffer(new SourceBuffer()),
|
mSourceBuffer(new SourceBuffer()),
|
||||||
mFrameCount(0),
|
mFrameCount(0),
|
||||||
|
mRetryCount(0),
|
||||||
mHasSize(false),
|
mHasSize(false),
|
||||||
mDecodeOnlyOnDraw(false),
|
mDecodeOnlyOnDraw(false),
|
||||||
mTransient(false),
|
mTransient(false),
|
||||||
|
@ -1342,6 +1343,31 @@ RasterImage::CanDiscard() {
|
||||||
!mAnim; // Can never discard animated images
|
!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.
|
// Sets up a decoder for this image.
|
||||||
already_AddRefed<Decoder>
|
already_AddRefed<Decoder>
|
||||||
RasterImage::CreateDecoder(const Maybe<IntSize>& aSize, uint32_t aFlags)
|
RasterImage::CreateDecoder(const Maybe<IntSize>& aSize, uint32_t aFlags)
|
||||||
|
@ -1418,6 +1444,33 @@ RasterImage::CreateDecoder(const Maybe<IntSize>& aSize, uint32_t aFlags)
|
||||||
SurfaceFormat::B8G8R8A8);
|
SurfaceFormat::B8G8R8A8);
|
||||||
decoder->AllocateFrame(*aSize);
|
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());
|
decoder->SetIterator(mSourceBuffer->Iterator());
|
||||||
|
|
||||||
// Set a target size for downscale-during-decode if applicable.
|
// Set a target size for downscale-during-decode if applicable.
|
||||||
|
|
|
@ -400,6 +400,9 @@ private: // data
|
||||||
// The number of frames this image has.
|
// The number of frames this image has.
|
||||||
uint32_t mFrameCount;
|
uint32_t mFrameCount;
|
||||||
|
|
||||||
|
// The number of times we've retried decoding this image.
|
||||||
|
uint8_t mRetryCount;
|
||||||
|
|
||||||
// Boolean flags (clustered together to conserve space):
|
// Boolean flags (clustered together to conserve space):
|
||||||
bool mHasSize:1; // Has SetSize() been called?
|
bool mHasSize:1; // Has SetSize() been called?
|
||||||
bool mDecodeOnlyOnDraw:1; // Decoding only on draw?
|
bool mDecodeOnlyOnDraw:1; // Decoding only on draw?
|
||||||
|
|
Загрузка…
Ссылка в новой задаче