From 5949a85197ab979281c5855f9ac7120f7e47f5e6 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Wed, 13 Feb 2013 14:18:08 -0600 Subject: [PATCH] Bug 784591. Part 2. Don't track images that don't have a frame created. r=jlebar --- content/base/src/nsImageLoadingContent.cpp | 76 +++++++++++++++++++--- content/base/src/nsImageLoadingContent.h | 6 +- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/content/base/src/nsImageLoadingContent.cpp b/content/base/src/nsImageLoadingContent.cpp index afe6fc1e3b6..f09daed1c8c 100644 --- a/content/base/src/nsImageLoadingContent.cpp +++ b/content/base/src/nsImageLoadingContent.cpp @@ -379,6 +379,21 @@ nsImageLoadingContent::FrameCreated(nsIFrame* aFrame) // be registered. nsPresContext* presContext = aFrame->PresContext(); + if (mCurrentRequest && !(mCurrentRequestFlags & REQUEST_IS_TRACKED)) { + nsIDocument* doc = GetOurCurrentDoc(); + if (doc) { + mCurrentRequestFlags |= REQUEST_IS_TRACKED; + doc->AddImage(mCurrentRequest); + } + } + if (mPendingRequest && !(mPendingRequestFlags & REQUEST_IS_TRACKED)) { + nsIDocument* doc = GetOurCurrentDoc(); + if (doc) { + mPendingRequestFlags |= REQUEST_IS_TRACKED; + doc->AddImage(mPendingRequest); + } + } + if (mCurrentRequest) { nsLayoutUtils::RegisterImageRequestIfAnimated(presContext, mCurrentRequest, &mCurrentRequestRegistered); @@ -407,6 +422,21 @@ nsImageLoadingContent::FrameDestroyed(nsIFrame* aFrame) mPendingRequest, &mPendingRequestRegistered); } + + if (mCurrentRequest && (mCurrentRequestFlags & REQUEST_IS_TRACKED)) { + nsIDocument* doc = GetOurCurrentDoc(); + if (doc) { + mCurrentRequestFlags &= ~REQUEST_IS_TRACKED; + doc->RemoveImage(mCurrentRequest); + } + } + if (mPendingRequest && (mPendingRequestFlags & REQUEST_IS_TRACKED)) { + nsIDocument* doc = GetOurCurrentDoc(); + if (doc) { + mPendingRequestFlags &= ~REQUEST_IS_TRACKED; + doc->RemoveImage(mPendingRequest); + } + } } int32_t @@ -1153,10 +1183,16 @@ nsImageLoadingContent::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsCxPusher pusher; pusher.PushNull(); - if (mCurrentRequest) - aDocument->AddImage(mCurrentRequest); - if (mPendingRequest) - aDocument->AddImage(mPendingRequest); + if (GetOurPrimaryFrame()) { + if (mCurrentRequest && !(mCurrentRequestFlags & REQUEST_IS_TRACKED)) { + mCurrentRequestFlags |= REQUEST_IS_TRACKED; + aDocument->AddImage(mCurrentRequest); + } + if (mPendingRequest && !(mPendingRequestFlags & REQUEST_IS_TRACKED)) { + mPendingRequestFlags |= REQUEST_IS_TRACKED; + aDocument->AddImage(mPendingRequest); + } + } if (mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD) aDocument->BlockOnload(); @@ -1175,10 +1211,14 @@ nsImageLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent) nsCxPusher pusher; pusher.PushNull(); - if (mCurrentRequest) + if (mCurrentRequest && (mCurrentRequestFlags & REQUEST_IS_TRACKED)) { + mCurrentRequestFlags &= ~REQUEST_IS_TRACKED; doc->RemoveImage(mCurrentRequest); - if (mPendingRequest) + } + if (mPendingRequest && (mPendingRequestFlags & REQUEST_IS_TRACKED)) { + mPendingRequestFlags &= ~REQUEST_IS_TRACKED; doc->RemoveImage(mPendingRequest); + } if (mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD) doc->UnblockOnload(false); @@ -1194,8 +1234,16 @@ nsImageLoadingContent::TrackImage(imgIRequest* aImage) "Why haven't we heard of this request?"); nsIDocument* doc = GetOurCurrentDoc(); - if (doc) - return doc->AddImage(aImage); + if (doc && GetOurPrimaryFrame()) { + if (aImage == mCurrentRequest && !(mCurrentRequestFlags & REQUEST_IS_TRACKED)) { + mCurrentRequestFlags |= REQUEST_IS_TRACKED; + doc->AddImage(mCurrentRequest); + } + if (aImage == mPendingRequest && !(mPendingRequestFlags & REQUEST_IS_TRACKED)) { + mPendingRequestFlags |= REQUEST_IS_TRACKED; + doc->AddImage(mPendingRequest); + } + } return NS_OK; } @@ -1212,8 +1260,16 @@ nsImageLoadingContent::UntrackImage(imgIRequest* aImage) // That's fine, because the document empties out the tracker and unlocks // all locked images on destruction. nsIDocument* doc = GetOurCurrentDoc(); - if (doc) - return doc->RemoveImage(aImage, nsIDocument::REQUEST_DISCARD); + if (doc) { + if (aImage == mCurrentRequest && (mCurrentRequestFlags & REQUEST_IS_TRACKED)) { + mCurrentRequestFlags &= ~REQUEST_IS_TRACKED; + doc->RemoveImage(mCurrentRequest, nsIDocument::REQUEST_DISCARD); + } + if (aImage == mPendingRequest && (mPendingRequestFlags & REQUEST_IS_TRACKED)) { + mPendingRequestFlags &= ~REQUEST_IS_TRACKED; + doc->RemoveImage(mPendingRequest, nsIDocument::REQUEST_DISCARD); + } + } return NS_OK; } diff --git a/content/base/src/nsImageLoadingContent.h b/content/base/src/nsImageLoadingContent.h index f463dfc2755..8c5cec598f6 100644 --- a/content/base/src/nsImageLoadingContent.h +++ b/content/base/src/nsImageLoadingContent.h @@ -337,10 +337,12 @@ protected: uint32_t mPendingRequestFlags; enum { - // Set if the request needs + // Set if the request needs ResetAnimation called on it. REQUEST_NEEDS_ANIMATION_RESET = 0x00000001U, // Set if the request is blocking onload. - REQUEST_BLOCKS_ONLOAD = 0x00000002U + REQUEST_BLOCKS_ONLOAD = 0x00000002U, + // Set if the request is currently tracked with the document. + REQUEST_IS_TRACKED = 0x00000004U }; // If the image was blocked or if there was an error loading, it's nice to