Bug 919219 - Trim gfxASurface more - r=jrmuizel
authorBenoit Jacob <bjacob@mozilla.com>
Tue, 24 Sep 2013 16:45:13 -0400
changeset 148491 6a26a65777a5b22010de9ece5eaa166ee25acd9b
parent 148490 557caa8ccaeadb529753f6c6599227118f742e84
child 148492 1892aa2a6de84d83a3c0aff80b0153d925e48ebc
push idunknown
push userunknown
push dateunknown
reviewersjrmuizel
bugs919219
milestone27.0a1
Bug 919219 - Trim gfxASurface more - r=jrmuizel
gfx/thebes/gfxASurface.cpp
gfx/thebes/gfxASurface.h
gfx/thebes/gfxCachedTempSurface.h
gfx/thebes/gfxImageSurface.h
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxTeeSurface.cpp
gfx/thebes/gfxTeeSurface.h
gfx/thebes/gfxXlibSurface.cpp
gfx/thebes/gfxXlibSurface.h
gfx/thebes/nsSurfaceTexture.cpp
widget/android/AndroidDirectTexture.cpp
widget/android/AndroidJNI.cpp
widget/shared/nsShmImage.h
--- a/gfx/thebes/gfxASurface.cpp
+++ b/gfx/thebes/gfxASurface.cpp
@@ -4,23 +4,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIMemoryReporter.h"
 #include "nsMemory.h"
 #include "mozilla/Base64.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
+#include "nsTraceRefcnt.h"
 
 #include "gfxASurface.h"
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
-
-#include "nsRect.h"
+#include "gfxRect.h"
 
 #include "cairo.h"
 #include <algorithm>
 
 #ifdef CAIRO_HAS_WIN32_SURFACE
 #include "gfxWindowsSurface.h"
 #endif
 #ifdef CAIRO_HAS_D2D_SURFACE
@@ -51,16 +51,30 @@
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "nsIClipboardHelper.h"
 
 using namespace mozilla;
 
 static cairo_user_data_key_t gfxasurface_pointer_key;
 
+gfxASurface::gfxASurface()
+ : mSurface(nullptr), mFloatingRefs(0), mBytesRecorded(0),
+   mSurfaceValid(false), mAllowUseAsSource(true)
+{
+    MOZ_COUNT_CTOR(gfxASurface);
+}
+
+gfxASurface::~gfxASurface()
+{
+    RecordMemoryFreed();
+
+    MOZ_COUNT_DTOR(gfxASurface);
+}
+
 // Surfaces use refcounting that's tied to the cairo surface refcnt, to avoid
 // refcount mismatch issues.
 nsrefcnt
 gfxASurface::AddRef(void)
 {
     if (mSurfaceValid) {
         if (mFloatingRefs) {
             // eat a floating ref
@@ -97,16 +111,28 @@ gfxASurface::Release(void)
             delete this;
             return 0;
         }
 
         return mFloatingRefs;
     }
 }
 
+nsrefcnt
+gfxASurface::AddRefExternal(void)
+{
+  return AddRef();
+}
+
+nsrefcnt
+gfxASurface::ReleaseExternal(void)
+{
+  return Release();
+}
+
 void
 gfxASurface::SurfaceDestroyFunc(void *data) {
     gfxASurface *surf = (gfxASurface*) data;
     // fprintf (stderr, "Deleting wrapper for %p (wrapper: %p)\n", surf->mSurface, data);
     delete surf;
 }
 
 gfxASurface*
@@ -289,17 +315,17 @@ void
 gfxASurface::Finish()
 {
     // null surfaces are allowed here
     cairo_surface_finish(mSurface);
 }
 
 already_AddRefed<gfxASurface>
 gfxASurface::CreateSimilarSurface(gfxContentType aContent,
-                                  const gfxIntSize& aSize)
+                                  const nsIntSize& aSize)
 {
     if (!mSurface || !mSurfaceValid) {
       return nullptr;
     }
     
     cairo_surface_t *surface =
         cairo_surface_create_similar(mSurface, cairo_content_t(aContent),
                                      aSize.width, aSize.height);
@@ -325,17 +351,17 @@ gfxASurface::GetAsReadableARGB32ImageSur
 
 already_AddRefed<gfxImageSurface>
 gfxASurface::CopyToARGB32ImageSurface()
 {
     if (!mSurface || !mSurfaceValid) {
       return nullptr;
     }
 
-    const gfxIntSize size = GetSize();
+    const nsIntSize size = GetSize();
     nsRefPtr<gfxImageSurface> imgSurface =
         new gfxImageSurface(size, gfxASurface::ImageFormatARGB32);
 
     gfxContext ctx(imgSurface);
     ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
     ctx.SetSource(this);
     ctx.Paint();
 
@@ -348,17 +374,17 @@ gfxASurface::CairoStatus()
     if (!mSurfaceValid)
         return -1;
 
     return cairo_surface_status(mSurface);
 }
 
 /* static */
 bool
-gfxASurface::CheckSurfaceSize(const gfxIntSize& sz, int32_t limit)
+gfxASurface::CheckSurfaceSize(const nsIntSize& sz, int32_t limit)
 {
     if (sz.width < 0 || sz.height < 0) {
         NS_WARNING("Surface width or height < 0!");
         return false;
     }
 
     // reject images with sides bigger than limit
     if (limit && (sz.width > limit || sz.height > limit)) {
@@ -514,17 +540,17 @@ gfxASurface::FastMovePixels(const nsIntR
 void
 gfxASurface::MovePixels(const nsIntRect& aSourceRect,
                         const nsIntPoint& aDestTopLeft)
 {
     // Assume the backend can't handle self copying well and allocate
     // a temporary surface instead.
     nsRefPtr<gfxASurface> tmp = 
       CreateSimilarSurface(GetContentType(), 
-                           gfxIntSize(aSourceRect.width, aSourceRect.height));
+                           nsIntSize(aSourceRect.width, aSourceRect.height));
     // CreateSimilarSurface can return nullptr if the current surface is
     // in an error state. This isn't good, but its better to carry
     // on with the error surface instead of crashing.
     NS_WARN_IF_FALSE(tmp, "Must have temporary surface to move pixels!");
     if (!tmp) {
         return;
     }
     nsRefPtr<gfxContext> ctx = new gfxContext(tmp);
@@ -744,28 +770,28 @@ gfxASurface::CopyAsDataURL()
  * Write to a PNG file. If aBinary is true, then it is written
  * as binary, otherwise as a data URL. If no file is specified then
  * data is copied to the clipboard (must not be binary!).
  */
 void
 gfxASurface::WriteAsPNG_internal(FILE* aFile, bool aBinary)
 {
   nsRefPtr<gfxImageSurface> imgsurf = GetAsImageSurface();
-  gfxIntSize size;
+  nsIntSize size;
 
   // FIXME/bug 831898: hack r5g6b5 for now.
   if (!imgsurf || imgsurf->Format() == ImageFormatRGB16_565) {
     size = GetSize();
     if (size.width == -1 && size.height == -1) {
       printf("Could not determine surface size\n");
       return;
     }
 
     imgsurf =
-      new gfxImageSurface(gfxIntSize(size.width, size.height),
+      new gfxImageSurface(nsIntSize(size.width, size.height),
                           gfxASurface::ImageFormatARGB32);
 
     if (!imgsurf || imgsurf->CairoStatus()) {
       printf("Could not allocate image surface\n");
       return;
     }
 
     nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf);
@@ -883,8 +909,39 @@ gfxASurface::WriteAsPNG_internal(FILE* a
     nsCOMPtr<nsIClipboardHelper> clipboard(do_GetService("@mozilla.org/widget/clipboardhelper;1", &rv));
     if (clipboard) {
       clipboard->CopyString(NS_ConvertASCIItoUTF16(string), nullptr);
     }
   }
 
   return;
 }
+
+void
+gfxASurface::SetOpaqueRect(const gfxRect& aRect)
+{
+    if (aRect.IsEmpty()) {
+        mOpaqueRect = nullptr;
+    } else if (!!mOpaqueRect) {
+        *mOpaqueRect = aRect;
+    } else {
+        mOpaqueRect = new gfxRect(aRect);
+    }
+}
+
+/* static */const gfxRect&
+gfxASurface::GetEmptyOpaqueRect()
+{
+  static const gfxRect empty(0, 0, 0, 0);
+  return empty;
+}
+
+const nsIntSize
+gfxASurface::GetSize() const
+{
+  return nsIntSize(-1, -1);
+}
+
+already_AddRefed<gfxImageSurface>
+gfxASurface::GetAsImageSurface()
+{
+  return nullptr;
+}
--- a/gfx/thebes/gfxASurface.h
+++ b/gfx/thebes/gfxASurface.h
@@ -7,47 +7,53 @@
 #define GFX_ASURFACE_H
 
 #ifdef MOZ_DUMP_PAINTING
  #define MOZ_DUMP_IMAGES
 #endif
 
 #include "mozilla/MemoryReporting.h"
 #include "gfxTypes.h"
-#include "gfxRect.h"
-#include "nsAutoPtr.h"
+#include "mozilla/Scoped.h"
+#include "nscore.h"
+
+#ifdef MOZILLA_INTERNAL_API
+#include "nsStringFwd.h"
+#else
+#include "nsStringAPI.h"
+#endif
 
 typedef struct _cairo_surface cairo_surface_t;
 typedef struct _cairo_user_data_key cairo_user_data_key_t;
 
 typedef void (*thebes_destroy_func_t) (void *data);
 
 class gfxImageSurface;
 struct nsIntPoint;
 struct nsIntRect;
+struct gfxRect;
+struct gfxPoint;
+struct nsIntSize;
+
+template <typename T>
+struct already_AddRefed;
 
 /**
  * A surface is something you can draw on. Instantiate a subclass of this
  * abstract class, and use gfxContext to draw on this surface.
  */
 class gfxASurface {
 public:
 #ifdef MOZILLA_INTERNAL_API
     nsrefcnt AddRef(void);
     nsrefcnt Release(void);
 
     // These functions exist so that browsercomps can refcount a gfxASurface
-    virtual nsrefcnt AddRefExternal(void)
-    {
-      return AddRef();
-    }
-    virtual nsrefcnt ReleaseExternal(void)
-    {
-      return Release();
-    }
+    virtual nsrefcnt AddRefExternal(void);
+    virtual nsrefcnt ReleaseExternal(void);
 #else
     virtual nsrefcnt AddRef(void);
     virtual nsrefcnt Release(void);
 #endif
 
 public:
     /**
      * The format for an image surface. For all formats with alpha data, 0
@@ -100,17 +106,16 @@ public:
 
     /** Wrap the given cairo surface and return a gfxASurface for it.
      * This adds a reference to csurf (owned by the returned gfxASurface).
      */
     static already_AddRefed<gfxASurface> Wrap(cairo_surface_t *csurf);
 
     /*** this DOES NOT addref the surface */
     cairo_surface_t *CairoSurface() {
-        NS_ASSERTION(mSurface != nullptr, "gfxASurface::CairoSurface called with mSurface == nullptr!");
         return mSurface;
     }
 
     gfxSurfaceType GetType() const;
 
     gfxContentType GetContentType() const;
 
     void SetDeviceOffset(const gfxPoint& offset);
@@ -137,27 +142,24 @@ public:
     virtual void Finish();
 
     /**
      * Create an offscreen surface that can be efficiently copied into
      * this surface (at least if tiling is not involved).
      * Returns null on error.
      */
     virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType,
-                                                               const gfxIntSize& aSize);
+                                                               const nsIntSize& aSize);
 
     /**
      * Returns an image surface for this surface, or nullptr if not supported.
      * This will not copy image data, just wraps an image surface around
      * pixel data already available in memory.
      */
-    virtual already_AddRefed<gfxImageSurface> GetAsImageSurface()
-    {
-      return nullptr;
-    }
+    virtual already_AddRefed<gfxImageSurface> GetAsImageSurface();
 
     /**
      * Returns a read-only ARGB32 image surface for this surface. If this is an
      * optimized surface this may require a copy.
      * Returns null on error.
      */
     virtual already_AddRefed<gfxImageSurface> GetAsReadableARGB32ImageSurface();
 
@@ -168,17 +170,17 @@ public:
     already_AddRefed<gfxImageSurface> CopyToARGB32ImageSurface();
 
     int CairoStatus();
 
     /* Make sure that the given dimensions don't overflow a 32-bit signed int
      * using 4 bytes per pixel; optionally, make sure that either dimension
      * doesn't exceed the given limit.
      */
-    static bool CheckSurfaceSize(const gfxIntSize& sz, int32_t limit = 0);
+    static bool CheckSurfaceSize(const nsIntSize& sz, int32_t limit = 0);
 
     /* Provide a stride value that will respect all alignment requirements of
      * the accelerated image-rendering code.
      */
     static int32_t FormatStrideForWidth(gfxImageFormat format, int32_t width);
 
     /* Return the default set of context flags for this surface; these are
      * hints to the context about any special rendering considerations.  See
@@ -234,17 +236,17 @@ public:
     /**
      * Where does this surface's memory live?  By default, we say it's in this
      * process's heap.
      */
     virtual MemoryLocation GetMemoryLocation() const;
 
     static int32_t BytePerPixelFromFormat(gfxImageFormat format);
 
-    virtual const gfxIntSize GetSize() const { return gfxIntSize(-1, -1); }
+    virtual const nsIntSize GetSize() const;
 
     /**
      * Debug functions to encode the current image as a PNG and export it.
      */
 
     /**
      * Writes a binary PNG file.
      */
@@ -259,33 +261,25 @@ public:
      * Write as a PNG encoded Data URL to stdout.
      */
     void PrintAsDataURL();
 
     /**
      * Copy a PNG encoded Data URL to the clipboard.
      */
     void CopyAsDataURL();
-    
+
     void WriteAsPNG_internal(FILE* aFile, bool aBinary);
 
-    void SetOpaqueRect(const gfxRect& aRect) {
-        if (aRect.IsEmpty()) {
-            mOpaqueRect = nullptr;
-        } else if (mOpaqueRect) {
-            *mOpaqueRect = aRect;
-        } else {
-            mOpaqueRect = new gfxRect(aRect);
-        }
-    }
+    void SetOpaqueRect(const gfxRect& aRect);
+
     const gfxRect& GetOpaqueRect() {
-        if (mOpaqueRect)
+        if (!!mOpaqueRect)
             return *mOpaqueRect;
-        static const gfxRect empty(0, 0, 0, 0);
-        return empty;
+        return GetEmptyOpaqueRect();
     }
 
     /**
      * Move the pixels in |aSourceRect| to |aDestTopLeft|.  Like with
      * memmove(), |aSourceRect| and the rectangle defined by
      * |aDestTopLeft| are allowed to overlap, and the effect is
      * equivalent to copying |aSourceRect| to a scratch surface and
      * then back to |aDestTopLeft|.
@@ -300,21 +294,17 @@ public:
      * Mark the surface as being allowed/not allowed to be used as a source.
      */
     void SetAllowUseAsSource(bool aAllow) { mAllowUseAsSource = aAllow; }
     bool GetAllowUseAsSource() { return mAllowUseAsSource; }
 
     static uint8_t BytesPerPixel(gfxImageFormat aImageFormat);
 
 protected:
-    gfxASurface() : mSurface(nullptr), mFloatingRefs(0), mBytesRecorded(0),
-                    mSurfaceValid(false), mAllowUseAsSource(true)
-    {
-        MOZ_COUNT_CTOR(gfxASurface);
-    }
+    gfxASurface();
 
     static gfxASurface* GetSurfaceWrapper(cairo_surface_t *csurf);
     static void SetSurfaceWrapper(cairo_surface_t *csurf, gfxASurface *asurf);
 
     /**
      * An implementation of MovePixels that assumes the backend can
      * internally handle this operation and doesn't allocate any
      * temporary surfaces.
@@ -322,25 +312,24 @@ protected:
     void FastMovePixels(const nsIntRect& aSourceRect,
                         const nsIntPoint& aDestTopLeft);
 
     // NB: Init() *must* be called from within subclass's
     // constructors.  It's unsafe to call it after the ctor finishes;
     // leaks and use-after-frees are possible.
     void Init(cairo_surface_t *surface, bool existingSurface = false);
 
-    virtual ~gfxASurface()
-    {
-        RecordMemoryFreed();
+    // out-of-line helper to allow GetOpaqueRect() to be inlined
+    // without including gfxRect.h here
+    static const gfxRect& GetEmptyOpaqueRect();
 
-        MOZ_COUNT_DTOR(gfxASurface);
-    }
+    virtual ~gfxASurface();
 
     cairo_surface_t *mSurface;
-    nsAutoPtr<gfxRect> mOpaqueRect;
+    mozilla::ScopedDeletePtr<gfxRect> mOpaqueRect;
 
 private:
     static void SurfaceDestroyFunc(void *data);
 
     int32_t mFloatingRefs;
     int32_t mBytesRecorded;
 
 protected:
--- a/gfx/thebes/gfxCachedTempSurface.h
+++ b/gfx/thebes/gfxCachedTempSurface.h
@@ -3,16 +3,17 @@
  * 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 GFX_CACHED_TEMP_SURFACE_H
 #define GFX_CACHED_TEMP_SURFACE_H
 
 #include "gfxASurface.h"
 #include "nsExpirationTracker.h"
+#include "nsSize.h"
 
 class gfxContext;
 
 /**
  * This class can be used to cache double-buffering back surfaces.
  *
  * Large resource allocations may have an overhead that can be avoided by
  * caching.  Caching also alows the system to use history in deciding whether
--- a/gfx/thebes/gfxImageSurface.h
+++ b/gfx/thebes/gfxImageSurface.h
@@ -3,16 +3,17 @@
  * 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 GFX_IMAGESURFACE_H
 #define GFX_IMAGESURFACE_H
 
 #include "mozilla/MemoryReporting.h"
 #include "gfxASurface.h"
+#include "nsAutoPtr.h"
 #include "gfxPoint.h"
 
 // ARGB -- raw buffer.. wont be changed.. good for storing data.
 
 class gfxSubimageSurface;
 
 namespace mozilla {
 namespace gfx {
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -5,20 +5,23 @@
 
 #ifndef GFX_PLATFORM_H
 #define GFX_PLATFORM_H
 
 #include "prlog.h"
 #include "nsTArray.h"
 #include "nsString.h"
 #include "nsIObserver.h"
+#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
 
 #include "gfxTypes.h"
 #include "gfxASurface.h"
 #include "gfxColor.h"
+#include "nsRect.h"
 
 #include "qcms.h"
 
 #include "mozilla/gfx/2D.h"
 #include "gfx2DGlue.h"
 #include "mozilla/RefPtr.h"
 #include "GfxInfoCollector.h"
 
--- a/gfx/thebes/gfxTeeSurface.cpp
+++ b/gfx/thebes/gfxTeeSurface.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "gfxTeeSurface.h"
+#include "nsAutoPtr.h"
 
 #include "cairo-tee.h"
 
 gfxTeeSurface::gfxTeeSurface(cairo_surface_t *csurf)
 {
     Init(csurf, true);
 }
 
--- a/gfx/thebes/gfxTeeSurface.h
+++ b/gfx/thebes/gfxTeeSurface.h
@@ -3,16 +3,17 @@
  * 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 GFX_TEESURFACE_H
 #define GFX_TEESURFACE_H
 
 #include "gfxASurface.h"
 #include "nsTArray.h"
+#include "nsSize.h"
 
 /**
  * Wraps a cairo_tee_surface. The first surface in the surface list is the
  * primary surface, which answers all surface queries (including size).
  * All drawing is performed on all the surfaces.
  *
  * The device transform of a tee surface is applied before drawing to the
  * underlying surfaces --- which also applies the device transforms of the
--- a/gfx/thebes/gfxXlibSurface.cpp
+++ b/gfx/thebes/gfxXlibSurface.cpp
@@ -7,16 +7,17 @@
 
 #include "cairo.h"
 #include "cairo-xlib.h"
 #include "cairo-xlib-xrender.h"
 #include <X11/Xlibint.h>	/* For XESetCloseDisplay */
 #undef max // Xlibint.h defines this and it breaks std::max
 #undef min // Xlibint.h defines this and it breaks std::min
 
+#include "nsAutoPtr.h"
 #include "nsTArray.h"
 #include "nsAlgorithm.h"
 #include "mozilla/Preferences.h"
 #include <algorithm>
 
 using namespace mozilla;
 
 // Although the dimension parameters in the xCreatePixmapReq wire protocol are
--- a/gfx/thebes/gfxXlibSurface.h
+++ b/gfx/thebes/gfxXlibSurface.h
@@ -10,16 +10,18 @@
 
 #include <X11/extensions/Xrender.h>
 #include <X11/Xlib.h>
 
 #if defined(GL_PROVIDER_GLX)
 #include "GLXLibrary.h"
 #endif
 
+#include "nsSize.h"
+
 class gfxXlibSurface : public gfxASurface {
 public:
     // construct a wrapper around the specified drawable with dpy/visual.
     // Will use XGetGeometry to query the window/pixmap size.
     gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual);
 
     // construct a wrapper around the specified drawable with dpy/visual,
     // and known width/height.
--- a/gfx/thebes/nsSurfaceTexture.cpp
+++ b/gfx/thebes/nsSurfaceTexture.cpp
@@ -7,16 +7,17 @@
 #ifdef MOZ_WIDGET_ANDROID
 
 #include <set>
 #include <map>
 #include <android/log.h>
 #include "nsSurfaceTexture.h"
 #include "gfxImageSurface.h"
 #include "AndroidBridge.h"
+#include "nsThreadUtils.h"
 
 using namespace mozilla;
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "nsSurfaceTexture" , ## args)
 
 // UGH
 static std::map<int, nsSurfaceTexture*> sInstances;
 static int sNextID = 0;
--- a/widget/android/AndroidDirectTexture.cpp
+++ b/widget/android/AndroidDirectTexture.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * 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 <unistd.h>
 #include <errno.h>
 #include "AndroidDirectTexture.h"
+#include "nsRect.h"
 
 typedef gfxASurface::gfxImageFormat gfxImageFormat;
 
 namespace mozilla {
 
 AndroidDirectTexture::AndroidDirectTexture(uint32_t width, uint32_t height, uint32_t usage,
                                            gfxImageFormat format) :
     mLock("AndroidDirectTexture.mLock")
--- a/widget/android/AndroidJNI.cpp
+++ b/widget/android/AndroidJNI.cpp
@@ -17,16 +17,17 @@
 #include <unistd.h>
 #include <sched.h>
 
 #include "nsAppShell.h"
 #include "nsWindow.h"
 #include <android/log.h>
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
+#include "nsThreadUtils.h"
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsICrashReporter.h"
 #include "nsExceptionHandler.h"
 #endif
 
 #include "mozilla/unused.h"
 
--- a/widget/shared/nsShmImage.h
+++ b/widget/shared/nsShmImage.h
@@ -12,16 +12,17 @@
 #if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV)
 #  define MOZ_HAVE_SHMIMAGE
 #endif
 
 #ifdef MOZ_HAVE_SHMIMAGE
 
 #include "nsIWidget.h"
 #include "gfxASurface.h"
+#include "nsAutoPtr.h"
 
 #include "mozilla/X11Util.h"
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/extensions/XShm.h>
 
 #if defined(MOZ_WIDGET_GTK)
 #define DISPLAY gdk_x11_get_default_xdisplay