Bug 731419 - Part 1: Discard image data immediately on tab close, imagelib changes. r=joe
authorJustin Lebar <justin.lebar@gmail.com>
Sat, 10 Mar 2012 01:29:28 -0500
changeset 91590 d6dc71da36ac15c57e8714cbbfe5d9a7c87c9dfd
parent 91589 46fe585786aec2100218208beef8cc892cef9ff5
child 91591 f0933a7d1ab0f921071154902bbf4c76e2d9fffe
push id783
push userlsblakk@mozilla.com
push dateTue, 24 Apr 2012 17:33:42 +0000
treeherdermozilla-beta@11faed19f136 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe
bugs731419
milestone13.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 731419 - Part 1: Discard image data immediately on tab close, imagelib changes. r=joe
image/public/imgIContainer.idl
image/public/imgIRequest.idl
image/src/RasterImage.cpp
image/src/RasterImage.h
image/src/VectorImage.cpp
image/src/VectorImage.h
image/src/imgRequestProxy.cpp
--- a/image/public/imgIContainer.idl
+++ b/image/public/imgIContainer.idl
@@ -88,17 +88,17 @@ native gfxGraphicsFilter(gfxPattern::Gra
 /**
  * imgIContainer is the interface that represents an image. It allows
  * access to frames as Thebes surfaces, and permits users to extract subregions
  * as other imgIContainers. It also allows drawing of images on to Thebes
  * contexts.
  *
  * Internally, imgIContainer also manages animation of images.
  */
-[scriptable, uuid(2506249c-e0a1-4d8f-846c-2d478247f8d8)]
+[scriptable, uuid(8bf87433-be67-413b-9497-00071c5002bd)]
 interface imgIContainer : nsISupports
 {
   /**
    * The width of the container rectangle.  In the case of any error,
    * zero is returned, and an exception will be thrown.
    */
   readonly attribute PRInt32 width;
 
@@ -279,16 +279,22 @@ interface imgIContainer : nsISupports
     *
     * Upon instantiation images have a lock count of zero. It is an error to
     * call this method without first having made a matching lockImage() call.
     * In other words, the lock count is not allowed to be negative.
     */
   void unlockImage();
 
   /**
+   * If this image is unlocked, discard its decoded data.  If the image is
+   * locked or has already been discarded, do nothing.
+   */
+  void requestDiscard();
+
+  /**
     * Indicates that this imgIContainer has been triggered to update
     * its internal animation state. Likely this should only be called
     * from within nsImageFrame or objects of similar type.
     */
   [notxpcom] void requestRefresh([const] in TimeStamp aTime);
 
   /**
    * Animation mode Constants
--- a/image/public/imgIRequest.idl
+++ b/image/public/imgIRequest.idl
@@ -47,17 +47,17 @@ interface nsIPrincipal;
 
 /**
  * imgIRequest interface
  *
  * @author Stuart Parmenter <stuart@mozilla.com>
  * @version 0.1
  * @see imagelib2
  */
-[scriptable, uuid(c3bf4e2a-f64b-4ac1-a84e-18631b1802ab)]
+[scriptable, uuid(d35a9adb-8328-4b64-b06f-72a165acd080)]
 interface imgIRequest : nsIRequest
 {
   /**
    * the image container...
    * @return the image object associated with the request.
    * @attention NEED DOCS
    */
   readonly attribute imgIContainer image;
@@ -190,16 +190,22 @@ interface imgIRequest : nsIRequest
   /**
    * Unlocks an image.
    *
    * @see imgIContainer::unlockImage for documentation of the underlying call.
    */
   void unlockImage();
 
   /**
+   * If this image is unlocked, discard the image's decoded data.  If the image
+   * is locked or is already discarded, do nothing.
+   */
+  void requestDiscard();
+
+  /**
    * If this request is for an animated image, the method creates a new
    * request which contains the current frame of the image.
    * Otherwise returns the same request.
    */
   imgIRequest getStaticRequest();
 
   /**
    * Requests that the image animate (if it has an animation).
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -2691,16 +2691,28 @@ RasterImage::UnlockImage()
   if (CanDiscard()) {
     nsresult rv = DiscardTracker::Reset(&mDiscardTrackerNode);
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   return NS_OK;
 }
 
+//******************************************************************************
+/* void requestDiscard() */
+NS_IMETHODIMP
+RasterImage::RequestDiscard()
+{
+  if (CanDiscard()) {
+    ForceDiscard();
+  }
+
+  return NS_OK;
+}
+
 // Flushes up to aMaxBytes to the decoder.
 nsresult
 RasterImage::DecodeSomeData(PRUint32 aMaxBytes)
 {
   // We should have a decoder if we get here
   NS_ABORT_IF_FALSE(mDecoder, "trying to decode without decoder!");
 
   // If we have nothing to decode, return
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -193,16 +193,17 @@ public:
   NS_IMETHOD GetImageContainer(mozilla::layers::ImageContainer **_retval NS_OUTPARAM);
   NS_IMETHOD CopyFrame(PRUint32 aWhichFrame, PRUint32 aFlags, gfxImageSurface **_retval NS_OUTPARAM);
   NS_IMETHOD ExtractFrame(PRUint32 aWhichFrame, const nsIntRect & aRect, PRUint32 aFlags, imgIContainer **_retval NS_OUTPARAM);
   NS_IMETHOD Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter, const gfxMatrix & aUserSpaceToImageSpace, const gfxRect & aFill, const nsIntRect & aSubimage, const nsIntSize & aViewportSize, PRUint32 aFlags);
   NS_IMETHOD_(nsIFrame *) GetRootLayoutFrame(void);
   NS_SCRIPTABLE NS_IMETHOD RequestDecode(void);
   NS_SCRIPTABLE NS_IMETHOD LockImage(void);
   NS_SCRIPTABLE NS_IMETHOD UnlockImage(void);
+  NS_SCRIPTABLE NS_IMETHOD RequestDiscard(void);
   NS_SCRIPTABLE NS_IMETHOD ResetAnimation(void);
   NS_IMETHOD_(void) RequestRefresh(const mozilla::TimeStamp& aTime);
   // END NS_DECL_IMGICONTAINER
 
   RasterImage(imgStatusTracker* aStatusTracker = nsnull);
   virtual ~RasterImage();
 
   virtual nsresult StartAnimation();
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -622,16 +622,25 @@ VectorImage::LockImage()
 NS_IMETHODIMP
 VectorImage::UnlockImage()
 {
   // This method is for image-discarding, which only applies to RasterImages.
   return NS_OK;
 }
 
 //******************************************************************************
+/* void requestDiscard() */
+NS_IMETHODIMP
+VectorImage::RequestDiscard()
+{
+  // This method is for image-discarding, which only applies to RasterImages.
+  return NS_OK;
+}
+
+//******************************************************************************
 /* void resetAnimation (); */
 NS_IMETHODIMP
 VectorImage::ResetAnimation()
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   if (!mIsFullyLoaded || !mHaveAnimations) {
--- a/image/src/VectorImage.h
+++ b/image/src/VectorImage.h
@@ -76,16 +76,17 @@ public:
   NS_IMETHOD GetImageContainer(mozilla::layers::ImageContainer **_retval NS_OUTPARAM) { *_retval = NULL; return NS_OK; }
   NS_IMETHOD CopyFrame(PRUint32 aWhichFrame, PRUint32 aFlags, gfxImageSurface **_retval NS_OUTPARAM);
   NS_IMETHOD ExtractFrame(PRUint32 aWhichFrame, const nsIntRect & aRect, PRUint32 aFlags, imgIContainer **_retval NS_OUTPARAM);
   NS_IMETHOD Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter, const gfxMatrix & aUserSpaceToImageSpace, const gfxRect & aFill, const nsIntRect & aSubimage, const nsIntSize & aViewportSize, PRUint32 aFlags);
   NS_IMETHOD_(nsIFrame *) GetRootLayoutFrame(void);
   NS_SCRIPTABLE NS_IMETHOD RequestDecode(void);
   NS_SCRIPTABLE NS_IMETHOD LockImage(void);
   NS_SCRIPTABLE NS_IMETHOD UnlockImage(void);
+  NS_SCRIPTABLE NS_IMETHOD RequestDiscard(void);
   NS_SCRIPTABLE NS_IMETHOD ResetAnimation(void);
   NS_IMETHOD_(void) RequestRefresh(const mozilla::TimeStamp& aTime);
   // END NS_DECL_IMGICONTAINER
 
   VectorImage(imgStatusTracker* aStatusTracker = nsnull);
   virtual ~VectorImage();
 
   // Methods inherited from Image
--- a/image/src/imgRequestProxy.cpp
+++ b/image/src/imgRequestProxy.cpp
@@ -365,16 +365,26 @@ imgRequestProxy::UnlockImage()
   NS_ABORT_IF_FALSE(mLockCount > 0, "calling unlock but no locks!");
 
   mLockCount--;
   if (mImage)
     return mImage->UnlockImage();
   return NS_OK;
 }
 
+/* void requestDiscard (); */
+NS_IMETHODIMP
+imgRequestProxy::RequestDiscard()
+{
+  if (mImage) {
+    return mImage->RequestDiscard();
+  }
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 imgRequestProxy::IncrementAnimationConsumers()
 {
   mAnimationConsumers++;
   if (mImage)
     mImage->IncrementAnimationConsumers();
   return NS_OK;
 }