зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1118655 - Use decode-on-draw only, and ignore RequestDecode and the like, when APZ and downscale-during-decode are enabled. r=tn
This commit is contained in:
Родитель
f5127dcbe3
Коммит
d34d823d05
|
@ -322,7 +322,7 @@ pref("media.fragmented-mp4.gonk.enabled", true);
|
|||
pref("media.video-queue.default-size", 3);
|
||||
|
||||
// optimize images' memory usage
|
||||
pref("image.mem.decodeondraw", true);
|
||||
pref("image.mem.decodeondraw", false);
|
||||
pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */
|
||||
// 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
|
||||
|
|
|
@ -45,7 +45,8 @@ ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart)
|
|||
|
||||
// We default to the static globals.
|
||||
bool isDiscardable = gfxPrefs::ImageMemDiscardable();
|
||||
bool doDecodeOnDraw = gfxPrefs::ImageMemDecodeOnDraw();
|
||||
bool doDecodeOnDraw = gfxPrefs::ImageMemDecodeOnDraw() &&
|
||||
gfxPrefs::AsyncPanZoomEnabled();
|
||||
bool doDownscaleDuringDecode = gfxPrefs::ImageDownscaleDuringDecodeEnabled();
|
||||
|
||||
// We want UI to be as snappy as possible and not to flicker. Disable
|
||||
|
@ -64,9 +65,12 @@ ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart)
|
|||
isDiscardable = doDecodeOnDraw = false;
|
||||
}
|
||||
|
||||
// Downscale-during-decode is only enabled for certain content types.
|
||||
if (doDownscaleDuringDecode && !ShouldDownscaleDuringDecode(aMimeType)) {
|
||||
// Downscale-during-decode and decode-on-draw are only enabled for certain
|
||||
// content types.
|
||||
if ((doDownscaleDuringDecode || doDecodeOnDraw) &&
|
||||
!ShouldDownscaleDuringDecode(aMimeType)) {
|
||||
doDownscaleDuringDecode = false;
|
||||
doDecodeOnDraw = false;
|
||||
}
|
||||
|
||||
// For multipart/x-mixed-replace, we basically want a direct channel to the
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
@ -271,6 +272,7 @@ RasterImage::RasterImage(ProgressTracker* aProgressTracker,
|
|||
mSourceBuffer(new SourceBuffer()),
|
||||
mFrameCount(0),
|
||||
mHasSize(false),
|
||||
mBlockedOnload(false),
|
||||
mDecodeOnDraw(false),
|
||||
mTransient(false),
|
||||
mDiscardable(false),
|
||||
|
@ -1166,26 +1168,58 @@ RasterImage::OnImageDataComplete(nsIRequest*, nsISupports*, nsresult aStatus,
|
|||
DoError();
|
||||
}
|
||||
|
||||
// Notify our listeners, which will fire this image's load event.
|
||||
MOZ_ASSERT(mHasSize || mError, "Need to know size before firing load event");
|
||||
MOZ_ASSERT(!mHasSize ||
|
||||
(mProgressTracker->GetProgress() & FLAG_SIZE_AVAILABLE),
|
||||
"Should have notified that the size is available if we have it");
|
||||
|
||||
Progress loadProgress = LoadCompleteProgress(aLastPart, mError, finalStatus);
|
||||
|
||||
if (mBlockedOnload) {
|
||||
// For decode-on-draw images, we want to send notifications as if we've
|
||||
// already finished decoding. Otherwise some observers will never even try
|
||||
// to draw.
|
||||
MOZ_ASSERT(mDecodeOnDraw, "Blocked onload but not decode-on-draw");
|
||||
loadProgress |= FLAG_FRAME_COMPLETE |
|
||||
FLAG_DECODE_COMPLETE |
|
||||
FLAG_ONLOAD_UNBLOCKED;
|
||||
}
|
||||
|
||||
// Notify our listeners, which will fire this image's load event.
|
||||
NotifyProgress(loadProgress);
|
||||
|
||||
return finalStatus;
|
||||
}
|
||||
|
||||
void
|
||||
RasterImage::BlockOnloadForDecodeOnDraw()
|
||||
{
|
||||
if (mHasSourceData) {
|
||||
// OnImageDataComplete got called before we got to run. No point in blocking
|
||||
// onload now.
|
||||
return;
|
||||
}
|
||||
|
||||
// Block onload. We'll unblock it in OnImageDataComplete.
|
||||
mBlockedOnload = true;
|
||||
NotifyProgress(FLAG_DECODE_STARTED | FLAG_ONLOAD_BLOCKED);
|
||||
}
|
||||
|
||||
nsresult
|
||||
RasterImage::OnImageDataAvailable(nsIRequest*,
|
||||
nsISupports*,
|
||||
nsIInputStream* aInStr,
|
||||
uint64_t,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (MOZ_UNLIKELY(mDecodeOnDraw && aOffset == 0)) {
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewRunnableMethod(this, &RasterImage::BlockOnloadForDecodeOnDraw);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
|
||||
// WriteToSourceBuffer always consumes everything it gets if it doesn't run
|
||||
// out of memory.
|
||||
uint32_t bytesRead;
|
||||
|
@ -1405,6 +1439,11 @@ RasterImage::WantDecodedFrames(const nsIntSize& aSize, uint32_t aFlags,
|
|||
NS_IMETHODIMP
|
||||
RasterImage::RequestDecode()
|
||||
{
|
||||
// For decode-on-draw images, we only act on RequestDecodeForSize.
|
||||
if (mDecodeOnDraw) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT);
|
||||
}
|
||||
|
||||
|
@ -1417,6 +1456,11 @@ RasterImage::StartDecoding()
|
|||
NS_NewRunnableMethod(this, &RasterImage::StartDecoding));
|
||||
}
|
||||
|
||||
// For decode-on-draw images, we only act on RequestDecodeForSize.
|
||||
if (mDecodeOnDraw) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return RequestDecodeForSize(mSize, FLAG_SYNC_DECODE);
|
||||
}
|
||||
|
||||
|
@ -1457,7 +1501,7 @@ bool
|
|||
RasterImage::IsDecoded()
|
||||
{
|
||||
// XXX(seth): We need to get rid of this; it's not reliable.
|
||||
return mHasBeenDecoded || mError;
|
||||
return mHasBeenDecoded || mError || (mDecodeOnDraw && mHasSourceData);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -242,6 +242,8 @@ public:
|
|||
nsresult aStatus,
|
||||
bool aLastPart) MOZ_OVERRIDE;
|
||||
|
||||
void BlockOnloadForDecodeOnDraw();
|
||||
|
||||
/**
|
||||
* A hint of the number of bytes of source data that the image contains. If
|
||||
* called early on, this can help reduce copying and reallocations by
|
||||
|
@ -387,6 +389,7 @@ private: // data
|
|||
|
||||
// Boolean flags (clustered together to conserve space):
|
||||
bool mHasSize:1; // Has SetSize() been called?
|
||||
bool mBlockedOnload:1; // Did send BLOCK_ONLOAD?
|
||||
bool mDecodeOnDraw:1; // Decoding on draw?
|
||||
bool mTransient:1; // Is the image short-lived?
|
||||
bool mDiscardable:1; // Is container discardable?
|
||||
|
|
|
@ -1425,8 +1425,7 @@ nsDisplayImage::GetContainer(LayerManager* aManager,
|
|||
nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
nsRefPtr<ImageContainer> container;
|
||||
nsresult rv = mImage->GetImageContainer(aManager, getter_AddRefs(container));
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
mImage->GetImageContainer(aManager, getter_AddRefs(container));
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -434,8 +434,7 @@ nsImageBoxFrame::GetContainer(LayerManager* aManager)
|
|||
}
|
||||
|
||||
nsRefPtr<ImageContainer> container;
|
||||
nsresult rv = imgCon->GetImageContainer(aManager, getter_AddRefs(container));
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
imgCon->GetImageContainer(aManager, getter_AddRefs(container));
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -563,7 +563,7 @@ pref("media.fragmented-mp4.android-media-codec.enabled", true);
|
|||
pref("media.fragmented-mp4.android-media-codec.preferred", true);
|
||||
|
||||
// optimize images memory usage
|
||||
pref("image.mem.decodeondraw", true);
|
||||
pref("image.mem.decodeondraw", false);
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// Shumway component (SWF player) is disabled by default. Also see bug 904346.
|
||||
|
|
|
@ -3789,7 +3789,7 @@ pref("image.mem.discardable", true);
|
|||
|
||||
// Prevents images from automatically being decoded on load, instead allowing
|
||||
// them to be decoded on demand when they are drawn.
|
||||
pref("image.mem.decodeondraw", true);
|
||||
pref("image.mem.decodeondraw", false);
|
||||
|
||||
// Allows image locking of decoded image data in content processes.
|
||||
pref("image.mem.allow_locking_in_content_processes", true);
|
||||
|
|
|
@ -135,6 +135,16 @@ nsAlertsIconListener::OnLoadComplete(imgIRequest* aRequest)
|
|||
mIconRequest = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
rv = aRequest->GetImage(getter_AddRefs(image));
|
||||
MOZ_ASSERT(image);
|
||||
|
||||
// Ask the image to decode at its intrinsic size.
|
||||
int32_t width = 0, height = 0;
|
||||
image->GetWidth(&width);
|
||||
image->GetHeight(&height);
|
||||
image->RequestDecodeForSize(nsIntSize(width, height), imgIContainer::FLAG_NONE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -227,8 +237,6 @@ nsAlertsIconListener::StartRequest(const nsAString & aImageUrl, bool aInPrivateB
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mIconRequest->StartDecoding();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -314,9 +314,6 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
|
|||
getter_AddRefs(mIconRequest));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// We need to request the icon be decoded (bug 573583, bug 705516).
|
||||
mIconRequest->StartDecoding();
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
@ -331,6 +328,27 @@ nsMenuItemIconX::Notify(imgIRequest* aRequest,
|
|||
int32_t aType,
|
||||
const nsIntRect* aData)
|
||||
{
|
||||
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
|
||||
// Make sure the image loaded successfully.
|
||||
uint32_t status = imgIRequest::STATUS_ERROR;
|
||||
if (NS_FAILED(aRequest->GetImageStatus(&status)) ||
|
||||
(status & imgIRequest::STATUS_ERROR)) {
|
||||
mIconRequest->Cancel(NS_BINDING_ABORTED);
|
||||
mIconRequest = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
aRequest->GetImage(getter_AddRefs(image));
|
||||
MOZ_ASSERT(image);
|
||||
|
||||
// Ask the image to decode at its intrinsic size.
|
||||
int32_t width = 0, height = 0;
|
||||
image->GetWidth(&width);
|
||||
image->GetHeight(&height);
|
||||
image->RequestDecodeForSize(nsIntSize(width, height), imgIContainer::FLAG_NONE);
|
||||
}
|
||||
|
||||
if (aType == imgINotificationObserver::FRAME_COMPLETE) {
|
||||
return OnFrameComplete(aRequest);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче