Bug 747811 - Separate gfxReusableSurfaceWrapper into a base class and implementation. r=BenWa
authorChris Lord <chrislord.net@gmail.com>
Mon, 19 Aug 2013 14:59:25 +0100
changeset 156949 97d2a33c5455ee88788ea2bf4802a9edc4d63282
parent 156948 426f477baba5c239c79ff84e59185848a7395484
child 156950 2e1710495bd9f31109899d08e8353da809c249a6
push id407
push userlsblakk@mozilla.com
push dateTue, 03 Dec 2013 03:32:50 +0000
treeherdermozilla-release@babf8c9ebc52 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBenWa
bugs747811
milestone26.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 747811 - Separate gfxReusableSurfaceWrapper into a base class and implementation. r=BenWa Split gfxReusableSurfaceWrapper into gfxReusableSurfaceWrapper and gfxReusableSharedImageSurfaceWrapper, to allow for non gfxSharedImage-based implementations.
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TiledContentClient.cpp
gfx/thebes/gfxBaseSharedMemorySurface.h
gfx/thebes/gfxReusableSharedImageSurfaceWrapper.cpp
gfx/thebes/gfxReusableSharedImageSurfaceWrapper.h
gfx/thebes/gfxReusableSurfaceWrapper.cpp
gfx/thebes/gfxReusableSurfaceWrapper.h
gfx/thebes/moz.build
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -9,17 +9,17 @@
 #include "mozilla/layers/ImageClient.h"
 #include "mozilla/layers/CanvasClient.h"
 #include "mozilla/layers/ContentClient.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layers/SharedPlanarYCbCrImage.h"
 #include "GLContext.h"
 #include "BasicLayers.h" // for PaintContext
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
-#include "gfxReusableSurfaceWrapper.h"
+#include "gfxReusableSharedImageSurfaceWrapper.h"
 #include "gfxSharedImageSurface.h"
 #include "gfxPlatform.h"
 #include "mozilla/layers/ImageDataSerializer.h"
 #include "gfx2DGlue.h"
 
 #include <stdint.h>
 
 using namespace mozilla::gl;
@@ -475,17 +475,17 @@ bool
 DeprecatedTextureClientTile::EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType)
 {
   if (!mSurface ||
       mSurface->Format() != gfxPlatform::GetPlatform()->OptimalFormatForContent(aType)) {
     nsRefPtr<gfxSharedImageSurface> sharedImage =
       gfxSharedImageSurface::CreateUnsafe(mForwarder,
                                           gfxIntSize(aSize.width, aSize.height),
                                           gfxPlatform::GetPlatform()->OptimalFormatForContent(aType));
-    mSurface = new gfxReusableSurfaceWrapper(mForwarder, sharedImage);
+    mSurface = new gfxReusableSharedImageSurfaceWrapper(mForwarder, sharedImage);
     mContentType = aType;
   }
   return true;
 }
 
 gfxImageSurface*
 DeprecatedTextureClientTile::LockImageSurface()
 {
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -2,16 +2,17 @@
  * 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 "mozilla/layers/TiledContentClient.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/MathAlgorithms.h"
 #include "ClientTiledThebesLayer.h"
+#include "gfxReusableSharedImageSurfaceWrapper.h"
 
 #ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
 #include "cairo.h"
 #include <sstream>
 using mozilla::layers::Layer;
 static void DrawDebugOverlay(gfxASurface* imgSurf, int x, int y)
 {
   gfxContext c(imgSurf);
@@ -74,17 +75,17 @@ void
 TiledContentClient::LockCopyAndWrite(TiledBufferType aType)
 {
   BasicTiledLayerBuffer* buffer = aType == LOW_PRECISION_TILED_BUFFER
     ? &mLowPrecisionTiledBuffer
     : &mTiledBuffer;
 
   // Take an extra ReadLock on behalf of the TiledContentHost. This extra
   // reference will be adopted when the descriptor is opened by
-  // gfxReusableSurfaceWrapper::Open.
+  // gfxReusableSharedImageSurfaceWrapper::Open.
   buffer->ReadLock();
 
   mForwarder->PaintedTiledLayerBuffer(this, buffer->GetSurfaceDescriptorTiles());
   buffer->ClearPaintedRegion();
 }
 
 BasicTiledLayerBuffer::BasicTiledLayerBuffer(ClientTiledThebesLayer* aThebesLayer,
                                              ClientLayerManager* aManager)
@@ -110,24 +111,24 @@ BasicTiledLayerBuffer::GetContentType() 
     return gfxASurface::CONTENT_COLOR_ALPHA;
   }
 }
 
 
 BasicTileDescriptor
 BasicTiledLayerTile::GetTileDescriptor()
 {
-  return BasicTileDescriptor(GetSurface()->GetShmem());
+  return BasicTileDescriptor(static_cast<gfxReusableSharedImageSurfaceWrapper*>(GetSurface())->GetShmem());
 }
 
 /* static */ BasicTiledLayerTile
 BasicTiledLayerTile::OpenDescriptor(ISurfaceAllocator *aAllocator, const BasicTileDescriptor& aDesc)
 {
   nsRefPtr<gfxReusableSurfaceWrapper> surface =
-    gfxReusableSurfaceWrapper::Open(aAllocator, aDesc.reusableSurface());
+    gfxReusableSharedImageSurfaceWrapper::Open(aAllocator, aDesc.reusableSurface());
   return BasicTiledLayerTile(
     new DeprecatedTextureClientTile(nullptr, TextureInfo(BUFFER_TILED), surface));
 }
 
 SurfaceDescriptorTiles
 BasicTiledLayerBuffer::GetSurfaceDescriptorTiles()
 {
   InfallibleTArray<TileDescriptor> tiles;
--- a/gfx/thebes/gfxBaseSharedMemorySurface.h
+++ b/gfx/thebes/gfxBaseSharedMemorySurface.h
@@ -30,17 +30,17 @@ GetShmInfoPtr(const mozilla::ipc::Shmem&
 }
 
 extern const cairo_user_data_key_t SHM_KEY;
 
 template <typename Base, typename Sub>
 class gfxBaseSharedMemorySurface : public Base {
     typedef mozilla::ipc::SharedMemory SharedMemory;
     typedef mozilla::ipc::Shmem Shmem;
-    friend class gfxReusableSurfaceWrapper;
+    friend class gfxReusableSharedImageSurfaceWrapper;
 
 public:
     virtual ~gfxBaseSharedMemorySurface()
     {
         MOZ_COUNT_DTOR(gfxBaseSharedMemorySurface);
     }
 
     /**
rename from gfx/thebes/gfxReusableSurfaceWrapper.cpp
rename to gfx/thebes/gfxReusableSharedImageSurfaceWrapper.cpp
--- a/gfx/thebes/gfxReusableSurfaceWrapper.cpp
+++ b/gfx/thebes/gfxReusableSharedImageSurfaceWrapper.cpp
@@ -1,53 +1,53 @@
 /* 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 "gfxReusableSurfaceWrapper.h"
+#include "gfxReusableSharedImageSurfaceWrapper.h"
 #include "gfxSharedImageSurface.h"
 
 using mozilla::ipc::Shmem;
 using mozilla::layers::ISurfaceAllocator;
 
-gfxReusableSurfaceWrapper::gfxReusableSurfaceWrapper(ISurfaceAllocator* aAllocator,
-                                                     gfxSharedImageSurface* aSurface)
+gfxReusableSharedImageSurfaceWrapper::gfxReusableSharedImageSurfaceWrapper(ISurfaceAllocator* aAllocator,
+                                                                           gfxSharedImageSurface* aSurface)
   : mAllocator(aAllocator)
   , mSurface(aSurface)
 {
-  MOZ_COUNT_CTOR(gfxReusableSurfaceWrapper);
+  MOZ_COUNT_CTOR(gfxReusableSharedImageSurfaceWrapper);
   ReadLock();
 }
 
-gfxReusableSurfaceWrapper::~gfxReusableSurfaceWrapper()
+gfxReusableSharedImageSurfaceWrapper::~gfxReusableSharedImageSurfaceWrapper()
 {
-  MOZ_COUNT_DTOR(gfxReusableSurfaceWrapper);
+  MOZ_COUNT_DTOR(gfxReusableSharedImageSurfaceWrapper);
   ReadUnlock();
 }
 
 void
-gfxReusableSurfaceWrapper::ReadLock()
+gfxReusableSharedImageSurfaceWrapper::ReadLock()
 {
   NS_CheckThreadSafe(_mOwningThread.GetThread(), "Only the owner thread can call ReadLock");
   mSurface->ReadLock();
 }
 
 void
-gfxReusableSurfaceWrapper::ReadUnlock()
+gfxReusableSharedImageSurfaceWrapper::ReadUnlock()
 {
   int32_t readCount = mSurface->ReadUnlock();
   NS_ABORT_IF_FALSE(readCount >= 0, "Read count should not be negative");
 
   if (readCount == 0) {
     mAllocator->DeallocShmem(mSurface->GetShmem());
   }
 }
 
 gfxReusableSurfaceWrapper*
-gfxReusableSurfaceWrapper::GetWritable(gfxImageSurface** aSurface)
+gfxReusableSharedImageSurfaceWrapper::GetWritable(gfxImageSurface** aSurface)
 {
   NS_CheckThreadSafe(_mOwningThread.GetThread(), "Only the owner thread can call GetWritable");
 
   int32_t readCount = mSurface->GetReadCount();
   NS_ABORT_IF_FALSE(readCount > 0, "A ReadLock must be held when calling GetWritable");
   if (readCount == 1) {
     *aSurface = mSurface;
     return this;
@@ -55,43 +55,43 @@ gfxReusableSurfaceWrapper::GetWritable(g
 
   // Something else is reading the surface, copy it
   nsRefPtr<gfxSharedImageSurface> copySurface =
     gfxSharedImageSurface::CreateUnsafe(mAllocator, mSurface->GetSize(), mSurface->Format());
   copySurface->CopyFrom(mSurface);
   *aSurface = copySurface;
 
   // We need to create a new wrapper since this wrapper has an external ReadLock
-  gfxReusableSurfaceWrapper* wrapper = new gfxReusableSurfaceWrapper(mAllocator, copySurface);
+  gfxReusableSurfaceWrapper* wrapper = new gfxReusableSharedImageSurfaceWrapper(mAllocator, copySurface);
 
   // No need to release the ReadLock on the surface, this will happen when
   // the wrapper is destroyed.
 
   return wrapper;
 }
 
 const unsigned char*
-gfxReusableSurfaceWrapper::GetReadOnlyData() const
+gfxReusableSharedImageSurfaceWrapper::GetReadOnlyData() const
 {
   NS_ABORT_IF_FALSE(mSurface->GetReadCount() > 0, "Should have read lock");
   return mSurface->Data();
 }
 
 gfxASurface::gfxImageFormat
-gfxReusableSurfaceWrapper::Format()
+gfxReusableSharedImageSurfaceWrapper::Format()
 {
   return mSurface->Format();
 }
 
 Shmem&
-gfxReusableSurfaceWrapper::GetShmem()
+gfxReusableSharedImageSurfaceWrapper::GetShmem()
 {
   return mSurface->GetShmem();
 }
 
-/* static */ already_AddRefed<gfxReusableSurfaceWrapper>
-gfxReusableSurfaceWrapper::Open(ISurfaceAllocator* aAllocator, const Shmem& aShmem)
+/* static */ already_AddRefed<gfxReusableSharedImageSurfaceWrapper>
+gfxReusableSharedImageSurfaceWrapper::Open(ISurfaceAllocator* aAllocator, const Shmem& aShmem)
 {
   nsRefPtr<gfxSharedImageSurface> sharedImage = gfxSharedImageSurface::Open(aShmem);
-  nsRefPtr<gfxReusableSurfaceWrapper> wrapper = new gfxReusableSurfaceWrapper(aAllocator, sharedImage);
+  nsRefPtr<gfxReusableSharedImageSurfaceWrapper> wrapper = new gfxReusableSharedImageSurfaceWrapper(aAllocator, sharedImage);
   wrapper->ReadUnlock();
   return wrapper.forget();
 }
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/gfxReusableSharedImageSurfaceWrapper.h
@@ -0,0 +1,47 @@
+/* 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 GFXSHMCOWSURFACEWRAPPER
+#define GFXSHMCOWSURFACEWRAPPER
+
+#include "gfxReusableSurfaceWrapper.h"
+#include "mozilla/layers/ISurfaceAllocator.h"
+
+class gfxSharedImageSurface;
+
+/**
+ * A cross-process capable implementation of gfxReusableSurfaceWrapper based
+ * on gfxSharedImageSurface.
+ */
+class gfxReusableSharedImageSurfaceWrapper : public gfxReusableSurfaceWrapper {
+public:
+  gfxReusableSharedImageSurfaceWrapper(mozilla::layers::ISurfaceAllocator* aAllocator,
+                                       gfxSharedImageSurface* aSurface);
+  ~gfxReusableSharedImageSurfaceWrapper();
+
+  const unsigned char* GetReadOnlyData() const MOZ_OVERRIDE;
+  gfxASurface::gfxImageFormat Format() MOZ_OVERRIDE;
+  gfxReusableSurfaceWrapper* GetWritable(gfxImageSurface** aSurface) MOZ_OVERRIDE;
+  void ReadLock() MOZ_OVERRIDE;
+  void ReadUnlock() MOZ_OVERRIDE;
+
+  /**
+   * Returns the shared memory segment that backs the shared image surface.
+   */
+  mozilla::ipc::Shmem& GetShmem();
+
+  /**
+   * Create a gfxReusableSurfaceWrapper from the shared memory segment of a
+   * gfxSharedImageSurface. A ReadLock must be held, which will be adopted by
+   * the returned gfxReusableSurfaceWrapper.
+   */
+  static already_AddRefed<gfxReusableSharedImageSurfaceWrapper>
+  Open(mozilla::layers::ISurfaceAllocator* aAllocator, const mozilla::ipc::Shmem& aShmem);
+
+private:
+  mozilla::layers::ISurfaceAllocator*     mAllocator;
+  nsRefPtr<gfxSharedImageSurface>         mSurface;
+};
+
+#endif // GFXSHMCOWSURFACEWRAPPER
--- a/gfx/thebes/gfxReusableSurfaceWrapper.h
+++ b/gfx/thebes/gfxReusableSurfaceWrapper.h
@@ -1,83 +1,72 @@
 /* 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 GFXCOWSURFACEWRAPPER
 #define GFXCOWSURFACEWRAPPER
 
-#include "gfxASurface.h"
+#include "gfxImageSurface.h"
 #include "nsISupportsImpl.h"
 #include "nsAutoPtr.h"
-#include "mozilla/Atomics.h"
-#include "mozilla/layers/ISurfaceAllocator.h"
 
-class gfxSharedImageSurface;
 
 /**
- * Provides a cross thread wrapper for a gfxSharedImageSurface
- * that has copy-on-write schemantics.
+ * Provides an interface to implement a cross thread/process wrapper for a
+ * gfxImageSurface that has copy-on-write semantics.
  *
- * Only the owner thread can write to the surface and aquire
- * read locks.
+ * Only the owner thread can write to the surface and acquire
+ * read locks. Destroying a gfxReusableSurfaceWrapper releases
+ * a read lock.
  *
  * OMTC Usage:
  * 1) Content creates a writable copy of this surface
- *    wrapper which be optimized to the same wrapper if there
+ *    wrapper which will be optimized to the same wrapper if there
  *    are no readers.
  * 2) The surface is sent from content to the compositor once
- *    or potentially many time, each increasing a read lock.
- * 3) When the compositor has processed the surface and uploaded
- *    the content it then releases the read lock.
+ *    or potentially many times, each increasing a read lock.
+ * 3) When the compositor receives the surface, it adopts the
+ *    read lock.
+ * 4) Once the compositor has processed the surface and uploaded
+ *    the content, it then releases the read lock by dereferencing
+ *    its wrapper.
  */
 class gfxReusableSurfaceWrapper {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxReusableSurfaceWrapper)
 public:
-  /**
-   * Pass the gfxSharedImageSurface to the wrapper. The wrapper will ReadLock
-   * on creation and ReadUnlock on destruction.
-   */
-  gfxReusableSurfaceWrapper(mozilla::layers::ISurfaceAllocator* aAllocator, gfxSharedImageSurface* aSurface);
-
-  ~gfxReusableSurfaceWrapper();
-
-  const unsigned char* GetReadOnlyData() const;
-
-  mozilla::ipc::Shmem& GetShmem();
+  virtual ~gfxReusableSurfaceWrapper() {}
 
   /**
-   * Create a gfxReusableSurfaceWrapper from the shared memory segment of a
-   * gfxSharedImageSurface. A ReadLock must be held, which will be adopted by
-   * the returned gfxReusableSurfaceWrapper.
+   * Returns a read-only pointer to the image data.
    */
-  static already_AddRefed<gfxReusableSurfaceWrapper>
-  Open(mozilla::layers::ISurfaceAllocator* aAllocator, const mozilla::ipc::Shmem& aShmem);
-
-  gfxASurface::gfxImageFormat Format();
+  virtual const unsigned char* GetReadOnlyData() const = 0;
 
   /**
-   * Get a writable copy of the image.
+   * Returns the image surface format.
+   */
+  virtual gfxASurface::gfxImageFormat Format() = 0;
+
+  /**
+   * Returns a writable copy of the image.
    * If necessary this will copy the wrapper. If there are no contention
    * the same wrapper will be returned. A ReadLock must be held when
    * calling this function, and calling it will give up this lock.
    */
-  gfxReusableSurfaceWrapper* GetWritable(gfxImageSurface** aSurface);
+  virtual gfxReusableSurfaceWrapper* GetWritable(gfxImageSurface** aSurface) = 0;
 
   /**
    * A read only lock count is recorded, any attempts to
    * call GetWritable() while this count is greater than one will
    * create a new surface/wrapper pair.
    *
    * When a surface's read count falls to zero, its memory will be
    * deallocated. It is the responsibility of the user to make sure
    * that all locks are matched with an equal number of unlocks.
    */
-  void ReadLock();
-  void ReadUnlock();
+  virtual void ReadLock() = 0;
+  virtual void ReadUnlock() = 0;
 
-private:
+protected:
   NS_DECL_OWNINGTHREAD
-  mozilla::layers::ISurfaceAllocator*     mAllocator;
-  nsRefPtr<gfxSharedImageSurface>         mSurface;
 };
 
 #endif // GFXCOWSURFACEWRAPPER
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -31,16 +31,17 @@ EXPORTS += [
     'gfxPattern.h',
     'gfxPlatform.h',
     'gfxPoint.h',
     'gfxPoint3D.h',
     'gfxPointH3D.h',
     'gfxQuad.h',
     'gfxQuaternion.h',
     'gfxRect.h',
+    'gfxReusableSharedImageSurfaceWrapper.h',
     'gfxReusableSurfaceWrapper.h',
     'gfxSVGGlyphs.h',
     'gfxSharedImageSurface.h',
     'gfxSharedQuartzSurface.h',
     'gfxSkipChars.h',
     'gfxTeeSurface.h',
     'gfxTypes.h',
     'gfxUserFontSet.h',
@@ -245,17 +246,17 @@ CPP_SOURCES += [
     'gfxHarfBuzzShaper.cpp',
     'gfxImageSurface.cpp',
     'gfxMatrix.cpp',
     'gfxPath.cpp',
     'gfxPattern.cpp',
     'gfxPlatform.cpp',
     'gfxPlatformFontList.cpp',
     'gfxRect.cpp',
-    'gfxReusableSurfaceWrapper.cpp',
+    'gfxReusableSharedImageSurfaceWrapper.cpp',
     'gfxSVGGlyphs.cpp',
     'gfxScriptItemizer.cpp',
     'gfxSkipChars.cpp',
     'gfxTeeSurface.cpp',
     'gfxUserFontSet.cpp',
     'gfxUtils.cpp',
     'nsSurfaceTexture.cpp',
 ]