Bug 843895 (Part 4) - Use FrozenImage instead of ExtractFrame for imgRequestProxy::GetStaticRequest. r=joe
authorSeth Fowler <seth@mozilla.com>
Sun, 10 Mar 2013 18:43:38 -0700
changeset 124346 f42a8ed7bf2fa8abaee85875238f65e7a4ac624f
parent 124345 1b269c239a7537c95387cd2c929882a2a2e8d2ab
child 124347 cc45fdc389df2d1161bcc8ff244cff31d562ede0
push id24417
push userryanvm@gmail.com
push dateMon, 11 Mar 2013 23:58:07 +0000
treeherdermozilla-central@7433bc4545c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe
bugs843895
milestone22.0a1
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
Bug 843895 (Part 4) - Use FrozenImage instead of ExtractFrame for imgRequestProxy::GetStaticRequest. r=joe
image/src/ImageFactory.cpp
image/src/ImageFactory.h
image/src/imgRequestProxy.cpp
--- a/image/src/ImageFactory.cpp
+++ b/image/src/ImageFactory.cpp
@@ -16,16 +16,17 @@
 #include "nsMimeTypes.h"
 #include "nsIURI.h"
 #include "nsIRequest.h"
 
 #include "imgIContainer.h"
 #include "imgStatusTracker.h"
 #include "RasterImage.h"
 #include "VectorImage.h"
+#include "FrozenImage.h"
 #include "Image.h"
 
 #include "ImageFactory.h"
 
 namespace mozilla {
 namespace image {
 
 // Global preferences related to image containers.
@@ -169,16 +170,23 @@ GetContentSize(nsIRequest* aRequest)
     }
   }
 
   // Fallback - neither http nor file. We'll use dynamic allocation.
   return 0;
 }
 
 /* static */ already_AddRefed<Image>
+ImageFactory::Freeze(Image* aImage)
+{
+  nsRefPtr<Image> frozenImage = new FrozenImage(aImage);
+  return frozenImage.forget();
+}
+
+/* static */ already_AddRefed<Image>
 ImageFactory::CreateRasterImage(nsIRequest* aRequest,
                                 imgStatusTracker* aStatusTracker,
                                 const nsCString& aMimeType,
                                 nsIURI* aURI,
                                 uint32_t aImageFlags,
                                 uint32_t aInnerWindowId)
 {
   nsresult rv;
--- a/image/src/ImageFactory.h
+++ b/image/src/ImageFactory.h
@@ -2,16 +2,19 @@
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_IMAGELIB_IMAGEFACTORY_H_
 #define MOZILLA_IMAGELIB_IMAGEFACTORY_H_
 
+#include "nsCOMPtr.h"
+
+class nsCString;
 class nsIRequest;
 class nsIURI;
 class imgStatusTracker;
 
 namespace mozilla {
 namespace image {
 
 class Image;
@@ -38,16 +41,23 @@ public:
   /**
    * Creates a new image which isn't associated with a URI or loaded through
    * the usual image loading mechanism.
    *
    * @param aMimeType      The mimetype of the image.
    */
   static already_AddRefed<Image> CreateAnonymousImage(const nsCString& aMimeType);
 
+  /**
+   * Creates a version of an existing image which does not animate and is frozen
+   * at the first frame.
+   *
+   * @param aImage         The existing image.
+   */
+  static already_AddRefed<Image> Freeze(Image* aImage);
 
 private:
   // Factory functions that create specific types of image containers.
   static already_AddRefed<Image> CreateRasterImage(nsIRequest* aRequest,
                                                    imgStatusTracker* aStatusTracker,
                                                    const nsCString& aMimeType,
                                                    nsIURI* aURI,
                                                    uint32_t aImageFlags,
--- a/image/src/imgRequestProxy.cpp
+++ b/image/src/imgRequestProxy.cpp
@@ -13,16 +13,17 @@
 #include "nsIMultiPartChannel.h"
 
 #include "nsString.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 
 #include "Image.h"
+#include "ImageFactory.h"
 #include "nsError.h"
 #include "ImageLogging.h"
 
 #include "nspr.h"
 
 using namespace mozilla::image;
 
 // The split of imgRequestProxy and imgRequestProxyStatic means that
@@ -901,35 +902,31 @@ imgRequestProxy::GetStaticRequest(imgReq
 
   bool animated;
   if (!image || (NS_SUCCEEDED(image->GetAnimated(&animated)) && !animated)) {
     // Early exit - we're not animated, so we don't have to do anything.
     NS_ADDREF(*aReturn = this);
     return NS_OK;
   }
 
-  // We are animated. We need to extract the current frame from this image.
-  int32_t w = 0;
-  int32_t h = 0;
-  image->GetWidth(&w);
-  image->GetHeight(&h);
-  nsIntRect rect(0, 0, w, h);
-  nsCOMPtr<imgIContainer> currentFrame;
-  nsresult rv = image->ExtractFrame(imgIContainer::FRAME_CURRENT, rect,
-                                    imgIContainer::FLAG_SYNC_DECODE,
-                                    getter_AddRefs(currentFrame));
-  if (NS_FAILED(rv))
-    return rv;
+  // Check for errors in the image. Callers code rely on GetStaticRequest
+  // failing in this case, though with FrozenImage there's no technical reason
+  // for it anymore.
+  if (image->HasError()) {
+    return NS_ERROR_FAILURE;
+  }
 
-  nsRefPtr<Image> frame = static_cast<Image*>(currentFrame.get());
+  // We are animated. We need to create a frozen version of this image.
+  nsRefPtr<Image> frozenImage = ImageFactory::Freeze(image);
 
   // Create a static imgRequestProxy with our new extracted frame.
   nsCOMPtr<nsIPrincipal> currentPrincipal;
   GetImagePrincipal(getter_AddRefs(currentPrincipal));
-  nsRefPtr<imgRequestProxy> req = new imgRequestProxyStatic(frame, currentPrincipal);
+  nsRefPtr<imgRequestProxy> req = new imgRequestProxyStatic(frozenImage,
+                                                            currentPrincipal);
   req->Init(nullptr, nullptr, mURI, nullptr);
 
   NS_ADDREF(*aReturn = req);
 
   return NS_OK;
 }
 
 void imgRequestProxy::NotifyListener()