From fcd1ce5c848b276ee5aa8c735c7c95830696054c Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 11 Oct 2012 21:34:24 -0400 Subject: [PATCH] Bug 505385 - Part 18: Reduce number of notifications - START_REQUEST/START_CONTAINER -> SIZE_AVAILABLE, remove START_DECODE and START_FRAME. Rename remaining ones for clarity. r=joe --- content/base/src/nsImageLoadingContent.cpp | 10 +-- content/html/document/src/ImageDocument.cpp | 6 +- content/svg/content/src/nsSVGFilters.cpp | 8 +- image/public/imgIDecoderObserver.idl | 9 +-- image/public/imgINotificationObserver.idl | 20 ++--- .../imgIScriptedNotificationObserver.idl | 16 ++-- image/src/Decoder.cpp | 4 - image/src/ScriptedNotificationObserver.cpp | 28 +++---- image/src/imgRequestProxy.cpp | 53 ++----------- image/src/imgRequestProxy.h | 7 +- image/src/imgStatusTracker.cpp | 74 ++----------------- image/src/imgStatusTracker.h | 5 -- image/test/mochitest/imgutils.js | 14 ++-- image/test/mochitest/test_animSVGImage.html | 2 +- image/test/unit/async_load_tests.js | 15 ++-- image/test/unit/image_load_helpers.js | 64 +++++++--------- layout/generic/nsBulletFrame.cpp | 5 +- layout/generic/nsImageFrame.cpp | 31 ++++---- layout/generic/nsImageFrame.h | 1 + layout/style/ImageLoader.cpp | 6 +- layout/svg/nsSVGImageFrame.cpp | 6 +- layout/xul/base/src/nsImageBoxFrame.cpp | 8 +- .../base/src/tree/src/nsTreeImageListener.cpp | 5 +- toolkit/system/gnome/nsAlertsIconListener.cpp | 4 +- widget/cocoa/nsMenuItemIconX.mm | 4 +- 25 files changed, 124 insertions(+), 281 deletions(-) diff --git a/content/base/src/nsImageLoadingContent.cpp b/content/base/src/nsImageLoadingContent.cpp index 43a49bc6c558..d5a5b1c183db 100644 --- a/content/base/src/nsImageLoadingContent.cpp +++ b/content/base/src/nsImageLoadingContent.cpp @@ -134,7 +134,7 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest, return OnImageIsAnimated(aRequest); } - if (aType == imgINotificationObserver::STOP_REQUEST) { + if (aType == imgINotificationObserver::LOAD_COMPLETE) { // We should definitely have a request here NS_ABORT_IF_FALSE(aRequest, "no request?"); @@ -144,17 +144,15 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest, NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - if (aType != imgINotificationObserver::FRAME_CHANGED) { - LOOP_OVER_OBSERVERS(Notify(aRequest, aType, aData)); - } + LOOP_OVER_OBSERVERS(Notify(aRequest, aType, aData)); - if (aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::SIZE_AVAILABLE) { // Have to check for state changes here, since we might have been in // the LOADING state before. UpdateImageState(true); } - if (aType == imgINotificationObserver::STOP_REQUEST) { + if (aType == imgINotificationObserver::LOAD_COMPLETE) { uint32_t reqStatus; aRequest->GetImageStatus(&reqStatus); nsresult status = diff --git a/content/html/document/src/ImageDocument.cpp b/content/html/document/src/ImageDocument.cpp index ba00cb5c348c..7993afe96432 100644 --- a/content/html/document/src/ImageDocument.cpp +++ b/content/html/document/src/ImageDocument.cpp @@ -508,13 +508,13 @@ ImageDocument::ToggleImageSize() NS_IMETHODIMP ImageDocument::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData) { - if (aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::SIZE_AVAILABLE) { nsCOMPtr image; aRequest->GetImage(getter_AddRefs(image)); return OnStartContainer(aRequest, image); } - if (aType == imgINotificationObserver::STOP_DECODE) { + if (aType == imgINotificationObserver::DECODE_COMPLETE) { if (mImageContent) { // Update the background-color of the image only after the // image has been decoded to prevent flashes of just the @@ -533,7 +533,7 @@ ImageDocument::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aDa } } - if (aType == imgINotificationObserver::STOP_REQUEST) { + if (aType == imgINotificationObserver::LOAD_COMPLETE) { uint32_t reqStatus; aRequest->GetImageStatus(&reqStatus); nsresult status = diff --git a/content/svg/content/src/nsSVGFilters.cpp b/content/svg/content/src/nsSVGFilters.cpp index 643eae711f27..7a076aa3cc83 100644 --- a/content/svg/content/src/nsSVGFilters.cpp +++ b/content/svg/content/src/nsSVGFilters.cpp @@ -5763,7 +5763,7 @@ nsSVGFEImageElement::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRec { nsresult rv = nsImageLoadingContent::Notify(aRequest, aType, aData); - if (aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::SIZE_AVAILABLE) { // Request a decode nsCOMPtr container; aRequest->GetImage(getter_AddRefs(container)); @@ -5771,9 +5771,9 @@ nsSVGFEImageElement::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRec container->StartDecoding(); } - if (aType == imgINotificationObserver::STOP_REQUEST || - aType == imgINotificationObserver::FRAME_CHANGED || - aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::LOAD_COMPLETE || + aType == imgINotificationObserver::FRAME_UPDATE || + aType == imgINotificationObserver::SIZE_AVAILABLE) { Invalidate(); } diff --git a/image/public/imgIDecoderObserver.idl b/image/public/imgIDecoderObserver.idl index e721d59ec915..27b0259a6cc4 100644 --- a/image/public/imgIDecoderObserver.idl +++ b/image/public/imgIDecoderObserver.idl @@ -43,7 +43,7 @@ interface imgIContainer; * @version 0.1 * @see imagelib2 */ -[scriptable, uuid(dad8093d-384b-4923-b83c-351c4e5f9dce)] +[scriptable, uuid(0089cf0c-210c-4b44-9ab0-8099b32bcf64)] interface imgIDecoderObserver : imgIContainerObserver { /** @@ -74,13 +74,6 @@ interface imgIDecoderObserver : imgIContainerObserver */ void onStartContainer(); - /** - * Decode notification. - * - * called when each frame is created. - */ - void onStartFrame(); - /** * Decode notification. * diff --git a/image/public/imgINotificationObserver.idl b/image/public/imgINotificationObserver.idl index ac3b67e07e61..8b9c56bb1889 100644 --- a/image/public/imgINotificationObserver.idl +++ b/image/public/imgINotificationObserver.idl @@ -14,20 +14,16 @@ interface imgIRequest; [ptr] native nsIntRect(nsIntRect); -[scriptable, builtinclass, uuid(9c606ef4-a8e9-45c0-9721-9d6171227ca5)] +[scriptable, builtinclass, uuid(90b3d21c-317d-4d96-93c0-12add64a26bf)] interface imgINotificationObserver : nsISupports { - const long START_REQUEST = 1; - const long START_CONTAINER = 2; - const long START_FRAME = 3; - const long DATA_AVAILABLE = 4; - const long STOP_FRAME = 5; - const long STOP_DECODE = 7; - const long DISCARD = 8; - const long IS_ANIMATED = 9; - const long FRAME_CHANGED = 10; - const long STOP_REQUEST = 11; - const long START_DECODE = 12; + const long SIZE_AVAILABLE = 1; + const long FRAME_UPDATE = 2; + const long FRAME_COMPLETE = 3; + const long LOAD_COMPLETE = 4; + const long DECODE_COMPLETE = 5; + const long DISCARD = 6; + const long IS_ANIMATED = 7; [noscript] void notify(in imgIRequest aProxy, in long aType, [const] in nsIntRect aRect); }; diff --git a/image/public/imgIScriptedNotificationObserver.idl b/image/public/imgIScriptedNotificationObserver.idl index 062a4d4ebc97..6eea5773814a 100644 --- a/image/public/imgIScriptedNotificationObserver.idl +++ b/image/public/imgIScriptedNotificationObserver.idl @@ -8,18 +8,14 @@ interface imgIRequest; -[scriptable, uuid(c5a58b5f-cd1f-4c47-a5ed-5013e0b53e95)] +[scriptable, uuid(10be55b3-2029-41a7-a975-538efed250ed)] interface imgIScriptedNotificationObserver : nsISupports { - void startRequest(in imgIRequest aRequest); - void startContainer(in imgIRequest aRequest); - void startFrame(in imgIRequest aRequest); - void startDecode(in imgIRequest aRequest); - void dataAvailable(in imgIRequest aRequest); - void stopFrame(in imgIRequest aRequest); - void stopDecode(in imgIRequest aRequest); - void stopRequest(in imgIRequest aRequest); + void sizeAvailable(in imgIRequest aRequest); + void frameUpdate(in imgIRequest aRequest); + void frameComplete(in imgIRequest aRequest); + void loadComplete(in imgIRequest aRequest); + void decodeComplete(in imgIRequest aRequest); void discard(in imgIRequest aRequest); void isAnimated(in imgIRequest aRequest); - void frameChanged(in imgIRequest aRequest); }; diff --git a/image/src/Decoder.cpp b/image/src/Decoder.cpp index 9d445849dddc..d0c9dc9c5bf8 100644 --- a/image/src/Decoder.cpp +++ b/image/src/Decoder.cpp @@ -220,10 +220,6 @@ Decoder::PostFrameStart() // reported by the Image. NS_ABORT_IF_FALSE(mFrameCount == mImage.GetNumFrames(), "Decoder frame count doesn't match image's!"); - - // Fire notification - if (mObserver) - mObserver->OnStartFrame(); } void diff --git a/image/src/ScriptedNotificationObserver.cpp b/image/src/ScriptedNotificationObserver.cpp index 0ed0c478f720..e1023cbedf47 100644 --- a/image/src/ScriptedNotificationObserver.cpp +++ b/image/src/ScriptedNotificationObserver.cpp @@ -31,27 +31,19 @@ ScriptedNotificationObserver::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* /*aUnused*/) { - if (aType == imgINotificationObserver::START_REQUEST) - return mInner->StartRequest(aRequest); - if (aType == imgINotificationObserver::START_CONTAINER) - return mInner->StartContainer(aRequest); - if (aType == imgINotificationObserver::START_FRAME) - return mInner->StartFrame(aRequest); - if (aType == imgINotificationObserver::START_DECODE) - return mInner->StartDecode(aRequest); - if (aType == imgINotificationObserver::DATA_AVAILABLE) - return mInner->DataAvailable(aRequest); - if (aType == imgINotificationObserver::STOP_FRAME) - return mInner->StopFrame(aRequest); - if (aType == imgINotificationObserver::STOP_DECODE) - return mInner->StopDecode(aRequest); - if (aType == imgINotificationObserver::STOP_REQUEST) - return mInner->StopRequest(aRequest); + if (aType == imgINotificationObserver::SIZE_AVAILABLE) + return mInner->SizeAvailable(aRequest); + if (aType == imgINotificationObserver::FRAME_UPDATE) + return mInner->FrameUpdate(aRequest); + if (aType == imgINotificationObserver::FRAME_COMPLETE) + return mInner->FrameComplete(aRequest); + if (aType == imgINotificationObserver::DECODE_COMPLETE) + return mInner->DecodeComplete(aRequest); + if (aType == imgINotificationObserver::LOAD_COMPLETE) + return mInner->LoadComplete(aRequest); if (aType == imgINotificationObserver::DISCARD) return mInner->Discard(aRequest); if (aType == imgINotificationObserver::IS_ANIMATED) return mInner->IsAnimated(aRequest); - if (aType == imgINotificationObserver::FRAME_CHANGED) - return mInner->FrameChanged(aRequest); return NS_OK; } diff --git a/image/src/imgRequestProxy.cpp b/image/src/imgRequestProxy.cpp index 60feffbc2896..f6db557569a0 100644 --- a/image/src/imgRequestProxy.cpp +++ b/image/src/imgRequestProxy.cpp @@ -612,30 +612,8 @@ NS_IMETHODIMP imgRequestProxy::GetHasTransferredData(bool* hasData) return NS_OK; } -void imgRequestProxy::FrameChanged(const nsIntRect *dirtyRect) -{ - LOG_FUNC(gImgLog, "imgRequestProxy::FrameChanged"); - - if (mListener && !mCanceled) { - // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->Notify(this, imgINotificationObserver::FRAME_CHANGED, dirtyRect); - } -} - /** imgIDecoderObserver methods **/ -void imgRequestProxy::OnStartDecode() -{ - LOG_FUNC(gImgLog, "imgRequestProxy::OnStartDecode"); - - if (mListener && !mCanceled) { - // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->Notify(this, imgINotificationObserver::START_DECODE, nullptr); - } -} - void imgRequestProxy::OnStartContainer() { LOG_FUNC(gImgLog, "imgRequestProxy::OnStartContainer"); @@ -643,30 +621,19 @@ void imgRequestProxy::OnStartContainer() if (mListener && !mCanceled && !mSentStartContainer) { // Hold a ref to the listener while we call it, just in case. nsCOMPtr kungFuDeathGrip(mListener); - mListener->Notify(this, imgINotificationObserver::START_CONTAINER, nullptr); + mListener->Notify(this, imgINotificationObserver::SIZE_AVAILABLE, nullptr); mSentStartContainer = true; } } -void imgRequestProxy::OnStartFrame() -{ - LOG_FUNC(gImgLog, "imgRequestProxy::OnStartFrame"); - - if (mListener && !mCanceled) { - // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->Notify(this, imgINotificationObserver::START_FRAME, nullptr); - } -} - -void imgRequestProxy::OnDataAvailable(const nsIntRect * rect) +void imgRequestProxy::OnFrameUpdate(const nsIntRect * rect) { LOG_FUNC(gImgLog, "imgRequestProxy::OnDataAvailable"); if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. nsCOMPtr kungFuDeathGrip(mListener); - mListener->Notify(this, imgINotificationObserver::DATA_AVAILABLE, rect); + mListener->Notify(this, imgINotificationObserver::FRAME_UPDATE, rect); } } @@ -677,7 +644,7 @@ void imgRequestProxy::OnStopFrame() if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. nsCOMPtr kungFuDeathGrip(mListener); - mListener->Notify(this, imgINotificationObserver::STOP_FRAME, nullptr); + mListener->Notify(this, imgINotificationObserver::FRAME_COMPLETE, nullptr); } } @@ -688,7 +655,7 @@ void imgRequestProxy::OnStopDecode() if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. nsCOMPtr kungFuDeathGrip(mListener); - mListener->Notify(this, imgINotificationObserver::STOP_DECODE, nullptr); + mListener->Notify(this, imgINotificationObserver::DECODE_COMPLETE, nullptr); } // Multipart needs reset for next OnStartContainer @@ -724,14 +691,6 @@ void imgRequestProxy::OnStartRequest() GetName(name); LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnStartRequest", "name", name.get()); #endif - - // Notify even if mCanceled, since OnStartRequest is guaranteed by the - // nsIStreamListener contract so it makes sense to do the same here. - if (mListener) { - // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->Notify(this, imgINotificationObserver::START_REQUEST, nullptr); - } } void imgRequestProxy::OnStopRequest(bool lastPart) @@ -749,7 +708,7 @@ void imgRequestProxy::OnStopRequest(bool lastPart) if (mListener) { // Hold a ref to the listener while we call it, just in case. nsCOMPtr kungFuDeathGrip(mListener); - mListener->Notify(this, imgINotificationObserver::STOP_REQUEST, nullptr); + mListener->Notify(this, imgINotificationObserver::LOAD_COMPLETE, nullptr); } // If we're expecting more data from a multipart channel, re-add ourself diff --git a/image/src/imgRequestProxy.h b/image/src/imgRequestProxy.h index 6ab22229da26..9b3f85d6f093 100644 --- a/image/src/imgRequestProxy.h +++ b/image/src/imgRequestProxy.h @@ -132,18 +132,13 @@ protected: // notifications. /* non-virtual imgIDecoderObserver methods */ - void OnStartDecode (); void OnStartContainer (); - void OnStartFrame (); - void OnDataAvailable (const nsIntRect * aRect); + void OnFrameUpdate (const nsIntRect * aRect); void OnStopFrame (); void OnStopDecode (); void OnDiscard (); void OnImageIsAnimated (); - /* non-virtual imgIContainerObserver methods */ - void FrameChanged(const nsIntRect *aDirtyRect); - /* non-virtual sort-of-nsIRequestObserver methods */ void OnStartRequest(); void OnStopRequest(bool aLastPart); diff --git a/image/src/imgStatusTracker.cpp b/image/src/imgStatusTracker.cpp index 10b870d424f9..305088053f45 100644 --- a/image/src/imgStatusTracker.cpp +++ b/image/src/imgStatusTracker.cpp @@ -46,20 +46,12 @@ NS_IMETHODIMP imgStatusTrackerObserver::FrameChanged(const nsIntRect *dirtyRect) /** imgIDecoderObserver methods **/ -/* void onStartDecode (); */ NS_IMETHODIMP imgStatusTrackerObserver::OnStartDecode() { LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStartDecode"); NS_ABORT_IF_FALSE(mTracker->GetImage(), "OnStartDecode callback before we've created our image"); - mTracker->RecordStartDecode(); - - nsTObserverArray::ForwardIterator iter(mTracker->mConsumers); - while (iter.HasMore()) { - mTracker->SendStartDecode(iter.GetNext()); - } - if (!mTracker->GetRequest()->GetMultipart()) { MOZ_ASSERT(!mTracker->mBlockingOnload); mTracker->mBlockingOnload = true; @@ -105,23 +97,6 @@ NS_IMETHODIMP imgStatusTrackerObserver::OnStartContainer() return NS_OK; } -/* void onStartFrame (); */ -NS_IMETHODIMP imgStatusTrackerObserver::OnStartFrame() -{ - LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStartFrame"); - NS_ABORT_IF_FALSE(mTracker->GetImage(), - "OnStartFrame callback before we've created our image"); - - mTracker->RecordStartFrame(); - - nsTObserverArray::ForwardIterator iter(mTracker->mConsumers); - while (iter.HasMore()) { - mTracker->SendStartFrame(iter.GetNext()); - } - - return NS_OK; -} - /* [noscript] void onDataAvailable ([const] in nsIntRect rect); */ NS_IMETHODIMP imgStatusTrackerObserver::OnDataAvailable(const nsIntRect * rect) { @@ -420,28 +395,22 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy) if (mState & stateHasSize) proxy->OnStartContainer(); - // OnStartDecode - if (mState & stateDecodeStarted) - proxy->OnStartDecode(); - // BlockOnload if (mState & stateBlockingOnload) proxy->BlockOnload(); if (mImage) { int16_t imageType = mImage->GetType(); - // Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame) + // Send frame messages (OnDataAvailable, OnStopFrame) if (imageType == imgIContainer::TYPE_VECTOR || static_cast(mImage)->GetNumFrames() > 0) { - proxy->OnStartFrame(); - // OnDataAvailable // XXX - Should only send partial rects here, but that needs to // wait until we fix up the observer interface nsIntRect r; mImage->GetCurrentFrameRect(r); - proxy->OnDataAvailable(&r); + proxy->OnFrameUpdate(&r); if (mState & stateFrameStopped) proxy->OnStopFrame(); @@ -529,25 +498,10 @@ void imgStatusTracker::RecordDecoded() { NS_ABORT_IF_FALSE(mImage, "RecordDecoded called before we have an Image"); - mState |= stateDecodeStarted | stateDecodeStopped | stateFrameStopped; + mState |= stateDecodeStopped | stateFrameStopped; mImageStatus |= imgIRequest::STATUS_FRAME_COMPLETE | imgIRequest::STATUS_DECODE_COMPLETE; } -/* non-virtual imgIDecoderObserver methods */ -void -imgStatusTracker::RecordStartDecode() -{ - NS_ABORT_IF_FALSE(mImage, "RecordStartDecode without an Image"); - mState |= stateDecodeStarted; -} - -void -imgStatusTracker::SendStartDecode(imgRequestProxy* aProxy) -{ - if (!aProxy->NotificationsDeferred()) - aProxy->OnStartDecode(); -} - void imgStatusTracker::RecordStartContainer(imgIContainer* aContainer) { @@ -566,21 +520,6 @@ imgStatusTracker::SendStartContainer(imgRequestProxy* aProxy) aProxy->OnStartContainer(); } -void -imgStatusTracker::RecordStartFrame() -{ - NS_ABORT_IF_FALSE(mImage, "RecordStartFrame called before we have an Image"); - // no bookkeeping necessary here - this is implied by imgIContainer's number - // of frames -} - -void -imgStatusTracker::SendStartFrame(imgRequestProxy* aProxy) -{ - if (!aProxy->NotificationsDeferred()) - aProxy->OnStartFrame(); -} - void imgStatusTracker::RecordDataAvailable() { @@ -595,7 +534,7 @@ imgStatusTracker::SendDataAvailable(imgRequestProxy* aProxy, const nsIntRect* aRect) { if (!aProxy->NotificationsDeferred()) - aProxy->OnDataAvailable(aRect); + aProxy->OnFrameUpdate(aRect); } @@ -642,7 +581,7 @@ imgStatusTracker::RecordDiscard() NS_ABORT_IF_FALSE(mImage, "RecordDiscard called before we have an Image"); // Clear the state bits we no longer deserve. - uint32_t stateBitsToClear = stateDecodeStarted | stateDecodeStopped; + uint32_t stateBitsToClear = stateDecodeStopped; mState &= ~stateBitsToClear; // Clear the status bits we no longer deserve. @@ -691,7 +630,7 @@ imgStatusTracker::SendFrameChanged(imgRequestProxy* aProxy, const nsIntRect* aDirtyRect) { if (!aProxy->NotificationsDeferred()) - aProxy->FrameChanged(aDirtyRect); + aProxy->OnFrameUpdate(aDirtyRect); } /* non-virtual sort-of-nsIRequestObserver methods */ @@ -704,7 +643,6 @@ imgStatusTracker::RecordStartRequest() mImageStatus &= ~imgIRequest::STATUS_LOAD_COMPLETE; mImageStatus &= ~imgIRequest::STATUS_FRAME_COMPLETE; mState &= ~stateRequestStarted; - mState &= ~stateDecodeStarted; mState &= ~stateDecodeStopped; mState &= ~stateRequestStopped; mState &= ~stateBlockingOnload; diff --git a/image/src/imgStatusTracker.h b/image/src/imgStatusTracker.h index a7833d716c21..a46381ceba3a 100644 --- a/image/src/imgStatusTracker.h +++ b/image/src/imgStatusTracker.h @@ -32,7 +32,6 @@ class Image; enum { stateRequestStarted = PR_BIT(0), stateHasSize = PR_BIT(1), - stateDecodeStarted = PR_BIT(2), stateDecodeStopped = PR_BIT(3), stateFrameStopped = PR_BIT(4), stateRequestStopped = PR_BIT(5), @@ -149,12 +148,8 @@ public: void RecordDecoded(); /* non-virtual imgIDecoderObserver methods */ - void RecordStartDecode(); - void SendStartDecode(imgRequestProxy* aProxy); void RecordStartContainer(imgIContainer* aContainer); void SendStartContainer(imgRequestProxy* aProxy); - void RecordStartFrame(); - void SendStartFrame(imgRequestProxy* aProxy); void RecordDataAvailable(); void SendDataAvailable(imgRequestProxy* aProxy, const nsIntRect* aRect); void RecordStopFrame(); diff --git a/image/test/mochitest/imgutils.js b/image/test/mochitest/imgutils.js index e9855bc45096..b45604caae3c 100644 --- a/image/test/mochitest/imgutils.js +++ b/image/test/mochitest/imgutils.js @@ -124,15 +124,11 @@ function getImagePref(pref) // JS implementation of imgIScriptedNotificationObserver with stubs for all of its methods. function ImageDecoderObserverStub() { - this.startRequest = function startRequest(aRequest) {} - this.startDecode = function startDecode(aRequest) {} - this.startContainer = function startContainer(aRequest) {} - this.startFrame = function startFrame(aRequest) {} - this.stopFrame = function stopFrame(aRequest) {} - this.stopDecode = function stopDecode(aRequest) {} - this.stopRequest = function stopRequest(aRequest) {} - this.dataAvailable = function dataAvailable(aRequest) {} + this.sizeAvailable = function sizeAvailable(aRequest) {} + this.frameComplete = function frameComplete(aRequest) {} + this.decodeComplete = function decodeComplete(aRequest) {} + this.loadComplete = function loadComplete(aRequest) {} + this.frameUpdate = function frameUpdate(aRequest) {} this.discard = function discard(aRequest) {} this.isAnimated = function isAnimated(aRequest) {} - this.frameChanged = function frameChanged(aRequest) {} } diff --git a/image/test/mochitest/test_animSVGImage.html b/image/test/mochitest/test_animSVGImage.html index a1799b3f87e8..2cb7fefa6048 100644 --- a/image/test/mochitest/test_animSVGImage.html +++ b/image/test/mochitest/test_animSVGImage.html @@ -91,7 +91,7 @@ function main() { // Create, customize & attach decoder observer observer = new ImageDecoderObserverStub(); - observer.stopFrame = myOnStopFrame; + observer.frameComplete = myOnStopFrame; gMyDecoderObserver = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) .createScriptedObserver(observer); diff --git a/image/test/unit/async_load_tests.js b/image/test/unit/async_load_tests.js index 819d4343b89d..9f024141cac3 100644 --- a/image/test/unit/async_load_tests.js +++ b/image/test/unit/async_load_tests.js @@ -53,13 +53,10 @@ function checkClone(other_listener, aRequest) // Ensure that all the callbacks were called on aRequest. function checkAllCallbacks(listener, aRequest) { - do_check_neq(listener.state & START_REQUEST, 0); - do_check_neq(listener.state & START_DECODE, 0); - do_check_neq(listener.state & START_CONTAINER, 0); - do_check_neq(listener.state & START_FRAME, 0); - do_check_neq(listener.state & STOP_FRAME, 0); - do_check_neq(listener.state & STOP_DECODE, 0); - do_check_neq(listener.state & STOP_REQUEST, 0); + do_check_neq(listener.state & SIZE_AVAILABLE, 0); + do_check_neq(listener.state & FRAME_COMPLETE, 0); + do_check_neq(listener.state & DECODE_COMPLETE, 0); + do_check_neq(listener.state & LOAD_COMPLETE, 0); do_check_eq(listener.state, ALL_BITS); do_test_finished(); @@ -115,10 +112,10 @@ function firstLoadDone(oldlistener, aRequest) function getChannelLoadImageStartCallback(streamlistener) { return function channelLoadStart(imglistener, aRequest) { - // We must not have received any status before we get this start callback. + // We must not have received all status before we get this start callback. // If we have, we've broken people's expectations by delaying events from a // channel we were given. - do_check_eq(streamlistener.requestStatus, 0); + do_check_eq(streamlistener.requestStatus & STOP_REQUEST, 0); checkClone(imglistener, aRequest); } diff --git a/image/test/unit/image_load_helpers.js b/image/test/unit/image_load_helpers.js index 6c00b384b752..96f7d7189585 100644 --- a/image/test/unit/image_load_helpers.js +++ b/image/test/unit/image_load_helpers.js @@ -2,64 +2,47 @@ * Helper structures to track callbacks from image and channel loads. */ -// One bit per callback that imageListener below implements. Stored in -// ImageListener.state. -// START_REQUEST and STOP_REQUEST are also reused by ChannelListener, and +// START_REQUEST and STOP_REQUEST are used by ChannelListener, and // stored in ChannelListener.requestStatus. const START_REQUEST = 0x01; -const START_DECODE = 0x02; -const START_CONTAINER = 0x04; -const START_FRAME = 0x08; -const STOP_FRAME = 0x10; -const STOP_DECODE = 0x20; -const STOP_REQUEST = 0x40; -const ALL_BITS = START_REQUEST | START_DECODE | START_CONTAINER | START_FRAME | - STOP_FRAME | STOP_DECODE | STOP_REQUEST; +const STOP_REQUEST = 0x02; +const DATA_AVAILABLE = 0x04; + +// One bit per callback that imageListener below implements. Stored in +// ImageListener.state. +const SIZE_AVAILABLE = 0x01; +const FRAME_UPDATE = 0x02; +const FRAME_COMPLETE = 0x04; +const LOAD_COMPLETE = 0x08; +const DECODE_COMPLETE = 0x10; +const ALL_BITS = SIZE_AVAILABLE | FRAME_COMPLETE | DECODE_COMPLETE | LOAD_COMPLETE; // An implementation of imgIDecoderObserver with the ability to call specified // functions on onStartRequest and onStopRequest. function ImageListener(start_callback, stop_callback) { - this.startRequest = function onStartRequest(aRequest) + this.sizeAvailable = function onSizeAvailable(aRequest) { do_check_false(this.synchronous); - this.state |= START_REQUEST; + this.state |= SIZE_AVAILABLE; if (this.start_callback) this.start_callback(this, aRequest); } - this.startDecode = function onStartDecode(aRequest) + this.frameComplete = function onFrameComplete(aRequest) { do_check_false(this.synchronous); - this.state |= START_DECODE; + this.state |= FRAME_COMPLETE; } - this.startContainer = function onStartContainer(aRequest) + this.decodeComplete = function onDecodeComplete(aRequest) { do_check_false(this.synchronous); - this.state |= START_CONTAINER; + this.state |= DECODE_COMPLETE; } - this.startFrame = function onStartFrame(aRequest) - { - do_check_false(this.synchronous); - - this.state |= START_FRAME; - } - this.stopFrame = function onStopFrame(aRequest) - { - do_check_false(this.synchronous); - - this.state |= STOP_FRAME; - } - this.stopDecode = function onStopDecode(aRequest) - { - do_check_false(this.synchronous); - - this.state |= STOP_DECODE; - } - this.stopRequest = function onStopRequest(aRequest) + this.loadComplete = function onLoadcomplete(aRequest) { do_check_false(this.synchronous); @@ -67,12 +50,15 @@ function ImageListener(start_callback, stop_callback) // reference loops! aRequest.cancelAndForgetObserver(0); - this.state |= STOP_REQUEST; + this.state |= LOAD_COMPLETE; if (this.stop_callback) this.stop_callback(this, aRequest); } - this.dataAvailable = function onDataAvailable(aRequest) + this.frameUpdate = function onFrameUpdate(aRequest) + { + } + this.isAnimated = function onIsAnimated() { } @@ -111,6 +97,8 @@ function ChannelListener() { if (this.outputListener) this.outputListener.onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount); + + this.requestStatus |= DATA_AVAILABLE; } this.onStopRequest = function onStopRequest(aRequest, aContext, aStatusCode) diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp index b9f54682435a..0f0d822ca2c5 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -1434,14 +1434,13 @@ nsBulletFrame::GetPrefWidth(nsRenderingContext *aRenderingContext) NS_IMETHODIMP nsBulletFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { - if (aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::SIZE_AVAILABLE) { nsCOMPtr image; aRequest->GetImage(getter_AddRefs(image)); return OnStartContainer(aRequest, image); } - if (aType == imgINotificationObserver::DATA_AVAILABLE || - aType == imgINotificationObserver::FRAME_CHANGED) { + if (aType == imgINotificationObserver::FRAME_UPDATE) { // The image has changed. // Invalidate the entire content area. Maybe it's not optimal but it's simple and // always correct, and I'll be a stunned mullet if it ever matters for performance diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index e43a16c72ed8..75be7b649fa1 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -140,7 +140,8 @@ nsImageFrame::nsImageFrame(nsStyleContext* aContext) : ImageFrameSuper(aContext), mComputedSize(0, 0), mIntrinsicRatio(0, 0), - mDisplayingIcon(false) + mDisplayingIcon(false), + mFirstFrameComplete(false) { // We assume our size is not constrained and we haven't gotten an // initial reflow yet, so don't touch those flags. @@ -528,17 +529,21 @@ nsImageFrame::ShouldCreateImageFrameFor(Element* aElement, nsresult nsImageFrame::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData) { - if (aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::SIZE_AVAILABLE) { nsCOMPtr image; aRequest->GetImage(getter_AddRefs(image)); return OnStartContainer(aRequest, image); } - if (aType == imgINotificationObserver::DATA_AVAILABLE) { + if (aType == imgINotificationObserver::FRAME_UPDATE) { return OnDataAvailable(aRequest, aData); } - if (aType == imgINotificationObserver::STOP_REQUEST) { + if (aType == imgINotificationObserver::FRAME_COMPLETE) { + mFirstFrameComplete = true; + } + + if (aType == imgINotificationObserver::LOAD_COMPLETE) { uint32_t imgStatus; aRequest->GetImageStatus(&imgStatus); nsresult status = @@ -546,12 +551,6 @@ nsImageFrame::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aDat return OnStopRequest(aRequest, status); } - if (aType == imgINotificationObserver::FRAME_CHANGED) { - nsCOMPtr image; - aRequest->GetImage(getter_AddRefs(image)); - return FrameChanged(aRequest, image); - } - return NS_OK; } @@ -596,6 +595,12 @@ nsresult nsImageFrame::OnDataAvailable(imgIRequest *aRequest, const nsIntRect *aRect) { + if (mFirstFrameComplete) { + nsCOMPtr container; + aRequest->GetImage(getter_AddRefs(container)); + return FrameChanged(aRequest, container); + } + // XXX do we need to make sure that the reflow from the // OnStartContainer has been processed before we start calling // invalidate? @@ -625,7 +630,7 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest, InvalidateFrameWithRect(invalid, nsDisplayItem::TYPE_IMAGE); InvalidateFrameWithRect(invalid, nsDisplayItem::TYPE_ALT_FEEDBACK); } - + return NS_OK; } @@ -1976,8 +1981,8 @@ void nsImageFrame::IconLoad::GetPrefs() NS_IMETHODIMP nsImageFrame::IconLoad::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { - if (aType != imgINotificationObserver::STOP_REQUEST && - aType != imgINotificationObserver::FRAME_CHANGED) { + if (aType != imgINotificationObserver::LOAD_COMPLETE && + aType != imgINotificationObserver::FRAME_UPDATE) { return NS_OK; } diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index a92c342f7a60..702e46c24128 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -284,6 +284,7 @@ private: nsSize mIntrinsicRatio; bool mDisplayingIcon; + bool mFirstFrameComplete; static nsIIOService* sIOService; diff --git a/layout/style/ImageLoader.cpp b/layout/style/ImageLoader.cpp index d3f2ae216838..9cd885a9a077 100644 --- a/layout/style/ImageLoader.cpp +++ b/layout/style/ImageLoader.cpp @@ -341,7 +341,7 @@ NS_INTERFACE_MAP_END NS_IMETHODIMP ImageLoader::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { - if (aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::SIZE_AVAILABLE) { nsCOMPtr image; aRequest->GetImage(getter_AddRefs(image)); return OnStartContainer(aRequest, image); @@ -351,11 +351,11 @@ ImageLoader::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData return OnImageIsAnimated(aRequest); } - if (aType == imgINotificationObserver::STOP_FRAME) { + if (aType == imgINotificationObserver::LOAD_COMPLETE) { return OnStopFrame(aRequest); } - if (aType == imgINotificationObserver::FRAME_CHANGED) { + if (aType == imgINotificationObserver::FRAME_UPDATE) { return FrameChanged(aRequest); } diff --git a/layout/svg/nsSVGImageFrame.cpp b/layout/svg/nsSVGImageFrame.cpp index eff14c78dcc5..9dd8ae38ac8a 100644 --- a/layout/svg/nsSVGImageFrame.cpp +++ b/layout/svg/nsSVGImageFrame.cpp @@ -563,18 +563,18 @@ nsSVGImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect if (!mFrame) return NS_ERROR_FAILURE; - if (aType == imgINotificationObserver::STOP_REQUEST) { + if (aType == imgINotificationObserver::LOAD_COMPLETE) { nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame); } - if (aType == imgINotificationObserver::FRAME_CHANGED) { + if (aType == imgINotificationObserver::FRAME_UPDATE) { // No new dimensions, so we don't need to call // nsSVGUtils::InvalidateAndScheduleBoundsUpdate. nsSVGEffects::InvalidateRenderingObservers(mFrame); nsSVGUtils::InvalidateBounds(mFrame); } - if (aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::SIZE_AVAILABLE) { // Called once the resource's dimensions have been obtained. aRequest->GetImage(getter_AddRefs(mFrame->mImageContainer)); nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame); diff --git a/layout/xul/base/src/nsImageBoxFrame.cpp b/layout/xul/base/src/nsImageBoxFrame.cpp index 3263bdde573d..8d0563e12e87 100644 --- a/layout/xul/base/src/nsImageBoxFrame.cpp +++ b/layout/xul/base/src/nsImageBoxFrame.cpp @@ -580,17 +580,17 @@ nsImageBoxFrame::GetFrameName(nsAString& aResult) const nsresult nsImageBoxFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { - if (aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::SIZE_AVAILABLE) { nsCOMPtr image; aRequest->GetImage(getter_AddRefs(image)); return OnStartContainer(aRequest, image); } - if (aType == imgINotificationObserver::STOP_DECODE) { + if (aType == imgINotificationObserver::DECODE_COMPLETE) { return OnStopDecode(aRequest); } - if (aType == imgINotificationObserver::STOP_REQUEST) { + if (aType == imgINotificationObserver::LOAD_COMPLETE) { uint32_t imgStatus; aRequest->GetImageStatus(&imgStatus); nsresult status = @@ -602,7 +602,7 @@ nsImageBoxFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* a return OnImageIsAnimated(aRequest); } - if (aType == imgINotificationObserver::FRAME_CHANGED) { + if (aType == imgINotificationObserver::FRAME_UPDATE) { return FrameChanged(aRequest); } diff --git a/layout/xul/base/src/tree/src/nsTreeImageListener.cpp b/layout/xul/base/src/tree/src/nsTreeImageListener.cpp index c8ccf4b3a823..1680a4b5bc59 100644 --- a/layout/xul/base/src/tree/src/nsTreeImageListener.cpp +++ b/layout/xul/base/src/tree/src/nsTreeImageListener.cpp @@ -29,15 +29,14 @@ nsTreeImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRec return mTreeFrame ? mTreeFrame->OnImageIsAnimated(aRequest) : NS_OK; } - if (aType == imgINotificationObserver::START_CONTAINER) { + if (aType == imgINotificationObserver::SIZE_AVAILABLE) { // Ensure the animation (if any) is started. Note: There is no // corresponding call to Decrement for this. This Increment will be // 'cleaned up' by the Request when it is destroyed, but only then. aRequest->IncrementAnimationConsumers(); } - if (aType == imgINotificationObserver::DATA_AVAILABLE || - aType == imgINotificationObserver::FRAME_CHANGED) { + if (aType == imgINotificationObserver::FRAME_UPDATE) { Invalidate(); } diff --git a/toolkit/system/gnome/nsAlertsIconListener.cpp b/toolkit/system/gnome/nsAlertsIconListener.cpp index 70bff3be5e62..f53d659b3aca 100644 --- a/toolkit/system/gnome/nsAlertsIconListener.cpp +++ b/toolkit/system/gnome/nsAlertsIconListener.cpp @@ -92,11 +92,11 @@ nsAlertsIconListener::~nsAlertsIconListener() NS_IMETHODIMP nsAlertsIconListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { - if (aType == imgINotificationObserver::STOP_REQUEST) { + if (aType == imgINotificationObserver::LOAD_COMPLETE) { return OnStopRequest(aRequest); } - if (aType == imgINotificationObserver::STOP_FRAME) { + if (aType == imgINotificationObserver::FRAME_COMPLETE) { return OnStopFrame(aRequest); } diff --git a/widget/cocoa/nsMenuItemIconX.mm b/widget/cocoa/nsMenuItemIconX.mm index 470b81cf6007..deee6d083d28 100644 --- a/widget/cocoa/nsMenuItemIconX.mm +++ b/widget/cocoa/nsMenuItemIconX.mm @@ -324,11 +324,11 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI) NS_IMETHODIMP nsMenuItemIconX::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { - if (aType == imgINotificationObserver::STOP_FRAME) { + if (aType == imgINotificationObserver::FRAME_COMPLETE) { return OnStopFrame(aRequest); } - if (aType == imgINotificationObserver::STOP_REQUEST) { + if (aType == imgINotificationObserver::LOAD_COMPLETE) { if (mIconRequest && mIconRequest == aRequest) { mIconRequest->Cancel(NS_BINDING_ABORTED); mIconRequest = nullptr;