From 8311ff50b546c5568165ef9a78bb17c445bcd74c Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Thu, 18 Jun 2015 22:04:12 -0700 Subject: [PATCH] Back out 3a06964c6a52 (bug 1174923) for box-decoration-break-first-letter.html failures --- dom/base/nsImageLoadingContent.cpp | 33 ++++++++++++++-- dom/base/nsImageLoadingContent.h | 1 + image/Decoder.cpp | 7 ++-- image/RasterImage.cpp | 8 ++-- image/test/browser/browser_bug666317.js | 38 +++++------------- image/test/mochitest/mochitest.ini | 1 + image/test/mochitest/test_bug512435.html | 49 ++++++++++++++++++++++++ 7 files changed, 99 insertions(+), 38 deletions(-) create mode 100644 image/test/mochitest/test_bug512435.html diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp index 18205ab5d31..9008d4fbbc4 100644 --- a/dom/base/nsImageLoadingContent.cpp +++ b/dom/base/nsImageLoadingContent.cpp @@ -87,6 +87,7 @@ nsImageLoadingContent::nsImageLoadingContent() mBroken(true), mUserDisabled(false), mSuppressed(false), + mFireEventsOnDecode(false), mNewRequestsWillNeedAnimationReset(false), mStateChangerDepth(0), mCurrentRequestRegistered(false), @@ -185,6 +186,18 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest, } if (aType == imgINotificationObserver::DECODE_COMPLETE) { + if (mFireEventsOnDecode) { + mFireEventsOnDecode = false; + + uint32_t reqStatus; + aRequest->GetImageStatus(&reqStatus); + if (reqStatus & imgIRequest::STATUS_ERROR) { + FireEvent(NS_LITERAL_STRING("error")); + } else { + FireEvent(NS_LITERAL_STRING("load")); + } + } + UpdateImageState(true); } @@ -264,11 +277,23 @@ nsImageLoadingContent::OnLoadComplete(imgIRequest* aRequest, nsresult aStatus) } } - // Fire the appropriate DOM event. - if (NS_SUCCEEDED(aStatus)) { - FireEvent(NS_LITERAL_STRING("load")); + // We want to give the decoder a chance to find errors. If we haven't found + // an error yet and we've started decoding, either from the above + // StartDecoding or from some other place, we must only fire these events + // after we finish decoding. + uint32_t reqStatus; + aRequest->GetImageStatus(&reqStatus); + if (NS_SUCCEEDED(aStatus) && !(reqStatus & imgIRequest::STATUS_ERROR) && + (reqStatus & imgIRequest::STATUS_DECODE_STARTED) && + !(reqStatus & imgIRequest::STATUS_DECODE_COMPLETE)) { + mFireEventsOnDecode = true; } else { - FireEvent(NS_LITERAL_STRING("error")); + // Fire the appropriate DOM event. + if (NS_SUCCEEDED(aStatus)) { + FireEvent(NS_LITERAL_STRING("load")); + } else { + FireEvent(NS_LITERAL_STRING("error")); + } } nsCOMPtr thisNode = do_QueryInterface(static_cast(this)); diff --git a/dom/base/nsImageLoadingContent.h b/dom/base/nsImageLoadingContent.h index 8d23d379557..36b130dbc0e 100644 --- a/dom/base/nsImageLoadingContent.h +++ b/dom/base/nsImageLoadingContent.h @@ -410,6 +410,7 @@ private: bool mBroken : 1; bool mUserDisabled : 1; bool mSuppressed : 1; + bool mFireEventsOnDecode : 1; protected: /** diff --git a/image/Decoder.cpp b/image/Decoder.cpp index 9de720488b4..8ce895f052a 100644 --- a/image/Decoder.cpp +++ b/image/Decoder.cpp @@ -83,8 +83,9 @@ Decoder::Init() // No re-initializing MOZ_ASSERT(!mInitialized, "Can't re-initialize a decoder!"); + // Fire OnStartDecode at init time to support bug 512435. if (!IsSizeDecode()) { - mProgress |= FLAG_DECODE_STARTED; + mProgress |= FLAG_DECODE_STARTED | FLAG_ONLOAD_BLOCKED; } // Implementation-specific initialization @@ -272,7 +273,7 @@ Decoder::CompleteDecode() } else { // We're not usable. Record some final progress indicating the error. if (!IsSizeDecode()) { - mProgress |= FLAG_DECODE_COMPLETE; + mProgress |= FLAG_DECODE_COMPLETE | FLAG_ONLOAD_UNBLOCKED; } mProgress |= FLAG_HAS_ERROR; } @@ -623,7 +624,7 @@ Decoder::PostFrameStop(Opacity aFrameOpacity /* = Opacity::TRANSPARENT */, mCurrentFrame->Finish(aFrameOpacity, aDisposalMethod, aTimeout, aBlendMethod); - mProgress |= FLAG_FRAME_COMPLETE; + mProgress |= FLAG_FRAME_COMPLETE | FLAG_ONLOAD_UNBLOCKED; // If we're not sending partial invalidations, then we send an invalidation // here when the first frame is complete. diff --git a/image/RasterImage.cpp b/image/RasterImage.cpp index 440297d3bf5..e986ada7258 100644 --- a/image/RasterImage.cpp +++ b/image/RasterImage.cpp @@ -1211,9 +1211,11 @@ RasterImage::OnImageDataComplete(nsIRequest*, nsISupports*, nsresult aStatus, // to draw. (We may have already sent some of these notifications from // NotifyForDecodeOnlyOnDraw(), but ProgressTracker will ensure no duplicate // notifications get sent.) - loadProgress |= FLAG_DECODE_STARTED | + loadProgress |= FLAG_ONLOAD_BLOCKED | + FLAG_DECODE_STARTED | FLAG_FRAME_COMPLETE | - FLAG_DECODE_COMPLETE; + FLAG_DECODE_COMPLETE | + FLAG_ONLOAD_UNBLOCKED; } // Notify our listeners, which will fire this image's load event. @@ -1232,7 +1234,7 @@ RasterImage::NotifyForDecodeOnlyOnDraw() return; } - NotifyProgress(FLAG_DECODE_STARTED); + NotifyProgress(FLAG_DECODE_STARTED | FLAG_ONLOAD_BLOCKED); } nsresult diff --git a/image/test/browser/browser_bug666317.js b/image/test/browser/browser_bug666317.js index dfc6b91862d..ed7024db399 100644 --- a/image/test/browser/browser_bug666317.js +++ b/image/test/browser/browser_bug666317.js @@ -41,23 +41,6 @@ function forceDecodeImg() { ctx.drawImage(img, 0, 0); } -function runAfterAsyncEvents(aCallback) { - function handlePostMessage(aEvent) { - if (aEvent.data == 'next') { - window.removeEventListener('message', handlePostMessage, false); - aCallback(); - } - } - - window.addEventListener('message', handlePostMessage, false); - - // We'll receive the 'message' event after everything else that's currently in - // the event queue (which is a stronger guarantee than setTimeout, because - // setTimeout events may be coalesced). This lets us ensure that we run - // aCallback *after* any asynchronous events are delivered. - window.postMessage('next', '*'); -} - function test() { // Enable the discarding pref. oldDiscardingPref = prefBranch.getBoolPref('discardable'); @@ -89,13 +72,6 @@ function step2() { // Check that the image is decoded. forceDecodeImg(); - - // The FRAME_COMPLETE notification is delivered asynchronously, so continue - // after we're sure it has been delivered. - runAfterAsyncEvents(() => step3(result, scriptedObserver, clonedRequest)); -} - -function step3(result, scriptedObserver, clonedRequest) { ok(isImgDecoded(), 'Image should initially be decoded.'); // Focus the old tab, then fire a memory-pressure notification. This should @@ -105,12 +81,18 @@ function step3(result, scriptedObserver, clonedRequest) { .getService(Ci.nsIObserverService); os.notifyObservers(null, 'memory-pressure', 'heap-minimize'); - // The DISCARD notification is delivered asynchronously, so continue after - // we're sure it has been delivered. - runAfterAsyncEvents(() => step4(result, scriptedObserver, clonedRequest)); + // The discard notification is delivered asynchronously, so pump the event + // loop before checking. + window.addEventListener('message', function (event) { + if (event.data == 'step3') { + step3(result, scriptedObserver, clonedRequest); + } + }, false); + + window.postMessage('step3', '*'); } -function step4(result, scriptedObserver, clonedRequest) { +function step3(result, scriptedObserver, clonedRequest) { ok(result.wasDiscarded, 'Image should be discarded.'); // And we're done. diff --git a/image/test/mochitest/mochitest.ini b/image/test/mochitest/mochitest.ini index 611d543637a..0ea4e292211 100644 --- a/image/test/mochitest/mochitest.ini +++ b/image/test/mochitest/mochitest.ini @@ -70,6 +70,7 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only [test_bug496292.html] [test_bug497665.html] skip-if = (toolkit == 'android' && processor == 'x86') #x86 only +[test_bug512435.html] [test_bug552605-1.html] [test_bug552605-2.html] [test_bug553982.html] diff --git a/image/test/mochitest/test_bug512435.html b/image/test/mochitest/test_bug512435.html new file mode 100644 index 00000000000..1bffca1647e --- /dev/null +++ b/image/test/mochitest/test_bug512435.html @@ -0,0 +1,49 @@ + + + + + Test for Bug 512435 + + + + + + +Mozilla Bug 512435 + + + +
+
+
+ +