Bug 933082 - Part 4: let ClientLayerManager hold a ShadowLayerForwarder instead of inheriting from ShadowLayerForwarder. Make ISurfaceAllocator refcounted. Make SharedSurface_Gralloc keep its mAllocator alive - r=nical
☠☠ backed out by 641a86dd8f8d ☠ ☠
authorBenoit Jacob <bjacob@mozilla.com>
Tue, 26 Nov 2013 14:00:29 -0500
changeset 157585 7caa8e80b06a5e54dd426800c1890868221b6d1f
parent 157584 1509f8be5df30d9834e0c4b8b6c3343e31966d5e
child 157586 15efccc18eea15b6e4cf03fb95c89458dbf8a1db
push id25716
push userkwierso@gmail.com
push dateWed, 27 Nov 2013 01:32:11 +0000
treeherdermozilla-central@d822990ba9ee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs933082
milestone28.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 933082 - Part 4: let ClientLayerManager hold a ShadowLayerForwarder instead of inheriting from ShadowLayerForwarder. Make ISurfaceAllocator refcounted. Make SharedSurface_Gralloc keep its mAllocator alive - r=nical
dom/base/nsDOMWindowUtils.cpp
gfx/gl/SharedSurfaceGralloc.cpp
gfx/gl/SharedSurfaceGralloc.h
gfx/layers/client/ClientCanvasLayer.cpp
gfx/layers/client/ClientContainerLayer.h
gfx/layers/client/ClientImageLayer.cpp
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ClientLayerManager.h
gfx/layers/client/ClientThebesLayer.cpp
gfx/layers/client/ClientTiledThebesLayer.cpp
gfx/layers/client/TiledContentClient.cpp
gfx/layers/ipc/CompositableForwarder.h
gfx/layers/ipc/ISurfaceAllocator.h
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
widget/cocoa/nsChildView.mm
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1,15 +1,15 @@
 /* -*- 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
  * 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/CompositorParent.h"
-#include "mozilla/layers/PLayerTransactionChild.h"
+#include "mozilla/layers/LayerTransactionChild.h"
 #include "nsPresContext.h"
 #include "nsDOMClassInfoID.h"
 #include "nsError.h"
 #include "nsIDOMEvent.h"
 #include "nsDOMWindowUtils.h"
 #include "nsQueryContentEventResult.h"
 #include "CompositionStringSynthesizer.h"
 #include "nsGlobalWindow.h"
--- a/gfx/gl/SharedSurfaceGralloc.cpp
+++ b/gfx/gl/SharedSurfaceGralloc.cpp
@@ -38,17 +38,17 @@ SurfaceFactory_Gralloc::SurfaceFactory_G
     : SurfaceFactory_GL(prodGL, SharedSurfaceType::Gralloc, caps)
 {
     if (caps.surfaceAllocator) {
         allocator = caps.surfaceAllocator;
     }
 
     MOZ_ASSERT(allocator);
 
-    mAllocator = allocator->asWeakPtr();
+    mAllocator = allocator;
 }
 
 SharedSurface_Gralloc*
 SharedSurface_Gralloc::Create(GLContext* prodGL,
                               const GLFormats& formats,
                               const gfxIntSize& size,
                               bool hasAlpha,
                               ISurfaceAllocator* allocator)
--- a/gfx/gl/SharedSurfaceGralloc.h
+++ b/gfx/gl/SharedSurfaceGralloc.h
@@ -33,17 +33,17 @@ public:
     static SharedSurface_Gralloc* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->Type() == SharedSurfaceType::Gralloc);
 
         return (SharedSurface_Gralloc*)surf;
     }
 
 protected:
     GLLibraryEGL* const mEGL;
-    WeakPtr<layers::ISurfaceAllocator> mAllocator;
+    RefPtr<layers::ISurfaceAllocator> mAllocator;
     // We keep the SurfaceDescriptor around, because we'll end up
     // using it often and it's handy to do so.  The actual
     // GraphicBuffer is kept alive by the sp<GraphicBuffer> in
     // GrallocBufferActor; the actor will stay alive until we
     // explicitly destroy this descriptor (and thus deallocate the
     // actor) it in the destructor of this class.  This is okay to do
     // on the client, but is very bad to do on the server (because on
     // the client, the actor has no chance of going away unless the
@@ -59,17 +59,17 @@ protected:
                           layers::SurfaceDescriptorGralloc& desc,
                           GLuint prodTex)
         : SharedSurface_GL(SharedSurfaceType::Gralloc,
                            AttachmentType::GLTexture,
                            prodGL,
                            size,
                            hasAlpha)
         , mEGL(egl)
-        , mAllocator(allocator->asWeakPtr())
+        , mAllocator(allocator)
         , mDesc(desc)
         , mProdTex(prodTex)
     {}
 
     static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
 
 public:
     virtual ~SharedSurface_Gralloc();
@@ -88,17 +88,17 @@ public:
         return mDesc;
     }
 };
 
 class SurfaceFactory_Gralloc
     : public SurfaceFactory_GL
 {
 protected:
-    WeakPtr<layers::ISurfaceAllocator> mAllocator;
+    RefPtr<layers::ISurfaceAllocator> mAllocator;
 
 public:
     SurfaceFactory_Gralloc(GLContext* prodGL,
                            const SurfaceCaps& caps,
                            layers::ISurfaceAllocator* allocator = nullptr);
 
     virtual SharedSurface* CreateShared(const gfxIntSize& size) {
         bool hasAlpha = mReadCaps.alpha;
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -40,27 +40,27 @@ ClientCanvasLayer::Initialize(const Data
 
   if (mGLContext) {
     GLScreenBuffer* screen = mGLContext->Screen();
     SurfaceStreamType streamType =
         SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread,
                                           screen->PreserveBuffer());
     SurfaceFactory_GL* factory = nullptr;
     if (!mForceReadback) {
-      if (ClientManager()->GetCompositorBackendType() == mozilla::layers::LAYERS_OPENGL) {
+      if (ClientManager()->AsShadowForwarder()->GetCompositorBackendType() == mozilla::layers::LAYERS_OPENGL) {
         if (mGLContext->GetEGLContext()) {
           bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
 
           if (!isCrossProcess) {
             // [Basic/OGL Layers, OMTC] WebGL layer init.
             factory = SurfaceFactory_EGLImage::Create(mGLContext, screen->Caps());
           } else {
             // [Basic/OGL Layers, OOPC] WebGL layer init. (Out Of Process Compositing)
 #ifdef MOZ_WIDGET_GONK
-            factory = new SurfaceFactory_Gralloc(mGLContext, screen->Caps(), ClientManager());
+            factory = new SurfaceFactory_Gralloc(mGLContext, screen->Caps(), ClientManager()->AsShadowForwarder());
 #else
             // we could do readback here maybe
             NS_NOTREACHED("isCrossProcess but not on native B2G!");
 #endif
           }
         } else {
           // [Basic Layers, OMTC] WebGL layer init.
           // Well, this *should* work...
@@ -101,23 +101,23 @@ ClientCanvasLayer::RenderLayer()
       // We don't support locking for buffer surfaces currently
       flags |= TEXTURE_IMMEDIATE_UPLOAD;
     } else {
       // GLContext's SurfaceStream handles ownership itself,
       // and doesn't require layers to do any deallocation.
       flags |= TEXTURE_DEALLOCATE_CLIENT;
     }
     mCanvasClient = CanvasClient::CreateCanvasClient(GetCanvasClientType(),
-                                                     ClientManager(), flags);
+                                                     ClientManager()->AsShadowForwarder(), flags);
     if (!mCanvasClient) {
       return;
     }
     if (HasShadow()) {
       mCanvasClient->Connect();
-      ClientManager()->Attach(mCanvasClient, this);
+      ClientManager()->AsShadowForwarder()->Attach(mCanvasClient, this);
     }
   }
   
   FirePreTransactionCallback();
   mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);
 
   FireDidTransactionCallback();
 
--- a/gfx/layers/client/ClientContainerLayer.h
+++ b/gfx/layers/client/ClientContainerLayer.h
@@ -87,38 +87,38 @@ public:
     NS_ASSERTION(ClientManager()->InConstruction(),
                  "Can only set properties in construction phase");
     ContainerLayer::SetVisibleRegion(aRegion);
   }
   virtual void InsertAfter(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE
   {
     NS_ASSERTION(ClientManager()->InConstruction(),
                  "Can only set properties in construction phase");
-    ClientManager()->InsertAfter(ClientManager()->Hold(this),
-                                 ClientManager()->Hold(aChild),
-                                 aAfter ? ClientManager()->Hold(aAfter) : nullptr);
+    ClientManager()->AsShadowForwarder()->InsertAfter(ClientManager()->Hold(this),
+                                                      ClientManager()->Hold(aChild),
+                                                      aAfter ? ClientManager()->Hold(aAfter) : nullptr);
     ContainerLayer::InsertAfter(aChild, aAfter);
   }
 
   virtual void RemoveChild(Layer* aChild) MOZ_OVERRIDE
   { 
     NS_ASSERTION(ClientManager()->InConstruction(),
                  "Can only set properties in construction phase");
-    ClientManager()->RemoveChild(ClientManager()->Hold(this),
-                                 ClientManager()->Hold(aChild));
+    ClientManager()->AsShadowForwarder()->RemoveChild(ClientManager()->Hold(this),
+                                                      ClientManager()->Hold(aChild));
     ContainerLayer::RemoveChild(aChild);
   }
 
   virtual void RepositionChild(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE
   {
     NS_ASSERTION(ClientManager()->InConstruction(),
                  "Can only set properties in construction phase");
-    ClientManager()->RepositionChild(ClientManager()->Hold(this),
-                                     ClientManager()->Hold(aChild),
-                                     aAfter ? ClientManager()->Hold(aAfter) : nullptr);
+    ClientManager()->AsShadowForwarder()->RepositionChild(ClientManager()->Hold(this),
+                                                          ClientManager()->Hold(aChild),
+                                                          aAfter ? ClientManager()->Hold(aAfter) : nullptr);
     ContainerLayer::RepositionChild(aChild, aAfter);
   }
   
   virtual Layer* AsLayer() { return this; }
   virtual ShadowableLayer* AsShadowableLayer() { return this; }
 
   virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
   {
--- a/gfx/layers/client/ClientImageLayer.cpp
+++ b/gfx/layers/client/ClientImageLayer.cpp
@@ -138,28 +138,28 @@ ClientImageLayer::RenderLayer()
     if (type == BUFFER_UNKNOWN) {
       return;
     }
     TextureFlags flags = TEXTURE_FRONT;
     if (mDisallowBigImage) {
       flags |= TEXTURE_DISALLOW_BIGIMAGE;
     }
     mImageClient = ImageClient::CreateImageClient(type,
-                                                  ClientManager(),
+                                                  ClientManager()->AsShadowForwarder(),
                                                   flags);
     if (type == BUFFER_BRIDGE) {
       static_cast<ImageClientBridge*>(mImageClient.get())->SetLayer(this);
     }
 
     if (!mImageClient) {
       return;
     }
     if (HasShadow() && !mContainer->IsAsync()) {
       mImageClient->Connect();
-      ClientManager()->Attach(mImageClient, this);
+      ClientManager()->AsShadowForwarder()->Attach(mImageClient, this);
     }
     if (!mImageClient->UpdateImage(mContainer, GetContentFlags())) {
       return;
     }
   }
   if (mImageClient) {
     mImageClient->OnTransaction();
   }
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -15,17 +15,17 @@
 #include "mozilla/dom/TabChild.h"       // for TabChild
 #include "mozilla/hal_sandbox/PHal.h"   // for ScreenConfiguration
 #include "mozilla/layers/CompositableClient.h"  // for CompositableChild, etc
 #include "mozilla/layers/ContentClient.h"  // for ContentClientRemote
 #include "mozilla/layers/ISurfaceAllocator.h"
 #include "mozilla/layers/LayersMessages.h"  // for EditReply, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/PLayerChild.h"  // for PLayerChild
-#include "mozilla/layers/PLayerTransactionChild.h"
+#include "mozilla/layers/LayerTransactionChild.h"
 #include "nsAString.h"
 #include "nsIWidget.h"                  // for nsIWidget
 #include "nsTArray.h"                   // for AutoInfallibleTArray
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #endif
 
@@ -39,31 +39,32 @@ ClientLayerManager::ClientLayerManager(n
   : mPhase(PHASE_NONE)
   , mWidget(aWidget) 
   , mTargetRotation(ROTATION_0)
   , mRepeatTransaction(false)
   , mIsRepeatTransaction(false)
   , mTransactionIncomplete(false)
   , mCompositorMightResample(false)
   , mNeedsComposite(false)
+  , mForwarder(new ShadowLayerForwarder)
 {
   MOZ_COUNT_CTOR(ClientLayerManager);
 }
 
 ClientLayerManager::~ClientLayerManager()
 {
   mRoot = nullptr;
 
   MOZ_COUNT_DTOR(ClientLayerManager);
 }
 
 int32_t
 ClientLayerManager::GetMaxTextureSize() const
 {
-  return ShadowLayerForwarder::GetMaxTextureSize();
+  return mForwarder->GetMaxTextureSize();
 }
 
 void
 ClientLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
                                                   ScreenRotation aRotation)
 {
   mTargetRotation = aRotation;
   if (mWidget) {
@@ -77,31 +78,31 @@ ClientLayerManager::SetRoot(Layer* aLaye
   if (mRoot != aLayer) {
     // Have to hold the old root and its children in order to
     // maintain the same view of the layer tree in this process as
     // the parent sees.  Otherwise layers can be destroyed
     // mid-transaction and bad things can happen (v. bug 612573)
     if (mRoot) {
       Hold(mRoot);
     }
-    ShadowLayerForwarder::SetRoot(Hold(aLayer));
+    mForwarder->SetRoot(Hold(aLayer));
     NS_ASSERTION(aLayer, "Root can't be null");
     NS_ASSERTION(aLayer->Manager() == this, "Wrong manager");
     NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
     mRoot = aLayer;
   }
 }
 
 void
 ClientLayerManager::Mutated(Layer* aLayer)
 {
   LayerManager::Mutated(aLayer);
 
   NS_ASSERTION(InConstruction() || InDrawing(), "wrong phase");
-  ShadowLayerForwarder::Mutated(Hold(aLayer));
+  mForwarder->Mutated(Hold(aLayer));
 }
 
 void
 ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
 {
   mInTransaction = true;
 
 #ifdef MOZ_LAYERS_HAVE_LOG
@@ -124,17 +125,17 @@ ClientLayerManager::BeginTransactionWith
   } else {
     hal::ScreenConfiguration currentConfig;
     hal::GetCurrentScreenConfiguration(&currentConfig);
     orientation = currentConfig.orientation();
   }
   nsIntRect clientBounds;
   mWidget->GetClientBounds(clientBounds);
   clientBounds.x = clientBounds.y = 0;
-  ShadowLayerForwarder::BeginTransaction(mTargetBounds, mTargetRotation, clientBounds, orientation);
+  mForwarder->BeginTransaction(mTargetBounds, mTargetRotation, clientBounds, orientation);
 
   // If we're drawing on behalf of a context with async pan/zoom
   // enabled, then the entire buffer of thebes layers might be
   // composited (including resampling) asynchronously before we get
   // a chance to repaint, so we have to ensure that it's all valid
   // and not rotated.
   if (mWidget) {
     if (TabChild* window = mWidget->GetOwningTabChild()) {
@@ -259,30 +260,30 @@ ClientLayerManager::MakeSnapshotIfRequir
   if (!mShadowTarget) {
     return;
   }
   if (mWidget) {
     if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
       nsIntRect bounds;
       mWidget->GetBounds(bounds);
       SurfaceDescriptor inSnapshot, snapshot;
-      if (AllocSurfaceDescriptor(bounds.Size(),
-                                 GFX_CONTENT_COLOR_ALPHA,
-                                 &inSnapshot) &&
+      if (mForwarder->AllocSurfaceDescriptor(bounds.Size(),
+                                             GFX_CONTENT_COLOR_ALPHA,
+                                             &inSnapshot) &&
           // The compositor will usually reuse |snapshot| and return
           // it through |outSnapshot|, but if it doesn't, it's
           // responsible for freeing |snapshot|.
           remoteRenderer->SendMakeSnapshot(inSnapshot, &snapshot)) {
         AutoOpenSurface opener(OPEN_READ_ONLY, snapshot);
         gfxASurface* source = opener.Get();
 
         mShadowTarget->DrawSurface(source, source->GetSize());
       }
       if (IsSurfaceDescriptorValid(snapshot)) {
-        ShadowLayerForwarder::DestroySharedSurface(&snapshot);
+        mForwarder->DestroySharedSurface(&snapshot);
       }
     }
   }
   mShadowTarget = nullptr;
 }
 
 void
 ClientLayerManager::FlushRendering()
@@ -307,17 +308,17 @@ ClientLayerManager::SendInvalidRegion(co
 void
 ClientLayerManager::ForwardTransaction()
 {
   mPhase = PHASE_FORWARD;
 
   // forward this transaction's changeset to our LayerManagerComposite
   bool sent;
   AutoInfallibleTArray<EditReply, 10> replies;
-  if (HasShadowManager() && ShadowLayerForwarder::EndTransaction(&replies, &sent)) {
+  if (HasShadowManager() && mForwarder->EndTransaction(&replies, &sent)) {
     for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
       const EditReply& reply = replies[i];
 
       switch (reply.type()) {
       case EditReply::TOpContentBufferSwap: {
         MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));
 
         const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
@@ -388,31 +389,31 @@ ClientLayerManager::Hold(Layer* aLayer)
   mKeepAlive.AppendElement(aLayer);
   return shadowable;
 }
 
 bool
 ClientLayerManager::IsCompositingCheap()
 {
   // Whether compositing is cheap depends on the parent backend.
-  return mShadowManager &&
-         LayerManager::IsCompositingCheap(GetCompositorBackendType());
+  return mForwarder->mShadowManager &&
+         LayerManager::IsCompositingCheap(mForwarder->GetCompositorBackendType());
 }
 
 void
 ClientLayerManager::SetIsFirstPaint()
 {
-  ShadowLayerForwarder::SetIsFirstPaint();
+  mForwarder->SetIsFirstPaint();
 }
 
 void
 ClientLayerManager::ClearCachedResources(Layer* aSubtree)
 {
   MOZ_ASSERT(!HasShadowManager() || !aSubtree);
-  if (PLayerTransactionChild* manager = GetShadowManager()) {
+  if (LayerTransactionChild* manager = mForwarder->GetShadowManager()) {
     manager->SendClearCachedResources();
   }
   if (aSubtree) {
     ClearLayer(aSubtree);
   } else if (mRoot) {
     ClearLayer(mRoot);
   }
 }
@@ -425,17 +426,17 @@ ClientLayerManager::ClearLayer(Layer* aL
        child = child->GetNextSibling()) {
     ClearLayer(child);
   }
 }
 
 void
 ClientLayerManager::GetBackendName(nsAString& aName)
 {
-  switch (GetCompositorBackendType()) {
+  switch (mForwarder->GetCompositorBackendType()) {
     case LAYERS_BASIC: aName.AssignLiteral("Basic"); return;
     case LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
     case LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;
     case LAYERS_D3D10: aName.AssignLiteral("Direct3D 10"); return;
     case LAYERS_D3D11: aName.AssignLiteral("Direct3D 11"); return;
     default: NS_RUNTIMEABORT("Invalid backend");
   }
 }
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -29,28 +29,27 @@ class nsIWidget;
 namespace mozilla {
 namespace layers {
 
 class ClientThebesLayer;
 class CompositorChild;
 class ImageLayer;
 class PLayerChild;
 
-class ClientLayerManager : public LayerManager,
-                           public ShadowLayerForwarder
+class ClientLayerManager : public LayerManager
 {
   typedef nsTArray<nsRefPtr<Layer> > LayerRefArray;
 
 public:
   ClientLayerManager(nsIWidget* aWidget);
   virtual ~ClientLayerManager();
 
   virtual ShadowLayerForwarder* AsShadowForwarder()
   {
-    return this;
+    return mForwarder;
   }
 
   virtual int32_t GetMaxTextureSize() const;
 
   virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation);
   virtual void BeginTransactionWithTarget(gfxContext* aTarget);
   virtual void BeginTransaction();
   virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
@@ -70,27 +69,27 @@ public:
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
   virtual already_AddRefed<ImageLayer> CreateImageLayer();
   virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
   virtual already_AddRefed<ColorLayer> CreateColorLayer();
   virtual already_AddRefed<RefLayer> CreateRefLayer();
 
   virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
   {
-    return mTextureFactoryIdentifier;
+    return mForwarder->GetTextureFactoryIdentifier();
   }
 
   virtual void FlushRendering() MOZ_OVERRIDE;
   void SendInvalidRegion(const nsIntRegion& aRegion);
 
   virtual bool NeedsWidgetInvalidation() MOZ_OVERRIDE { return false; }
 
   ShadowableLayer* Hold(Layer* aLayer);
 
-  bool HasShadowManager() const { return ShadowLayerForwarder::HasShadowManager(); }
+  bool HasShadowManager() const { return mForwarder->HasShadowManager(); }
 
   virtual bool IsCompositingCheap();
   virtual bool HasShadowManagerInternal() const { return HasShadowManager(); }
 
   virtual void SetIsFirstPaint() MOZ_OVERRIDE;
 
   // Drop cached resources and ask our shadow manager to do the same,
   // if we have one.
@@ -201,16 +200,18 @@ private:
 
   // Used to repeat the transaction right away (to avoid rebuilding
   // a display list) to support progressive drawing.
   bool mRepeatTransaction;
   bool mIsRepeatTransaction;
   bool mTransactionIncomplete;
   bool mCompositorMightResample;
   bool mNeedsComposite;
+
+  RefPtr<ShadowLayerForwarder> mForwarder;
 };
 
 class ClientLayer : public ShadowableLayer
 {
 public:
   ClientLayer()
   {
     MOZ_COUNT_CTOR(ClientLayer);
@@ -250,22 +251,22 @@ public:
 // Create a shadow layer (PLayerChild) for aLayer, if we're forwarding
 // our layer tree to a parent process.  Record the new layer creation
 // in the current open transaction as a side effect.
 template<typename CreatedMethod> void
 CreateShadowFor(ClientLayer* aLayer,
                 ClientLayerManager* aMgr,
                 CreatedMethod aMethod)
 {
-  PLayerChild* shadow = aMgr->ConstructShadowFor(aLayer);
+  PLayerChild* shadow = aMgr->AsShadowForwarder()->ConstructShadowFor(aLayer);
   // XXX error handling
   NS_ABORT_IF_FALSE(shadow, "failed to create shadow");
 
   aLayer->SetShadow(shadow);
-  (aMgr->*aMethod)(aLayer);
+  (aMgr->AsShadowForwarder()->*aMethod)(aLayer);
   aMgr->Hold(aLayer->AsLayer());
 }
 
 #define CREATE_SHADOW(_type)                                       \
   CreateShadowFor(layer, this,                                     \
                   &ShadowLayerForwarder::Created ## _type ## Layer)
 
 
--- a/gfx/layers/client/ClientThebesLayer.cpp
+++ b/gfx/layers/client/ClientThebesLayer.cpp
@@ -89,22 +89,22 @@ ClientThebesLayer::PaintThebes()
 void
 ClientThebesLayer::RenderLayer()
 {
   if (GetMaskLayer()) {
     ToClientLayer(GetMaskLayer())->RenderLayer();
   }
   
   if (!mContentClient) {
-    mContentClient = ContentClient::CreateContentClient(ClientManager());
+    mContentClient = ContentClient::CreateContentClient(ClientManager()->AsShadowForwarder());
     if (!mContentClient) {
       return;
     }
     mContentClient->Connect();
-    ClientManager()->Attach(mContentClient, this);
+    ClientManager()->AsShadowForwarder()->Attach(mContentClient, this);
     MOZ_ASSERT(mContentClient->GetForwarder());
   }
 
   mContentClient->BeginPaint();
   PaintThebes();
   mContentClient->EndPaint();
 }
 
@@ -149,17 +149,17 @@ ClientThebesLayer::PaintBuffer(gfxContex
                                mVisibleRegion,
                                aDidSelfCopy);
 }
 
 already_AddRefed<ThebesLayer>
 ClientLayerManager::CreateThebesLayer()
 {
   NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
-  if (Preferences::GetBool("layers.force-tiles") && GetCompositorBackendType() == LAYERS_OPENGL) {
+  if (Preferences::GetBool("layers.force-tiles") && AsShadowForwarder()->GetCompositorBackendType() == LAYERS_OPENGL) {
     nsRefPtr<ClientTiledThebesLayer> layer =
       new ClientTiledThebesLayer(this);
     CREATE_SHADOW(Thebes);
     return layer.forget();
   } else
   {
     nsRefPtr<ClientThebesLayer> layer =
       new ClientThebesLayer(this);
--- a/gfx/layers/client/ClientTiledThebesLayer.cpp
+++ b/gfx/layers/client/ClientTiledThebesLayer.cpp
@@ -129,17 +129,17 @@ ClientTiledThebesLayer::RenderLayer()
     ClientManager()->SetTransactionIncomplete();
     return;
   }
 
   if (!mContentClient) {
     mContentClient = new TiledContentClient(this, ClientManager());
 
     mContentClient->Connect();
-    ClientManager()->Attach(mContentClient, this);
+    ClientManager()->AsShadowForwarder()->Attach(mContentClient, this);
     MOZ_ASSERT(mContentClient->GetForwarder());
   }
 
   if (mContentClient->mTiledBuffer.HasFormatChanged()) {
     mValidRegion = nsIntRegion();
   }
 
   nsIntRegion invalidRegion = mVisibleRegion;
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -311,17 +311,17 @@ BasicTiledLayerBuffer::PaintThebes(const
 
 BasicTiledLayerTile
 BasicTiledLayerBuffer::ValidateTileInternal(BasicTiledLayerTile aTile,
                                             const nsIntPoint& aTileOrigin,
                                             const nsIntRect& aDirtyRect)
 {
   if (aTile.IsPlaceholderTile()) {
     RefPtr<DeprecatedTextureClient> textureClient =
-      new DeprecatedTextureClientTile(mManager, TextureInfo(BUFFER_TILED));
+      new DeprecatedTextureClientTile(mManager->AsShadowForwarder(), TextureInfo(BUFFER_TILED));
     aTile.mDeprecatedTextureClient = static_cast<DeprecatedTextureClientTile*>(textureClient.get());
   }
   aTile.mDeprecatedTextureClient->EnsureAllocated(gfx::IntSize(GetTileLength(), GetTileLength()), GetContentType());
   gfxImageSurface* writableSurface = aTile.mDeprecatedTextureClient->LockImageSurface();
   // Bug 742100, this gfxContext really should live on the stack.
   nsRefPtr<gfxContext> ctxt;
 
   RefPtr<gfx::DrawTarget> writableDrawTarget;
--- a/gfx/layers/ipc/CompositableForwarder.h
+++ b/gfx/layers/ipc/CompositableForwarder.h
@@ -214,16 +214,21 @@ public:
     return mTextureFactoryIdentifier.mSupportsPartialUploads;
   }
 
   bool ForwardsToDifferentProcess() const
   {
     return mMultiProcess;
   }
 
+  const TextureFactoryIdentifier& GetTextureFactoryIdentifier() const
+  {
+    return mTextureFactoryIdentifier;
+  }
+
 protected:
   TextureFactoryIdentifier mTextureFactoryIdentifier;
   bool mMultiProcess;
 };
 
 } // namespace
 } // namespace
 
--- a/gfx/layers/ipc/ISurfaceAllocator.h
+++ b/gfx/layers/ipc/ISurfaceAllocator.h
@@ -6,17 +6,17 @@
 #ifndef GFX_LAYERS_ISURFACEDEALLOCATOR
 #define GFX_LAYERS_ISURFACEDEALLOCATOR
 
 #include <stddef.h>                     // for size_t
 #include <stdint.h>                     // for uint32_t
 #include "gfxTypes.h"
 #include "gfxPoint.h"                   // for gfxIntSize
 #include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
-#include "mozilla/WeakPtr.h"
+#include "mozilla/RefPtr.h"
 #include "nsIMemoryReporter.h"          // for MemoryUniReporter
 #include "mozilla/Atomics.h"            // for Atomic
 
 /*
  * FIXME [bjacob] *** PURE CRAZYNESS WARNING ***
  *
  * This #define is actually needed here, because subclasses of ISurfaceAllocator,
  * namely ShadowLayerForwarder, will or will not override AllocGrallocBuffer
@@ -68,20 +68,20 @@ bool ReleaseOwnedSurfaceDescriptor(const
  * An interface used to create and destroy surfaces that are shared with the
  * Compositor process (using shmem, or gralloc, or other platform specific memory)
  *
  * Most of the methods here correspond to methods that are implemented by IPDL
  * actors without a common polymorphic interface.
  * These methods should be only called in the ipdl implementor's thread, unless
  * specified otherwise in the implementing class.
  */
-class ISurfaceAllocator : public SupportsWeakPtr<ISurfaceAllocator>
+class ISurfaceAllocator : public AtomicRefCounted<ISurfaceAllocator>
 {
 public:
-ISurfaceAllocator() {}
+  ISurfaceAllocator() {}
 
   /**
    * Allocate shared memory that can be accessed by only one process at a time.
    * Ownership of this memory is passed when the memory is sent in an IPDL
    * message.
    */
   virtual bool AllocShmem(size_t aSize,
                           mozilla::ipc::SharedMemory::SharedMemoryType aType,
@@ -135,17 +135,20 @@ protected:
   virtual bool IsOnCompositorSide() const = 0;
   static bool PlatformDestroySharedSurface(SurfaceDescriptor* aSurface);
   virtual bool PlatformAllocSurfaceDescriptor(const gfxIntSize& aSize,
                                               gfxContentType aContent,
                                               uint32_t aCaps,
                                               SurfaceDescriptor* aBuffer);
 
 
-  ~ISurfaceAllocator() {}
+  virtual ~ISurfaceAllocator() {}
+
+  friend class detail::RefCounted<ISurfaceAllocator, detail::AtomicRefCount>;
+  //friend class detail::RefCounted<ISurfaceAllocator, detail::AtomicRefCount>;
 };
 
 class GfxMemoryImageReporter MOZ_FINAL : public mozilla::MemoryUniReporter
 {
 public:
   GfxMemoryImageReporter()
     : MemoryUniReporter("explicit/gfx/heap-textures", KIND_HEAP, UNITS_BYTES,
                         "Heap memory shared between threads by texture clients and hosts.")
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -194,17 +194,17 @@ ImageBridgeChild::UpdateTextureNoSwap(Co
 void
 ImageBridgeChild::UpdatePictureRect(CompositableClient* aCompositable,
                                     const nsIntRect& aRect)
 {
   mTxn->AddNoSwapEdit(OpUpdatePictureRect(nullptr, aCompositable->GetIPDLActor(), aRect));
 }
 
 // Singleton
-static ImageBridgeChild *sImageBridgeChildSingleton = nullptr;
+static StaticRefPtr<ImageBridgeChild> sImageBridgeChildSingleton;
 static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton;
 static Thread *sImageBridgeChildThread = nullptr;
 
 // dispatched function
 static void StopImageBridgeSync(ReentrantMonitor *aBarrier, bool *aDone)
 {
   ReentrantMonitorAutoEnter autoMon(*aBarrier);
 
@@ -220,17 +220,16 @@ static void StopImageBridgeSync(Reentran
 
 // dispatched function
 static void DeleteImageBridgeSync(ReentrantMonitor *aBarrier, bool *aDone)
 {
   ReentrantMonitorAutoEnter autoMon(*aBarrier);
 
   NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
                     "Should be in ImageBridgeChild thread.");
-  delete sImageBridgeChildSingleton;
   sImageBridgeChildSingleton = nullptr;
   sImageBridgeParentSingleton = nullptr;
   *aDone = true;
   aBarrier->NotifyAll();
 }
 
 // dispatched function
 static void CreateImageClientSync(RefPtr<ImageClient>* result,
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
@@ -4,17 +4,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/DebugOnly.h"
 
 #include "mozilla/layers/PGrallocBufferChild.h"
 #include "mozilla/layers/PGrallocBufferParent.h"
-#include "mozilla/layers/PLayerTransactionChild.h"
+#include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/unused.h"
 #include "nsXULAppAPI.h"
 
 #include "ShadowLayerUtilsGralloc.h"
 
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -18,17 +18,17 @@
 #include "gfxPlatform.h"                // for gfxImageFormat, gfxPlatform
 #include "gfxSharedImageSurface.h"      // for gfxSharedImageSurface
 #include "ipc/IPCMessageUtils.h"        // for gfxContentType, null_t
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient, etc
 #include "mozilla/layers/LayersMessages.h"  // for Edit, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
-#include "mozilla/layers/PLayerTransactionChild.h"
+#include "mozilla/layers/LayerTransactionChild.h"
 #include "ShadowLayerUtils.h"
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr, getter_AddRefs, etc
 #include "nsDebug.h"                    // for NS_ABORT_IF_FALSE, etc
 #include "nsRect.h"                     // for nsIntRect
 #include "nsSize.h"                     // for nsIntSize
 #include "nsTArray.h"                   // for nsAutoTArray, nsTArray, etc
@@ -979,10 +979,16 @@ void ShadowLayerForwarder::AttachAsyncCo
                                                    ShadowableLayer* aLayer)
 {
   MOZ_ASSERT(aLayer);
   MOZ_ASSERT(aCompositableID != 0); // zero is always an invalid compositable id.
   mTxn->AddEdit(OpAttachAsyncCompositable(nullptr, Shadow(aLayer),
                                           aCompositableID));
 }
 
+void ShadowLayerForwarder::SetShadowManager(PLayerTransactionChild* aShadowManager)
+{
+  mShadowManager = static_cast<LayerTransactionChild*>(aShadowManager);
+}
+
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -41,16 +41,17 @@ class ContentClientRemote;
 class EditReply;
 class ImageClient;
 class ImageLayerComposite;
 class Layer;
 class OptionalThebesBuffer;
 class PLayerChild;
 class PLayerTransactionChild;
 class PLayerTransactionParent;
+class LayerTransactionChild;
 class RefLayerComposite;
 class ShadowableLayer;
 class Shmem;
 class ShmemTextureClient;
 class SurfaceDescriptor;
 class TextureClient;
 class ThebesLayerComposite;
 class ThebesBuffer;
@@ -132,16 +133,17 @@ class Transaction;
  * from the content thread. (See CompositableForwarder.h and ImageBridgeChild.h)
  */
 
 class ShadowLayerForwarder : public CompositableForwarder
 {
   friend class AutoOpenSurface;
   friend class DeprecatedTextureClientShmem;
   friend class ContentClientIncremental;
+  friend class ClientLayerManager;
 
 public:
   virtual ~ShadowLayerForwarder();
 
   /**
    * Setup the IPDL actor for aCompositable to be part of layers
    * transactions.
    */
@@ -334,26 +336,23 @@ public:
    * |aReplies| are directions from the LayerManagerComposite to the
    * caller of EndTransaction().
    */
   bool EndTransaction(InfallibleTArray<EditReply>* aReplies, bool* aSent);
 
   /**
    * Set an actor through which layer updates will be pushed.
    */
-  void SetShadowManager(PLayerTransactionChild* aShadowManager)
-  {
-    mShadowManager = aShadowManager;
-  }
+  void SetShadowManager(PLayerTransactionChild* aShadowManager);
 
   /**
    * True if this is forwarding to a LayerManagerComposite.
    */
   bool HasShadowManager() const { return !!mShadowManager; }
-  PLayerTransactionChild* GetShadowManager() const { return mShadowManager.get(); }
+  LayerTransactionChild* GetShadowManager() const { return mShadowManager.get(); }
 
   virtual void WindowOverlayChanged() { mWindowOverlayChanged = true; }
 
   /**
    * The following Alloc/Open/Destroy interfaces abstract over the
    * details of working with surfaces that are shared across
    * processes.  They provide the glue between C++ Layers and the
    * LayerComposite IPC system.
@@ -416,17 +415,17 @@ protected:
   ShadowLayerForwarder();
 
 #ifdef DEBUG
   void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const;
 #else
   void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const {}
 #endif
 
-  RefPtr<PLayerTransactionChild> mShadowManager;
+  RefPtr<LayerTransactionChild> mShadowManager;
 
 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
   // from ISurfaceAllocator
   virtual PGrallocBufferChild* AllocGrallocBuffer(const gfxIntSize& aSize,
                                                   uint32_t aFormat,
                                                   uint32_t aUsage,
                                                   MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE;
 #endif
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -3689,17 +3689,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
     if ([self isUsingOpenGL]) {
       // When our view covers the titlebar, we need to repaint the titlebar
       // texture buffer when, for example, the window buttons are hovered.
       // So we notify our nsChildView about any areas needing repainting.
       mGeckoChild->NotifyDirtyRegion([self nativeDirtyRegionWithBoundingRect:[self bounds]]);
 
       if (mGeckoChild->GetLayerManager()->GetBackendType() == LAYERS_CLIENT) {
         ClientLayerManager *manager = static_cast<ClientLayerManager*>(mGeckoChild->GetLayerManager());
-        manager->WindowOverlayChanged();
+        manager->AsShadowForwarder()->WindowOverlayChanged();
       }
     }
 
     mGeckoChild->WillPaintWindow();
   }
   [super viewWillDraw];
 }