Bug 820132 - Measure imgFrame::mOptSurface's size where possible, instead of calculating it. r=joedrew.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 18 Dec 2012 21:59:30 -0800
changeset 116580 20cb0fa34108f6f7a25679041f5487daa6a0bec1
parent 116579 9c5effe633f0de18246b787fb43aedddfc302714
child 116581 3d2011652b37eecb3e0ea6210a4be108d3735e1b
push idunknown
push userunknown
push dateunknown
reviewersjoedrew
bugs820132
milestone20.0a1
Bug 820132 - Measure imgFrame::mOptSurface's size where possible, instead of calculating it. r=joedrew.
gfx/thebes/gfxASurface.h
gfx/thebes/gfxImageSurface.cpp
gfx/thebes/gfxImageSurface.h
image/src/imgFrame.cpp
--- a/gfx/thebes/gfxASurface.h
+++ b/gfx/thebes/gfxASurface.h
@@ -194,16 +194,24 @@ public:
      */
     void RecordMemoryUsed(int32_t aBytes);
     void RecordMemoryFreed();
 
     virtual int32_t KnownMemoryUsed() { return mBytesRecorded; }
 
     virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
     virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+    // gfxASurface has many sub-classes.  This method indicates if a sub-class
+    // is capable of measuring its own size accurately.  If not, the caller
+    // must fall back to a computed size.  (Note that gfxASurface can actually
+    // measure itself, but we must |return false| here because it serves as the
+    // (conservative) default for all the sub-classes.  Therefore, this
+    // function should only be called on a |gfxASurface*| that actually points
+    // to a sub-class of gfxASurface.)
+    virtual bool SizeOfIsMeasured() const { return false; }
 
     /**
      * The memory used by this surface (as reported by KnownMemoryUsed()) can
      * either live in this process's heap, in this process but outside the
      * heap, or in another process altogether.
      */
     enum MemoryLocation {
       MEMORY_IN_PROCESS_HEAP,
--- a/gfx/thebes/gfxImageSurface.cpp
+++ b/gfx/thebes/gfxImageSurface.cpp
@@ -185,16 +185,22 @@ gfxImageSurface::SizeOfExcludingThis(nsM
 }
 
 size_t
 gfxImageSurface::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
 {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
 }
 
+bool
+gfxImageSurface::SizeOfIsMeasured() const
+{
+    return true;
+}
+
 // helper function for the CopyFrom methods
 static void
 CopyForStride(unsigned char* aDest, unsigned char* aSrc, const gfxIntSize& aSize, long aDestStride, long aSrcStride)
 {
     if (aDestStride == aSrcStride) {
         memcpy (aDest, aSrc, aSrcStride * aSize.height);
     } else {
         int lineSize = NS_MIN(aDestStride, aSrcStride);
--- a/gfx/thebes/gfxImageSurface.h
+++ b/gfx/thebes/gfxImageSurface.h
@@ -93,16 +93,17 @@ public:
                             const nsIntPoint& aDestTopLeft) MOZ_OVERRIDE;
 
     static long ComputeStride(const gfxIntSize&, gfxImageFormat);
 
     virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
         MOZ_OVERRIDE;
     virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
         MOZ_OVERRIDE;
+    virtual bool SizeOfIsMeasured() const MOZ_OVERRIDE;
 
 protected:
     gfxImageSurface();
     void InitWithData(unsigned char *aData, const gfxIntSize& aSize,
                       long aStride, gfxImageFormat aFormat);
     void InitFromSurface(cairo_surface_t *csurf);
     long ComputeStride() const { return ComputeStride(mSize, mFormat); }
 
--- a/image/src/imgFrame.cpp
+++ b/image/src/imgFrame.cpp
@@ -1,11 +1,11 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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/. */
 
 #include "imgFrame.h"
 #include "DiscardTracker.h"
 
 #include <limits.h>
 
@@ -808,17 +808,16 @@ imgFrame::SizeOfExcludingThisWithCompute
   if (mPalettedImageData && aLocation == gfxASurface::MEMORY_IN_PROCESS_HEAP) {
     size_t n2 = aMallocSizeOf(mPalettedImageData);
     if (n2 == 0) {
       n2 = GetImageDataLength() + PaletteDataLength();
     }
     n += n2;
   }
 
-  // XXX: should pass aMallocSizeOf here.  See bug 723827.
 #ifdef USE_WIN_SURFACE
   if (mWinSurface && aLocation == mWinSurface->GetMemoryLocation()) {
     n += mWinSurface->KnownMemoryUsed();
   } else
 #endif
 #ifdef XP_MACOSX
   if (mQuartzSurface && aLocation == gfxASurface::MEMORY_IN_PROCESS_HEAP) {
     n += mSize.width * mSize.height * 4;
@@ -831,13 +830,22 @@ imgFrame::SizeOfExcludingThisWithCompute
     }
     if (n2 == 0) {  // non-HEAP or computed fallback for HEAP
       n2 = mImageSurface->KnownMemoryUsed();
     }
     n += n2;
   }
 
   if (mOptSurface && aLocation == mOptSurface->GetMemoryLocation()) {
-    n += mOptSurface->KnownMemoryUsed();
+    size_t n2 = 0;
+    if (aLocation == gfxASurface::MEMORY_IN_PROCESS_HEAP &&
+        mOptSurface->SizeOfIsMeasured()) {
+      // HEAP: measure (but only if the sub-class is capable of measuring)
+      n2 = mOptSurface->SizeOfIncludingThis(aMallocSizeOf);
+    }
+    if (n2 == 0) {  // non-HEAP or computed fallback for HEAP
+      n2 = mOptSurface->KnownMemoryUsed();
+    }
+    n += n2;
   }
 
   return n;
 }