Bug 968923 - part 3b - propagating use counters from SVG images into owning/parent documents; r=seth
authorCameron McCormack <cam@mcc.id.au>
Wed, 03 Jun 2015 13:42:07 -0400
changeset 290842 d2df20696ffe4542749883dda8575aba3b37c879
parent 290841 ff6b8f1977f0f3b247c6a5b0bbe092f363464cf7
child 290843 a384a005caf834d0df80f44b985303bc47602fe1
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseth
bugs968923
milestone43.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 968923 - part 3b - propagating use counters from SVG images into owning/parent documents; r=seth
dom/base/nsImageLoadingContent.cpp
image/DynamicImage.cpp
image/ImageWrapper.cpp
image/RasterImage.cpp
image/VectorImage.cpp
image/imgIContainer.idl
layout/generic/nsBulletFrame.cpp
layout/style/ImageLoader.cpp
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -186,16 +186,22 @@ nsImageLoadingContent::Notify(imgIReques
       }
     }
     nsresult status =
         reqStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
     return OnLoadComplete(aRequest, status);
   }
 
   if (aType == imgINotificationObserver::DECODE_COMPLETE) {
+    nsCOMPtr<imgIContainer> container;
+    aRequest->GetImage(getter_AddRefs(container));
+    if (container) {
+      container->PropagateUseCounters(GetOurOwnerDoc());
+    }
+
     UpdateImageState(true);
   }
 
   return NS_OK;
 }
 
 nsresult
 nsImageLoadingContent::OnLoadComplete(imgIRequest* aRequest, nsresult aStatus)
--- a/image/DynamicImage.cpp
+++ b/image/DynamicImage.cpp
@@ -331,10 +331,16 @@ DynamicImage::GetImageSpaceInvalidationR
 
 already_AddRefed<imgIContainer>
 DynamicImage::Unwrap()
 {
   nsCOMPtr<imgIContainer> self(this);
   return self.forget();
 }
 
+void
+DynamicImage::PropagateUseCounters(nsIDocument*)
+{
+  // No use counters.
+}
+
 } // namespace image
 } // namespace mozilla
--- a/image/ImageWrapper.cpp
+++ b/image/ImageWrapper.cpp
@@ -282,16 +282,22 @@ ImageWrapper::GetFirstFrameDelay()
 }
 
 NS_IMETHODIMP_(void)
 ImageWrapper::SetAnimationStartTime(const TimeStamp& aTime)
 {
   mInnerImage->SetAnimationStartTime(aTime);
 }
 
+void
+ImageWrapper::PropagateUseCounters(nsIDocument* aParentDocument)
+{
+  mInnerImage->PropagateUseCounters(aParentDocument);
+}
+
 nsIntSize
 ImageWrapper::OptimalImageSizeForDest(const gfxSize& aDest,
                                       uint32_t aWhichFrame,
                                       GraphicsFilter aFilter, uint32_t aFlags)
 {
   return mInnerImage->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter,
                                               aFlags);
 }
--- a/image/RasterImage.cpp
+++ b/image/RasterImage.cpp
@@ -2086,16 +2086,22 @@ RasterImage::ReportDecoderError(Decoder*
 
 already_AddRefed<imgIContainer>
 RasterImage::Unwrap()
 {
   nsCOMPtr<imgIContainer> self(this);
   return self.forget();
 }
 
+void
+RasterImage::PropagateUseCounters(nsIDocument*)
+{
+  // No use counters.
+}
+
 IntSize
 RasterImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
                                      GraphicsFilter aFilter, uint32_t aFlags)
 {
   MOZ_ASSERT(aDest.width >= 0 || ceil(aDest.width) <= INT32_MAX ||
              aDest.height >= 0 || ceil(aDest.height) <= INT32_MAX,
              "Unexpected destination size");
 
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -1245,16 +1245,25 @@ VectorImage::InvalidateObserversOnNextRe
 {
   if (mHaveAnimations) {
     mHasPendingInvalidation = true;
   } else {
     SendInvalidationNotifications();
   }
 }
 
+void
+VectorImage::PropagateUseCounters(nsIDocument* aParentDocument)
+{
+  nsIDocument* doc = mSVGDocumentWrapper->GetDocument();
+  if (doc) {
+    doc->PropagateUseCounters(aParentDocument);
+  }
+}
+
 nsIntSize
 VectorImage::OptimalImageSizeForDest(const gfxSize& aDest,
                                      uint32_t aWhichFrame,
                                      GraphicsFilter aFilter,
                                      uint32_t aFlags)
 {
   MOZ_ASSERT(aDest.width >= 0 || ceil(aDest.width) <= INT32_MAX ||
              aDest.height >= 0 || ceil(aDest.height) <= INT32_MAX,
--- a/image/imgIContainer.idl
+++ b/image/imgIContainer.idl
@@ -13,16 +13,18 @@
 #include "GraphicsFilter.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/RefPtr.h"
 #include "nsRect.h"
 #include "nsSize.h"
 #include "limits.h"
 
+class nsIDocument;
+
 namespace mozilla {
 namespace layers {
 class LayerManager;
 class ImageContainer;
 }
 }
 
 class nsIFrame;
@@ -102,26 +104,27 @@ native TempRefImageContainer(already_Add
 [ref] native ImageRegion(mozilla::image::ImageRegion);
 [ptr] native LayerManager(mozilla::layers::LayerManager);
 native Orientation(mozilla::image::Orientation);
 [ref] native TimeStamp(mozilla::TimeStamp);
 [ref] native MaybeSVGImageContext(mozilla::Maybe<mozilla::SVGImageContext>);
 native TempRefSourceSurface(already_AddRefed<mozilla::gfx::SourceSurface>);
 native TempRefImgIContainer(already_AddRefed<imgIContainer>);
 native nsIntSizeByVal(nsIntSize);
+[ptr] native nsIDocument(nsIDocument);
 
 
 /**
  * imgIContainer is the interface that represents an image. It allows
  * access to frames as Thebes surfaces. It also allows drawing of images
  * onto Thebes contexts.
  *
  * Internally, imgIContainer also manages animation of images.
  */
-[scriptable, builtinclass, uuid(f3596ad3-4238-4bc4-8093-90bc2d002ab6)]
+[scriptable, builtinclass, uuid(4880727a-5673-44f7-b248-f6c86e22a434)]
 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 int32_t width;
 
@@ -539,9 +542,15 @@ interface imgIContainer : nsISupports
    */
   [notxpcom] nsIntRectByVal
   getImageSpaceInvalidationRect([const] in nsIntRect aRect);
 
   /*
    * Removes any ImageWrappers and returns the unwrapped base image.
    */
   [notxpcom, nostdcall] TempRefImgIContainer unwrap();
+
+  /*
+   * Propagate the use counters (if any) from this container to the passed in
+   * document.
+   */
+  [noscript, notxpcom] void propagateUseCounters(in nsIDocument aDocument);
 };
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -713,16 +713,26 @@ nsBulletFrame::Notify(imgIRequest *aRequ
     // XXX(seth): We eventually want to decide whether to do this based on
     // visibility. We should get that for free from bug 1091236.
     if (aRequest == mImageRequest) {
       mImageRequest->RequestDecode();
     }
     InvalidateFrame();
   }
 
+  if (aType == imgINotificationObserver::DECODE_COMPLETE) {
+    if (nsIDocument* parent = GetOurCurrentDoc()) {
+      nsCOMPtr<imgIContainer> container;
+      aRequest->GetImage(getter_AddRefs(container));
+      if (container) {
+        container->PropagateUseCounters(parent);
+      }
+    }
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsBulletFrame::BlockOnload(imgIRequest* aRequest)
 {
   if (aRequest != mImageRequest) {
     return NS_OK;
--- a/layout/style/ImageLoader.cpp
+++ b/layout/style/ImageLoader.cpp
@@ -392,16 +392,24 @@ ImageLoader::Notify(imgIRequest* aReques
   if (aType == imgINotificationObserver::FRAME_COMPLETE) {
     return OnFrameComplete(aRequest);
   }
 
   if (aType == imgINotificationObserver::FRAME_UPDATE) {
     return OnFrameUpdate(aRequest);
   }
 
+  if (aType == imgINotificationObserver::DECODE_COMPLETE) {
+    nsCOMPtr<imgIContainer> image;
+    aRequest->GetImage(getter_AddRefs(image));
+    if (image && mDocument) {
+      image->PropagateUseCounters(mDocument);
+    }
+  }
+
   return NS_OK;
 }
 
 nsresult
 ImageLoader::OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage)
 { 
   nsPresContext* presContext = GetPresContext();
   if (!presContext) {