Backed out changeset 2eefd792306d (bug 1118655)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 12 Jan 2015 15:35:14 +0100
changeset 249187 2adce13cb838fcaba2e401de85cb461199a4ba2a
parent 249186 48028fd5c776f176701445fa927004ed2b4f8ae8
child 249188 e56e7cffe0f4578016f3c976325a72adadda89e9
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1118655
milestone37.0a1
backs out2eefd792306d61b25a5215828f1a76da193b1cb7
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 2eefd792306d (bug 1118655)
image/src/ImageFactory.cpp
image/src/RasterImage.cpp
image/src/RasterImage.h
layout/generic/nsImageFrame.cpp
layout/xul/nsImageBoxFrame.cpp
modules/libpref/init/all.js
toolkit/system/gnome/nsAlertsIconListener.cpp
widget/cocoa/nsMenuItemIconX.mm
--- a/image/src/ImageFactory.cpp
+++ b/image/src/ImageFactory.cpp
@@ -40,18 +40,17 @@ ShouldDownscaleDuringDecode(const nsCStr
 
 static uint32_t
 ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart)
 {
   nsresult rv;
 
   // We default to the static globals.
   bool isDiscardable = gfxPrefs::ImageMemDiscardable();
-  bool doDecodeOnDraw = gfxPrefs::ImageMemDecodeOnDraw() &&
-                        gfxPrefs::AsyncPanZoomEnabled();
+  bool doDecodeOnDraw = gfxPrefs::ImageMemDecodeOnDraw();
   bool doDownscaleDuringDecode = gfxPrefs::ImageDownscaleDuringDecodeEnabled();
 
   // We want UI to be as snappy as possible and not to flicker. Disable
   // discarding and decode-on-draw for chrome URLS.
   bool isChrome = false;
   rv = uri->SchemeIs("chrome", &isChrome);
   if (NS_SUCCEEDED(rv) && isChrome) {
     isDiscardable = doDecodeOnDraw = false;
@@ -71,21 +70,16 @@ ComputeImageFlags(ImageURL* uri, const n
   }
 
   // For multipart/x-mixed-replace, we basically want a direct channel to the
   // decoder. Disable everything for this case.
   if (isMultiPart) {
     isDiscardable = doDecodeOnDraw = doDownscaleDuringDecode = false;
   }
 
-  // We don't want decode-on-draw without downscale-during-decode.
-  if (!doDownscaleDuringDecode) {
-    doDecodeOnDraw = false;
-  }
-
   // We have all the information we need.
   uint32_t imageFlags = Image::INIT_FLAG_NONE;
   if (isDiscardable) {
     imageFlags |= Image::INIT_FLAG_DISCARDABLE;
   }
   if (doDecodeOnDraw) {
     imageFlags |= Image::INIT_FLAG_DECODE_ON_DRAW;
   }
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -30,17 +30,16 @@
 #include "nsBMPDecoder.h"
 #include "nsICODecoder.h"
 #include "nsIconDecoder.h"
 
 #include "gfxContext.h"
 
 #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"
 #include "mozilla/Services.h"
 #include <stdint.h>
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/ClearOnShutdown.h"
@@ -269,17 +268,16 @@ RasterImage::RasterImage(ProgressTracker
 #ifdef DEBUG
   mFramesNotified(0),
 #endif
   mSourceBuffer(new SourceBuffer()),
   mFrameCount(0),
   mNotifyProgress(NoProgress),
   mNotifying(false),
   mHasSize(false),
-  mBlockedOnload(false),
   mDecodeOnDraw(false),
   mTransient(false),
   mDiscardable(false),
   mHasSourceData(false),
   mHasBeenDecoded(false),
   mPendingAnimation(false),
   mAnimationFinished(false),
   mWantFullDecode(false)
@@ -1162,68 +1160,36 @@ RasterImage::OnImageDataComplete(nsIRequ
     finalStatus = aStatus;
   }
 
   // If loading failed, report an error.
   if (NS_FAILED(finalStatus)) {
     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 aOffset,
+                                  uint64_t,
                                   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;
   rv = aInStr->ReadSegments(WriteToSourceBuffer, this, aCount, &bytesRead);
 
   NS_ABORT_IF_FALSE(bytesRead == aCount || HasError() || NS_FAILED(rv),
     "WriteToSourceBuffer should consume everything if ReadSegments succeeds or "
     "the image must be in error!");
@@ -1433,38 +1399,28 @@ RasterImage::WantDecodedFrames(const nsI
   Decode(DecodeStrategy::ASYNC, Some(aSize), aFlags);
 }
 
 //******************************************************************************
 /* void requestDecode() */
 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);
 }
 
 /* void startDecode() */
 NS_IMETHODIMP
 RasterImage::StartDecoding()
 {
   if (!NS_IsMainThread()) {
     return NS_DispatchToMainThread(
       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);
 }
 
 NS_IMETHODIMP
 RasterImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -1495,17 +1451,17 @@ RasterImage::RequestDecodeForSize(const 
 
   return NS_OK;
 }
 
 bool
 RasterImage::IsDecoded()
 {
   // XXX(seth): We need to get rid of this; it's not reliable.
-  return mHasBeenDecoded || mError || (mDecodeOnDraw && mHasSourceData);
+  return mHasBeenDecoded || mError;
 }
 
 NS_IMETHODIMP
 RasterImage::Decode(DecodeStrategy aStrategy,
                     const Maybe<nsIntSize>& aSize,
                     uint32_t aFlags)
 {
   MOZ_ASSERT(!aSize || NS_IsMainThread());
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -237,18 +237,16 @@ public:
                                         nsIInputStream* aInStr,
                                         uint64_t aSourceOffset,
                                         uint32_t aCount) MOZ_OVERRIDE;
   virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
                                        nsISupports* aContext,
                                        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
    * appropriately preallocating the source data buffer.
    *
    * We take this approach rather than having the source data management code do
    * something more complicated (like chunklisting) because HTTP is by far the
    * dominant source of images, and the Content-Length header is quite reliable.
@@ -392,17 +390,16 @@ private: // data
 
   // Notification state. Used to avoid recursive notifications.
   Progress                   mNotifyProgress;
   nsIntRect                  mNotifyInvalidRect;
   bool                       mNotifying:1;
 
   // 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?
   bool                       mHasSourceData:1; // Do we have source data?
   bool                       mHasBeenDecoded:1; // Decoded at least once?
   bool                       mDownscaleDuringDecode:1;
 
   // Whether we're waiting to start animation. If we get a StartAnimation() call
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1420,17 +1420,18 @@ nsDisplayImage::ComputeInvalidationRegio
   nsDisplayImageContainer::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
 }
 
 already_AddRefed<ImageContainer>
 nsDisplayImage::GetContainer(LayerManager* aManager,
                              nsDisplayListBuilder* aBuilder)
 {
   nsRefPtr<ImageContainer> container;
-  mImage->GetImageContainer(aManager, getter_AddRefs(container));
+  nsresult rv = mImage->GetImageContainer(aManager, getter_AddRefs(container));
+  NS_ENSURE_SUCCESS(rv, nullptr);
   return container.forget();
 }
 
 gfxRect
 nsDisplayImage::GetDestRect()
 {
   int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
 
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -429,17 +429,18 @@ nsImageBoxFrame::GetContainer(LayerManag
 
   nsCOMPtr<imgIContainer> imgCon;
   mImageRequest->GetImage(getter_AddRefs(imgCon));
   if (!imgCon) {
     return nullptr;
   }
   
   nsRefPtr<ImageContainer> container;
-  imgCon->GetImageContainer(aManager, getter_AddRefs(container));
+  nsresult rv = imgCon->GetImageContainer(aManager, getter_AddRefs(container));
+  NS_ENSURE_SUCCESS(rv, nullptr);
   return container.forget();
 }
 
 
 //
 // DidSetStyleContext
 //
 // When the style context changes, make sure that all of our image is up to date.
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -3785,17 +3785,17 @@ pref("image.high_quality_upscaling.max_s
 //
 
 // Discards inactive image frames and re-decodes them on demand from
 // compressed data.
 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", false);
+pref("image.mem.decodeondraw", true);
 
 // Allows image locking of decoded image data in content processes.
 pref("image.mem.allow_locking_in_content_processes", true);
 
 // Chunk size for calls to the image decoders
 pref("image.mem.decode_bytes_at_a_time", 16384);
 
 // Minimum timeout for expiring unused images from the surface cache, in
--- a/toolkit/system/gnome/nsAlertsIconListener.cpp
+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
@@ -130,26 +130,16 @@ nsAlertsIconListener::OnLoadComplete(img
     // We have an error getting the image. Display the notification with no icon.
     ShowAlert(nullptr);
 
     // Cancel any pending request
     mIconRequest->Cancel(NS_BINDING_ABORTED);
     mIconRequest = nullptr;
   }
 
-  nsCOMPtr<imgIContainer> image;
-  rv = aRequest->GetImage(getter_AddRefs(image));
-  MOZ_ASSERT(image);
-
-  // Ask the image to decode at it's 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;
 }
 
 nsresult
 nsAlertsIconListener::OnFrameComplete(imgIRequest* aRequest)
 {
   NS_ASSERTION(mIconRequest == aRequest, "aRequest does not match!");
 
@@ -232,16 +222,18 @@ nsAlertsIconListener::StartRequest(const
                                    this, nullptr,
                                    aInPrivateBrowsing ? nsIRequest::LOAD_ANONYMOUS :
                                                         nsIRequest::LOAD_NORMAL,
                                    nullptr, 0 /* use default */,
                                    getter_AddRefs(mIconRequest));
   if (NS_FAILED(rv))
     return rv;
 
+  mIconRequest->StartDecoding();
+
   return NS_OK;
 }
 
 void
 nsAlertsIconListener::SendCallback()
 {
   if (mAlertListener)
     mAlertListener->Observe(nullptr, "alertclickcallback", mAlertCookie.get());
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -309,51 +309,33 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconU
   nsresult rv = loader->LoadImage(aIconURI, nullptr, nullptr,
                                   mozilla::net::RP_Default,
                                   nullptr, loadGroup, this,
                                   nullptr, nsIRequest::LOAD_NORMAL, nullptr,
                                   nsIContentPolicy::TYPE_IMAGE, EmptyString(),
                                   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;
 }
 
 //
 // imgINotificationObserver
 //
 
 NS_IMETHODIMP
 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 it's 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);
   }
 
   if (aType == imgINotificationObserver::DECODE_COMPLETE) {
     if (mIconRequest && mIconRequest == aRequest) {
       mIconRequest->Cancel(NS_BINDING_ABORTED);
       mIconRequest = nullptr;