Bug 897452 - Part 15 - Introduce a AtomicRefCountedWithFinalize class to factor our custom-refcounting needs - r=nical
☠☠ backed out by ff1bf2049ecf ☠ ☠
authorBenoit Jacob <bjacob@mozilla.com>
Wed, 11 Dec 2013 13:05:37 -0500
changeset 175987 11ad8608bc275d18f3538a18f4c64d626a86767f
parent 175986 6bcc629e76f90eccedfc5488e3660775fb49540d
child 175988 b93e7a83b3085afbd81bcea449ad30b0804977c2
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs897452
milestone29.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 897452 - Part 15 - Introduce a AtomicRefCountedWithFinalize class to factor our custom-refcounting needs - r=nical
gfx/layers/AtomicRefCountedWithFinalize.h
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/moz.build
new file mode 100644
--- /dev/null
+++ b/gfx/layers/AtomicRefCountedWithFinalize.h
@@ -0,0 +1,46 @@
+/* -*- 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/. */
+
+#ifndef MOZILLA_ATOMICREFCOUNTEDWITHFINALIZE_H_
+#define MOZILLA_ATOMICREFCOUNTEDWITHFINALIZE_H_
+
+#include "mozilla/RefPtr.h"
+
+namespace mozilla {
+
+template<typename T>
+class AtomicRefCountedWithFinalize
+{
+  protected:
+    AtomicRefCountedWithFinalize()
+      : mRefCount(0)
+    {}
+
+    ~AtomicRefCountedWithFinalize() {}
+
+  public:
+    void AddRef() {
+      MOZ_ASSERT(mRefCount >= 0);
+      ++mRefCount;
+    }
+
+    void Release() {
+      MOZ_ASSERT(mRefCount > 0);
+      if (0 == --mRefCount) {
+#ifdef DEBUG
+        mRefCount = detail::DEAD;
+#endif
+        static_cast<T*>(this)->Finalize();
+        delete this;
+      }
+    }
+
+private:
+    Atomic<int> mRefCount;
+};
+
+}
+
+#endif
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -228,18 +228,17 @@ ShmemTextureClient::DropTextureData()
   }
   TextureClientData* result = new ShmemTextureClientData(mShmem);
   MarkInvalid();
   mShmem = ipc::Shmem();
   return result;
 }
 
 TextureClient::TextureClient(TextureFlags aFlags)
-  : mRefCount(0)
-  , mActor(nullptr)
+  : mActor(nullptr)
   , mFlags(aFlags)
   , mShared(false)
   , mValid(true)
 {}
 
 TextureClient::~TextureClient()
 {
   // All the destruction code that may lead to virtual method calls must
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -19,16 +19,17 @@
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat
 #include "mozilla/ipc/Shmem.h"          // for Shmem
 #include "mozilla/layers/CompositorTypes.h"  // for TextureFlags, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsISupportsImpl.h"            // for TextureImage::AddRef, etc
+#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
 
 class gfxReusableSurfaceWrapper;
 class gfxASurface;
 class gfxImageSurface;
 
 namespace mozilla {
 namespace layers {
 
@@ -146,37 +147,22 @@ public:
  * lifetime. This means that the lifetime of the underlying shared data
  * matches the lifetime of the TextureClient/Host pair. It also means
  * TextureClient/Host do not implement double buffering, which is the
  * responsibility of the compositable (which would use two Texture pairs).
  * In order to send several different buffers to the compositor side, use
  * several TextureClients.
  */
 class TextureClient
+  : public AtomicRefCountedWithFinalize<TextureClient>
 {
 public:
   TextureClient(TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
   virtual ~TextureClient();
 
-  void AddRef() {
-    MOZ_ASSERT(mRefCount >= 0);
-    ++mRefCount;
-  }
-
-  void Release() {
-    MOZ_ASSERT(mRefCount > 0);
-    if (0 == --mRefCount) {
-#ifdef DEBUG
-      mRefCount = detail::DEAD;
-#endif
-      Finalize();
-      delete this;
-    }
-  }
-
   virtual TextureClientSurface* AsTextureClientSurface() { return nullptr; }
   virtual TextureClientDrawTarget* AsTextureClientDrawTarget() { return nullptr; }
   virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; }
 
   /**
    * Locks the shared data, allowing the caller to get access to it.
    *
    * Please always lock/unlock when accessing the shared data.
@@ -269,26 +255,26 @@ public:
   PTextureChild* GetIPDLActor();
 
   /**
    * TODO[nical] doc!
    */
   void ForceRemove();
 
 private:
-  Atomic<int> mRefCount;
-
   /**
    * Called once, just before the destructor.
    *
    * Here goes the shut-down code that uses virtual methods.
    * Must only be called by Release().
    */
   void Finalize();
 
+  friend class AtomicRefCountedWithFinalize<TextureClient>;
+
 protected:
   void AddFlags(TextureFlags  aFlags)
   {
     MOZ_ASSERT(!IsSharedWithCompositor());
     mFlags |= aFlags;
   }
 
   TextureChild* mActor;
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -207,18 +207,17 @@ CreateBackendIndependentTextureHost(cons
 void
 TextureHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
 {
     mCompositableBackendData = aBackendData;
 }
 
 
 TextureHost::TextureHost(TextureFlags aFlags)
-    : mRefCount(0)
-    , mFlags(aFlags)
+    : mFlags(aFlags)
 {}
 
 TextureHost::~TextureHost()
 {
 }
 
 void TextureHost::Finalize()
 {
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -18,16 +18,17 @@
 #include "mozilla/layers/CompositorTypes.h"  // for TextureFlags, etc
 #include "mozilla/layers/LayersTypes.h"  // for LayerRenderState, etc
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 #include "nscore.h"                     // for nsACString
+#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
 
 class gfxImageSurface;
 class gfxReusableSurfaceWrapper;
 struct nsIntPoint;
 struct nsIntSize;
 struct nsIntRect;
 
 namespace mozilla {
@@ -254,48 +255,33 @@ private:
  * matches the lifetime of the TextureClient/Host pair. It also means
  * TextureClient/Host do not implement double buffering, which is the
  * reponsibility of the compositable (which would use two Texture pairs).
  *
  * The Lock/Unlock mecanism here mirrors Lock/Unlock in TextureClient.
  *
  */
 class TextureHost
+  : public AtomicRefCountedWithFinalize<TextureHost>
 {
-  Atomic<int> mRefCount;
-
   /**
    * Called once, just before the destructor.
    *
    * Here goes the shut-down code that uses virtual methods.
    * Must only be called by Release().
    */
   void Finalize();
 
+  friend class AtomicRefCountedWithFinalize<TextureHost>;
+
 public:
   TextureHost(TextureFlags aFlags);
 
   virtual ~TextureHost();
 
-  void AddRef() {
-    MOZ_ASSERT(mRefCount >= 0);
-    ++mRefCount;
-  }
-
-  void Release() {
-    MOZ_ASSERT(mRefCount > 0);
-    if (0 == --mRefCount) {
-#ifdef DEBUG
-      mRefCount = detail::DEAD;
-#endif
-      Finalize();
-      delete this;
-    }
-  }
-
   /**
    * Factory method.
    */
   static TemporaryRef<TextureHost> Create(const SurfaceDescriptor& aDesc,
                                           ISurfaceAllocator* aDeallocator,
                                           TextureFlags aFlags);
 
   /**
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -93,16 +93,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
             'd3d11/CompositorD3D11.cpp',
         ]
 
 EXPORTS.gfxipc += [
     'ipc/ShadowLayerUtils.h',
 ]
 
 EXPORTS.mozilla.layers += [
+    'AtomicRefCountedWithFinalize.h',
     'basic/BasicCompositor.h',
     'basic/MacIOSurfaceTextureHostBasic.h',
     'basic/TextureHostBasic.h',
     'client/CanvasClient.h',
     'client/CompositableClient.h',
     'client/ContentClient.h',
     'client/ImageClient.h',
     'client/TextureClient.h',