From a727c1fe68027c66def7a24b1f954095cf07957e Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Wed, 28 Oct 2015 22:57:43 -0700 Subject: [PATCH] Back out 8 changesets (bug 1207355) for OS X 10.10 reftest failures in generated-content/ CLOSED TREE Backed out changeset aafd6db2fbb4 (bug 1207355) Backed out changeset 9dd950b837fb (bug 1207355) Backed out changeset e941e0e106a1 (bug 1207355) Backed out changeset ecebca101fcb (bug 1207355) Backed out changeset 08f2017137e1 (bug 1207355) Backed out changeset 3dc69e37c9b4 (bug 1207355) Backed out changeset bcdf51edb121 (bug 1207355) Backed out changeset 1d4c00dbf49a (bug 1207355) --- b2g/app/b2g.js | 1 + dom/base/nsDocument.cpp | 17 ++++++++-- dom/base/nsImageLoadingContent.cpp | 47 +++++++++++++++++++++++++++ image/DynamicImage.cpp | 6 ++++ image/ImageWrapper.cpp | 6 ++++ image/MultipartImage.cpp | 12 ++----- image/RasterImage.cpp | 24 +++++++------- image/VectorImage.cpp | 9 +++++ image/imgIContainer.idl | 20 ++++++++---- image/imgIRequest.idl | 13 ++++---- image/imgLoader.cpp | 4 +-- image/imgRequest.cpp | 4 +-- image/imgRequest.h | 4 +-- image/imgRequestProxy.cpp | 36 +++++++++++++++++--- image/test/unit/image_load_helpers.js | 6 ++++ layout/base/nsPresShell.cpp | 19 +---------- layout/generic/nsBulletFrame.cpp | 15 ++------- layout/generic/nsImageFrame.cpp | 32 +++--------------- layout/generic/nsImageFrame.h | 1 - layout/style/nsStyleStruct.h | 3 ++ modules/libpref/init/all.js | 3 ++ 21 files changed, 174 insertions(+), 108 deletions(-) diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index a32cc42a829e..d74046a04294 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -343,6 +343,7 @@ pref("image.mem.surfacecache.max_size_kb", 131072); // 128MB pref("image.mem.surfacecache.size_factor", 8); // 1/8 of main memory pref("image.mem.surfacecache.discard_factor", 2); // Discard 1/2 of the surface cache at a time. pref("image.mem.surfacecache.min_expiration_ms", 86400000); // 24h, we rely on the out of memory hook +pref("image.onload.decode.limit", 24); /* don't decode more than 24 images eagerly */ // XXX this isn't a good check for "are touch events supported", but // we don't really have a better one at the moment. diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index bd4939a9cbf6..c836aa1e8107 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -2117,6 +2117,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument) tmp->mInUnlinkOrDeletion = false; NS_IMPL_CYCLE_COLLECTION_UNLINK_END +static bool sPrefsInitialized = false; +static uint32_t sOnloadDecodeLimit = 0; + nsresult nsDocument::Init() { @@ -2124,6 +2127,11 @@ nsDocument::Init() return NS_ERROR_ALREADY_INITIALIZED; } + if (!sPrefsInitialized) { + sPrefsInitialized = true; + Preferences::AddUintVarCache(&sOnloadDecodeLimit, "image.onload.decode.limit", 0); + } + // Force initialization. nsINode::nsSlots* slots = Slots(); @@ -10514,8 +10522,12 @@ nsDocument::AddImage(imgIRequest* aImage) // If this is the first insertion and we're locking images, lock this image // too. - if (oldCount == 0 && mLockingImages) { - rv = aImage->LockImage(); + if (oldCount == 0) { + if (mLockingImages) + rv = aImage->LockImage(); + if (NS_SUCCEEDED(rv) && (!sOnloadDecodeLimit || + mImageTracker.Count() < sOnloadDecodeLimit)) + rv = aImage->StartDecoding(); } // If this is the first insertion and we're animating images, request @@ -10646,6 +10658,7 @@ PLDHashOperator LockEnumerator(imgIRequest* aKey, void* userArg) { aKey->LockImage(); + aKey->RequestDecode(); return PL_DHASH_NEXT; } diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp index fcd1aaa54b5a..75ba3f347c50 100644 --- a/dom/base/nsImageLoadingContent.cpp +++ b/dom/base/nsImageLoadingContent.cpp @@ -229,6 +229,53 @@ nsImageLoadingContent::OnLoadComplete(imgIRequest* aRequest, nsresult aStatus) MOZ_ASSERT(aRequest == mCurrentRequest, "One way or another, we should be current by now"); + // We just loaded all the data we're going to get. If we're visible and + // haven't done an initial paint (*), we want to make sure the image starts + // decoding immediately, for two reasons: + // + // 1) This image is sitting idle but might need to be decoded as soon as we + // start painting, in which case we've wasted time. + // + // 2) We want to block onload until all visible images are decoded. We do this + // by blocking onload until all in-progress decodes get at least one frame + // decoded. However, if all the data comes in while painting is suppressed + // (ie, before the initial paint delay is finished), we fire onload without + // doing a paint first. This means that decode-on-draw images don't start + // decoding, so we can't wait for them to finish. See bug 512435. + // + // (*) IsPaintingSuppressed returns false if we haven't gotten the initial + // reflow yet, so we have to test !DidInitialize || IsPaintingSuppressed. + // It's possible for painting to be suppressed for reasons other than the + // initial paint delay (for example, being in the bfcache), but we probably + // aren't loading images in those situations. + + // XXXkhuey should this be GetOurCurrentDoc? Decoding if we're not in + // the document seems silly. + nsIDocument* doc = GetOurOwnerDoc(); + nsIPresShell* shell = doc ? doc->GetShell() : nullptr; + if (shell && shell->IsVisible() && + (!shell->DidInitialize() || shell->IsPaintingSuppressed())) { + + nsIFrame* f = GetOurPrimaryFrame(); + // If we haven't gotten a frame yet either we aren't going to (so don't + // bother kicking off a decode), or we will get very soon on the next + // refresh driver tick when it flushes. And it will most likely be a + // specific image type frame (we only create generic (ie inline) type + // frames for images that don't have a size, and since we have all the data + // we should have the size) which will check its own visibility on its + // first reflow. + if (f) { + // If we've gotten a frame and that frame has called FrameCreate and that + // frame has been reflowed then we know that it checked it's own visibility + // so we can trust our visible count and we don't start decode if we are not + // visible. + if (!mFrameCreateCalled || (f->GetStateBits() & NS_FRAME_FIRST_REFLOW) || + mVisibleCount > 0 || shell->AssumeAllImagesVisible()) { + mCurrentRequest->StartDecoding(); + } + } + } + // Fire the appropriate DOM event. if (NS_SUCCEEDED(aStatus)) { FireEvent(NS_LITERAL_STRING("load")); diff --git a/image/DynamicImage.cpp b/image/DynamicImage.cpp index 4fdf836080bc..cf8d5555658d 100644 --- a/image/DynamicImage.cpp +++ b/image/DynamicImage.cpp @@ -246,6 +246,12 @@ DynamicImage::Draw(gfxContext* aContext, return DrawResult::SUCCESS; } +NS_IMETHODIMP +DynamicImage::RequestDecode() +{ + return NS_OK; +} + NS_IMETHODIMP DynamicImage::StartDecoding() { diff --git a/image/ImageWrapper.cpp b/image/ImageWrapper.cpp index 44cc8fe0e8a4..3289678669ec 100644 --- a/image/ImageWrapper.cpp +++ b/image/ImageWrapper.cpp @@ -214,6 +214,12 @@ ImageWrapper::Draw(gfxContext* aContext, aFilter, aSVGContext, aFlags); } +NS_IMETHODIMP +ImageWrapper::RequestDecode() +{ + return mInnerImage->RequestDecode(); +} + NS_IMETHODIMP ImageWrapper::StartDecoding() { diff --git a/image/MultipartImage.cpp b/image/MultipartImage.cpp index 4eb34bf716f3..4950e7699c82 100644 --- a/image/MultipartImage.cpp +++ b/image/MultipartImage.cpp @@ -70,16 +70,6 @@ public: return; } - // Retrieve the image's intrinsic size. - int32_t width = 0; - int32_t height = 0; - mImage->GetWidth(&width); - mImage->GetHeight(&height); - - // Request decoding at the intrinsic size. - mImage->RequestDecodeForSize(IntSize(width, height), - imgIContainer::DECODE_FLAGS_DEFAULT); - // If there's already an error, we may never get a FRAME_COMPLETE // notification, so go ahead and notify our owner right away. RefPtr tracker = mImage->GetProgressTracker(); @@ -135,6 +125,7 @@ MultipartImage::Init() RefPtr firstPartTracker = InnerImage()->GetProgressTracker(); firstPartTracker->AddObserver(this); + InnerImage()->RequestDecode(); InnerImage()->IncrementAnimationConsumers(); } @@ -163,6 +154,7 @@ MultipartImage::BeginTransitionToPart(Image* aNextPart) // Start observing the next part; we'll complete the transition when // NextPartObserver calls FinishTransition. mNextPartObserver->BeginObserving(mNextPart); + mNextPart->RequestDecode(); mNextPart->IncrementAnimationConsumers(); } diff --git a/image/RasterImage.cpp b/image/RasterImage.cpp index ba054ac84962..c4642321528f 100644 --- a/image/RasterImage.cpp +++ b/image/RasterImage.cpp @@ -319,9 +319,6 @@ RasterImage::LookupFrame(uint32_t aFrameNum, IntSize requestedSize = CanDownscaleDuringDecode(aSize, aFlags) ? aSize : mSize; - if (requestedSize.IsEmpty()) { - return DrawableFrameRef(); // Can't decode to a surface of zero size. - } LookupResult result = LookupFrameInternal(aFrameNum, requestedSize, aFlags); @@ -1166,18 +1163,18 @@ RasterImage::CanDiscard() { !mAnim; // Can never discard animated images } +//****************************************************************************** + +NS_IMETHODIMP +RasterImage::RequestDecode() +{ + return RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT); +} + + NS_IMETHODIMP RasterImage::StartDecoding() { - if (mError) { - return NS_ERROR_FAILURE; - } - - if (!mHasSize) { - mWantFullDecode = true; - return NS_OK; - } - return RequestDecodeForSize(mSize, FLAG_SYNC_DECODE_IF_FAST); } @@ -1191,6 +1188,7 @@ RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags) } if (!mHasSize) { + mWantFullDecode = true; return NS_OK; } @@ -1790,7 +1788,7 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder) // If we were a metadata decode and a full decode was requested, do it. if (done && wasMetadata && mWantFullDecode) { mWantFullDecode = false; - RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT); + RequestDecode(); } } diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp index 0703f18c2988..0bcd4f463265 100644 --- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -964,6 +964,15 @@ VectorImage::RecoverFromLossOfSurfaces() SurfaceCache::RemoveImage(ImageKey(this)); } +//****************************************************************************** + +NS_IMETHODIMP +VectorImage::RequestDecode() +{ + // Nothing to do for SVG images + return NS_OK; +} + NS_IMETHODIMP VectorImage::StartDecoding() { diff --git a/image/imgIContainer.idl b/image/imgIContainer.idl index 950ab0cda66f..c190494ca6a1 100644 --- a/image/imgIContainer.idl +++ b/image/imgIContainer.idl @@ -75,7 +75,7 @@ native nsIntSizeByVal(nsIntSize); * * Internally, imgIContainer also manages animation of images. */ -[scriptable, builtinclass, uuid(a8dbee24-ff86-4755-b40e-51175caf31af)] +[scriptable, builtinclass, uuid(7c795421-a79c-43ac-9e20-6d4e8a9dfb76)] interface imgIContainer : nsISupports { /** @@ -383,16 +383,22 @@ interface imgIContainer : nsISupports /* * Ensures that an image is decoding. Calling this function guarantees that - * the image will at some point fire off decode notifications. Images that - * can be decoded "quickly" according to some heuristic will be decoded - * synchronously. + * the image will at some point fire off decode notifications. Calling draw() + * or getFrame() triggers the same mechanism internally. Thus, if you want to + * be sure that the image will be decoded but don't want to access it until + * then, you must call requestDecode(). + */ + void requestDecode(); + + /* + * This is equivalent to requestDecode() but it also synchronously decodes + * images that can be decoded "quickly" according to some heuristic. */ [noscript] void startDecoding(); /* - * This method triggers decoding for an image, but unlike startDecoding() it - * enables the caller to provide more detailed information about the decode - * request. + * This method is equivalent to requestDecode(), but enables the caller to + * provide more detailed information about the decode request. * * @param aSize The size to which the image should be scaled while decoding, * if possible. If the image cannot be scaled to this size while diff --git a/image/imgIRequest.idl b/image/imgIRequest.idl index 680bd6e3ac65..ef31511e7eb1 100644 --- a/image/imgIRequest.idl +++ b/image/imgIRequest.idl @@ -19,7 +19,7 @@ interface nsIPrincipal; * @version 0.1 * @see imagelib2 */ -[scriptable, builtinclass, uuid(db0a945c-3883-424a-98d0-2ee0523b0255)] +[scriptable, builtinclass, uuid(4cb01f0a-ef94-4345-a8d7-1a93f15ff548)] interface imgIRequest : nsIRequest { /** @@ -145,14 +145,15 @@ interface imgIRequest : nsIRequest void cancelAndForgetObserver(in nsresult aStatus); /** - * Requests a synchronous decode for the image. + * Requests a decode for the image. * - * imgIContainer has a startDecoding() method, but callers may want to request + * imgIContainer has a requestDecode() method, but callers may want to request * a decode before the container has necessarily been instantiated. Calling - * startDecoding() on the imgIRequest simply forwards along the request if the - * container already exists, or calls it once the container becomes available - * if it does not yet exist. + * requestDecode() on the imgIRequest simply forwards along the request if the + * container already exists, or calls it once it gets OnStartContainer if the + * container does not yet exist. */ + void requestDecode(); void startDecoding(); /** diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp index aa298291dd26..33a5f0b86cc8 100644 --- a/image/imgLoader.cpp +++ b/image/imgLoader.cpp @@ -1590,7 +1590,7 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request, // We will send notifications from imgCacheValidator::OnStartRequest(). // In the mean time, we must defer notifications because we are added to // the imgRequest's proxy list, and we can get extra notifications - // resulting from methods such as StartDecoding(). See bug 579122. + // resulting from methods such as RequestDecode(). See bug 579122. proxy->SetNotificationsDeferred(true); // Attach the proxy without notifying @@ -1666,7 +1666,7 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request, // We will send notifications from imgCacheValidator::OnStartRequest(). // In the mean time, we must defer notifications because we are added to // the imgRequest's proxy list, and we can get extra notifications - // resulting from methods such as StartDecoding(). See bug 579122. + // resulting from methods such as RequestDecode(). See bug 579122. req->SetNotificationsDeferred(true); // Add the proxy without notifying diff --git a/image/imgRequest.cpp b/image/imgRequest.cpp index 62b6f1770a48..f6862039e38b 100644 --- a/image/imgRequest.cpp +++ b/image/imgRequest.cpp @@ -413,7 +413,7 @@ imgRequest::ContinueEvict() } void -imgRequest::StartDecoding() +imgRequest::RequestDecode() { MutexAutoLock lock(mMutex); mDecodeRequested = true; @@ -1053,7 +1053,7 @@ imgRequest::FinishPreparingForNewPart(const NewPartResult& aResult) } if (IsDecodeRequested()) { - aResult.mImage->StartDecoding(); + aResult.mImage->RequestDecode(); } } diff --git a/image/imgRequest.h b/image/imgRequest.h index 520ca16f59b4..4abf009108cc 100644 --- a/image/imgRequest.h +++ b/image/imgRequest.h @@ -95,7 +95,7 @@ public: void ContinueEvict(); // Request that we start decoding the image as soon as data becomes available. - void StartDecoding(); + void RequestDecode(); inline uint64_t InnerWindowID() const { return mInnerWindowId; @@ -220,7 +220,7 @@ private: // Update the cache entry size based on the image container. void UpdateCacheEntrySize(); - /// Returns true if StartDecoding() was called. + /// Returns true if RequestDecode() was called. bool IsDecodeRequested() const; // Weak reference to parent loader; this request cannot outlive its owner. diff --git a/image/imgRequestProxy.cpp b/image/imgRequestProxy.cpp index ecec7d588451..bf912ae2fbec 100644 --- a/image/imgRequestProxy.cpp +++ b/image/imgRequestProxy.cpp @@ -208,6 +208,15 @@ imgRequestProxy::ChangeOwner(imgRequest* aNewOwner) uint32_t oldAnimationConsumers = mAnimationConsumers; ClearAnimationConsumers(); + // Were we decoded before? + bool wasDecoded = false; + RefPtr progressTracker = GetProgressTracker(); + if (progressTracker->HasImage() && + progressTracker->GetImageStatus() & + imgIRequest::STATUS_FRAME_COMPLETE) { + wasDecoded = true; + } + GetOwner()->RemoveProxy(this, NS_IMAGELIB_CHANGING_OWNER); mBehaviour->SetOwner(aNewOwner); @@ -226,9 +235,9 @@ imgRequestProxy::ChangeOwner(imgRequest* aNewOwner) GetOwner()->AddProxy(this); - // If we'd previously requested a synchronous decode, request a decode on the - // new image. - if (mDecodeRequested) { + // If we were decoded, or if we'd previously requested a decode, request a + // decode on the new image + if (wasDecoded || mDecodeRequested) { StartDecoding(); } @@ -371,12 +380,31 @@ imgRequestProxy::StartDecoding() } if (GetOwner()) { - GetOwner()->StartDecoding(); + GetOwner()->RequestDecode(); } return NS_OK; } +NS_IMETHODIMP +imgRequestProxy::RequestDecode() +{ + // Flag this, so we know to transfer the request if our owner changes + mDecodeRequested = true; + + RefPtr image = GetImage(); + if (image) { + return image->RequestDecode(); + } + + if (GetOwner()) { + GetOwner()->RequestDecode(); + } + + return NS_OK; +} + + NS_IMETHODIMP imgRequestProxy::LockImage() { diff --git a/image/test/unit/image_load_helpers.js b/image/test/unit/image_load_helpers.js index e8d9a29f860d..5fc596584395 100644 --- a/image/test/unit/image_load_helpers.js +++ b/image/test/unit/image_load_helpers.js @@ -48,6 +48,12 @@ function ImageListener(start_callback, stop_callback) { do_check_false(this.synchronous); + try { + aRequest.requestDecode(); + } catch (e) { + do_print("requestDecode threw " + e); + } + this.state |= LOAD_COMPLETE; if (this.stop_callback) diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index b1a2d7152e82..d0c70289dfad 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -168,7 +168,6 @@ #include "mozilla/Telemetry.h" #include "nsCanvasFrame.h" #include "nsIImageLoadingContent.h" -#include "nsImageFrame.h" #include "nsIScreen.h" #include "nsIScreenManager.h" #include "nsPlaceholderFrame.h" @@ -10702,23 +10701,7 @@ nsresult PresShell::UpdateImageLockingState() { // We're locked if we're both thawed and active. - bool locked = !mFrozen && mIsActive; - - nsresult rv = mDocument->SetImageLockingState(locked); - - if (locked) { - // Request decodes for visible images; we want to start decoding as - // quickly as possible when we get foregrounded to minimize flashing. - for (auto iter = mVisibleImages.Iter(); !iter.Done(); iter.Next()) { - nsCOMPtr content = do_QueryInterface(iter.Get()->GetKey()); - nsImageFrame* imageFrame = do_QueryFrame(content->GetPrimaryFrame()); - if (imageFrame) { - imageFrame->MaybeDecodeForPredictedSize(); - } - } - } - - return rv; + return mDocument->SetImageLockingState(!mFrozen && mIsActive); } PresShell* diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp index f7472d2259c4..25c1f6dfcd8f 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -712,20 +712,9 @@ nsBulletFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aDa // Unconditionally start decoding for now. // XXX(seth): We eventually want to decide whether to do this based on // visibility. We should get that for free from bug 1091236. - nsCOMPtr container; - aRequest->GetImage(getter_AddRefs(container)); - if (container) { - // Retrieve the intrinsic size of the image. - int32_t width = 0; - int32_t height = 0; - container->GetWidth(&width); - container->GetHeight(&height); - - // Request a decode at that size. - container->RequestDecodeForSize(IntSize(width, height), - imgIContainer::DECODE_FLAGS_DEFAULT); + if (aRequest == mImageRequest) { + mImageRequest->RequestDecode(); } - InvalidateFrame(); } diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index a0411b6a1d13..f2a6dbc413aa 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1814,11 +1814,7 @@ nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // decoded yet. And we are not going to ask the image to draw, so this // may be the only chance to tell it that it should decode. if (currentRequest) { - uint32_t status = 0; - currentRequest->GetImageStatus(&status); - if (!(status & imgIRequest::STATUS_DECODE_COMPLETE)) { - MaybeDecodeForPredictedSize(); - } + currentRequest->RequestDecode(); } } else { aLists.Content()->AppendNewToTop(new (aBuilder) @@ -2299,6 +2295,7 @@ nsresult nsImageFrame::LoadIcons(nsPresContext *aPresContext) if (NS_FAILED(rv)) { return rv; } + gIconLoad->mLoadingImage->RequestDecode(); rv = LoadIcon(brokenSrc, aPresContext, @@ -2306,6 +2303,7 @@ nsresult nsImageFrame::LoadIcons(nsPresContext *aPresContext) if (NS_FAILED(rv)) { return rv; } + gIconLoad->mBrokenImage->RequestDecode(); return rv; } @@ -2375,35 +2373,13 @@ void nsImageFrame::IconLoad::GetPrefs() } NS_IMETHODIMP -nsImageFrame::IconLoad::Notify(imgIRequest* aRequest, - int32_t aType, - const nsIntRect* aData) +nsImageFrame::IconLoad::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { - MOZ_ASSERT(aRequest); - if (aType != imgINotificationObserver::LOAD_COMPLETE && aType != imgINotificationObserver::FRAME_UPDATE) { return NS_OK; } - if (aType == imgINotificationObserver::LOAD_COMPLETE) { - nsCOMPtr image; - aRequest->GetImage(getter_AddRefs(image)); - if (!image) { - return NS_ERROR_FAILURE; - } - - // Retrieve the image's intrinsic size. - int32_t width = 0; - int32_t height = 0; - image->GetWidth(&width); - image->GetHeight(&height); - - // Request a decode at that size. - image->RequestDecodeForSize(IntSize(width, height), - imgIContainer::DECODE_FLAGS_DEFAULT); - } - nsTObserverArray::ForwardIterator iter(mIconObservers); nsImageFrame *frame; while (iter.HasMore()) { diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index a2b7190d0ea0..4f43e35215d9 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -230,7 +230,6 @@ protected: protected: friend class nsImageListener; friend class nsImageLoadingContent; - friend class PresShell; nsresult OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage); nsresult OnFrameUpdate(imgIRequest* aRequest, const nsIntRect* aRect); diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index c33c3016f867..6f831876e075 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -962,6 +962,9 @@ struct nsStyleBorder { return mBorderImageSource.IsLoaded(); } + // Defined in nsStyleStructInlines.h + inline nsresult RequestDecode(); + void GetBorderColor(mozilla::css::Side aSide, nscolor& aColor, bool& aForeground) const { diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 2b27904ae638..73a049903554 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4152,6 +4152,9 @@ pref("image.multithreaded_decoding.limit", -1); // cache. pref("canvas.image.cache.limit", 0); +// How many images to eagerly decode on a given page. 0 means "no limit". +pref("image.onload.decode.limit", 0); + // WebGL prefs #ifdef ANDROID // Disable MSAA on mobile.