Backed out changeset a85da8081c68 (bug 1176011) of OSX failures
authorWes Kocher <wkocher@mozilla.com>
Wed, 08 Jun 2016 11:44:29 -0700
changeset 343282 1c0fc657e200d852dbb835027e652d0042858317
parent 343281 a8985f2347bd500ba2b5ff6063d8914ef0f4ef71
child 343283 a5e6427b76956ffb5f879ab7f3f17bd9e4bb9ac7
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1176011
milestone50.0a1
backs outa85da8081c68366a049c661229c93928d937b6b4
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
Backed out changeset a85da8081c68 (bug 1176011) of OSX failures
gfx/layers/D3D11ShareHandleImage.h
gfx/layers/D3D9SurfaceImage.h
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ClientLayerManager.h
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/client/TextureClientPool.cpp
gfx/layers/client/TextureClientPool.h
gfx/layers/client/TextureClientRecycleAllocator.cpp
gfx/layers/client/TextureClientRecycleAllocator.h
gfx/layers/client/TiledContentClient.cpp
gfx/layers/ipc/CompositableForwarder.h
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
gfx/layers/ipc/ISurfaceAllocator.cpp
gfx/layers/ipc/ISurfaceAllocator.h
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/TextureForwarder.h
gfx/layers/moz.build
--- a/gfx/layers/D3D11ShareHandleImage.h
+++ b/gfx/layers/D3D11ShareHandleImage.h
@@ -15,17 +15,17 @@
 #include "mozilla/layers/TextureClientRecycleAllocator.h"
 
 namespace mozilla {
 namespace layers {
 
 class D3D11RecycleAllocator : public TextureClientRecycleAllocator
 {
 public:
-  explicit D3D11RecycleAllocator(TextureForwarder* aAllocator,
+  explicit D3D11RecycleAllocator(CompositableForwarder* aAllocator,
                                  ID3D11Device* aDevice)
     : TextureClientRecycleAllocator(aAllocator)
     , mDevice(aDevice)
   {}
 
   already_AddRefed<TextureClient>
   CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
                         const gfx::IntSize& aSize);
--- a/gfx/layers/D3D9SurfaceImage.h
+++ b/gfx/layers/D3D9SurfaceImage.h
@@ -15,17 +15,17 @@
 namespace mozilla {
 namespace layers {
 
 class TextureClient;
 
 class D3D9RecycleAllocator : public TextureClientRecycleAllocator
 {
 public:
-  explicit D3D9RecycleAllocator(TextureForwarder* aAllocator,
+  explicit D3D9RecycleAllocator(CompositableForwarder* aAllocator,
                                 IDirect3DDevice9* aDevice)
     : TextureClientRecycleAllocator(aAllocator)
     , mDevice(aDevice)
   {}
 
   already_AddRefed<TextureClient>
   CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
                         const gfx::IntSize& aSize);
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -16,16 +16,17 @@
 #include "mozilla/layers/ContentClient.h"
 #include "mozilla/layers/FrameUniformityData.h"
 #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/LayerTransactionChild.h"
 #include "mozilla/layers/ShadowLayerChild.h"
+#include "mozilla/layers/TextureClientPool.h" // for TextureClientPool
 #include "mozilla/layers/PersistentBufferProvider.h"
 #include "ClientReadbackLayer.h"        // for ClientReadbackLayer
 #include "nsAString.h"
 #include "nsIWidgetListener.h"
 #include "nsTArray.h"                   // for AutoTArray
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
 #include "TiledLayerBuffer.h"
 #include "mozilla/dom/WindowBinding.h"  // for Overfill Callback
@@ -129,16 +130,19 @@ ClientLayerManager::~ClientLayerManager(
 }
 
 void
 ClientLayerManager::Destroy()
 {
   // It's important to call ClearCachedResource before Destroy because the
   // former will early-return if the later has already run.
   ClearCachedResources();
+  for (size_t i = 0; i < mTexturePools.Length(); i++) {
+    mTexturePools[i]->Destroy();
+  }
   LayerManager::Destroy();
 }
 
 int32_t
 ClientLayerManager::GetMaxTextureSize() const
 {
   return mForwarder->GetMaxTextureSize();
 }
@@ -420,16 +424,20 @@ ClientLayerManager::DidComposite(uint64_
     }
     mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
   }
 
   // These observers fire whether or not we were in a transaction.
   for (size_t i = 0; i < mDidCompositeObservers.Length(); i++) {
     mDidCompositeObservers[i]->DidComposite();
   }
+
+  for (size_t i = 0; i < mTexturePools.Length(); i++) {
+    mTexturePools[i]->ReturnDeferredClients();
+  }
 }
 
 void
 ClientLayerManager::GetCompositorSideAPZTestData(APZTestData* aData) const
 {
   if (mForwarder->HasShadowManager()) {
     if (!mForwarder->GetShadowManager()->SendGetAPZTestData(aData)) {
       NS_WARNING("Call to PLayerTransactionChild::SendGetAPZTestData() failed");
@@ -705,45 +713,67 @@ ClientLayerManager::AreComponentAlphaLay
 }
 
 void
 ClientLayerManager::SetIsFirstPaint()
 {
   mForwarder->SetIsFirstPaint();
 }
 
+TextureClientPool*
+ClientLayerManager::GetTexturePool(SurfaceFormat aFormat, TextureFlags aFlags)
+{
+  MOZ_DIAGNOSTIC_ASSERT(!mDestroyed);
+
+  for (size_t i = 0; i < mTexturePools.Length(); i++) {
+    if (mTexturePools[i]->GetFormat() == aFormat &&
+        mTexturePools[i]->GetFlags() == aFlags) {
+      return mTexturePools[i];
+    }
+  }
+
+  mTexturePools.AppendElement(
+      new TextureClientPool(aFormat, aFlags,
+                            IntSize(gfxPlatform::GetPlatform()->GetTileWidth(),
+                                    gfxPlatform::GetPlatform()->GetTileHeight()),
+                            gfxPrefs::LayersTileMaxPoolSize(),
+                            gfxPrefs::LayersTileShrinkPoolTimeout(),
+                            mForwarder));
+
+  return mTexturePools.LastElement();
+}
+
 void
 ClientLayerManager::ClearCachedResources(Layer* aSubtree)
 {
   if (mDestroyed) {
     // ClearCachedResource was already called by ClientLayerManager::Destroy
     return;
   }
   MOZ_ASSERT(!HasShadowManager() || !aSubtree);
   mForwarder->ClearCachedResources();
   if (aSubtree) {
     ClearLayer(aSubtree);
   } else if (mRoot) {
     ClearLayer(mRoot);
   }
-
-  if (GetCompositorBridgeChild()) {
-    GetCompositorBridgeChild()->ClearTexturePool();
+  for (size_t i = 0; i < mTexturePools.Length(); i++) {
+    mTexturePools[i]->Clear();
   }
 }
 
 void
 ClientLayerManager::HandleMemoryPressure()
 {
   if (mRoot) {
     HandleMemoryPressureLayer(mRoot);
   }
 
-  if (GetCompositorBridgeChild()) {
-    GetCompositorBridgeChild()->HandleMemoryPressure();
+  for (size_t i = 0; i < mTexturePools.Length(); i++) {
+    mTexturePools[i]->ShrinkToMinimumSize();
   }
 }
 
 void
 ClientLayerManager::ClearLayer(Layer* aLayer)
 {
   ClientLayer::ToClientLayer(aLayer)->ClearCachedResources();
   for (Layer* child = aLayer->GetFirstChild(); child;
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -30,16 +30,17 @@
 namespace mozilla {
 namespace layers {
 
 class ClientPaintedLayer;
 class CompositorBridgeChild;
 class ImageLayer;
 class PLayerChild;
 class FrameUniformityData;
+class TextureClientPool;
 
 class ClientLayerManager final : public LayerManager
 {
   typedef nsTArray<RefPtr<Layer> > LayerRefArray;
 
 public:
   explicit ClientLayerManager(nsIWidget* aWidget);
 
@@ -110,16 +111,18 @@ public:
 
   bool HasShadowManager() const { return mForwarder->HasShadowManager(); }
 
   virtual bool IsCompositingCheap() override;
   virtual bool HasShadowManagerInternal() const override { return HasShadowManager(); }
 
   virtual void SetIsFirstPaint() override;
 
+  TextureClientPool* GetTexturePool(gfx::SurfaceFormat aFormat, TextureFlags aFlags);
+
   /**
    * Pass through call to the forwarder for nsPresContext's
    * CollectPluginGeometryUpdates. Passes widget configuration information
    * to the compositor for transmission to the chrome process. This
    * configuration gets set when the window paints.
    */
   void StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration>&
                                        aConfigurations) override;
@@ -336,16 +339,17 @@ private:
 
   // An incrementing sequence number for paints.
   // Incremented in BeginTransaction(), but not for repeat transactions.
   uint32_t mPaintSequenceNumber;
 
   APZTestData mApzTestData;
 
   RefPtr<ShadowLayerForwarder> mForwarder;
+  AutoTArray<RefPtr<TextureClientPool>,2> mTexturePools;
   AutoTArray<dom::OverfillCallback*,0> mOverfillCallbacks;
   mozilla::TimeStamp mTransactionStart;
 
   nsTArray<DidCompositeObserver*> mDidCompositeObservers;
 
   RefPtr<MemoryPressureObserver> mMemoryPressureObserver;
   uint64_t mDeviceCounter;
 };
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -93,17 +93,16 @@ class TextureChild final : public ChildA
     // We should have deallocated mTextureData in ActorDestroy
     MOZ_ASSERT(!mTextureData);
   }
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureChild)
 
   TextureChild()
   : mForwarder(nullptr)
-  , mTextureForwarder(nullptr)
   , mTextureClient(nullptr)
   , mTextureData(nullptr)
   , mDestroyed(false)
   , mMainThreadOnly(false)
   , mIPCOpen(false)
   , mOwnsTextureData(false)
   {}
 
@@ -132,19 +131,18 @@ public:
     RECYCLE_LOG("[CLIENT] Cancelling wait for recycle %p\n", mWaitForRecycle.get());
 
     Lock();
     mWaitForRecycle = nullptr;
     Unlock();
   }
 
   CompositableForwarder* GetForwarder() { return mForwarder; }
-  TextureForwarder* GetTextureForwarder() { return mTextureForwarder; }
 
-  ClientIPCAllocator* GetAllocator() { return mTextureForwarder; }
+  ClientIPCAllocator* GetAllocator() { return mForwarder; }
 
   void ActorDestroy(ActorDestroyReason why) override;
 
   bool IPCOpen() const { return mIPCOpen; }
 
   void Lock() const { if (mForwarder->UsesImageBridge()) { mLock.Enter(); } }
 
   void Unlock() const { if (mForwarder->UsesImageBridge()) { mLock.Leave(); } }
@@ -227,17 +225,16 @@ private:
   // roles and the copy is needed to avoid the cost of re-drawing the valid
   // region.
   //
   // The important rule is that all of the dependent locking must occur only
   // in the texture's producer thread to avoid deadlocks.
   mutable gfx::CriticalSection mLock;
 
   RefPtr<CompositableForwarder> mForwarder;
-  RefPtr<TextureForwarder> mTextureForwarder;
   RefPtr<TextureClient> mWaitForRecycle;
 
   TextureClient* mTextureClient;
   TextureData* mTextureData;
   Atomic<bool> mDestroyed;
   bool mMainThreadOnly;
   bool mIPCOpen;
   bool mOwnsTextureData;
@@ -832,20 +829,17 @@ TextureClient::SetRecycleAllocator(IText
     ClearRecycleCallback();
   }
 }
 
 bool
 TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
 {
   MOZ_ASSERT(aForwarder && aForwarder->GetMessageLoop() == mAllocator->AsClientAllocator()->GetMessageLoop());
-  if (mActor && !mActor->mDestroyed) {
-    if (mActor->GetForwarder() != aForwarder) {
-      mActor->mForwarder = aForwarder;
-    }
+  if (mActor && !mActor->mDestroyed && mActor->GetForwarder() == aForwarder) {
     return true;
   }
   MOZ_ASSERT(!mActor || mActor->mDestroyed, "Cannot use a texture on several IPC channels.");
 
   SurfaceDescriptor desc;
   if (!ToSurfaceDescriptor(desc)) {
     return false;
   }
@@ -882,17 +876,17 @@ BackendTypeForBackendSelector(LayersBack
     default:
       MOZ_ASSERT_UNREACHABLE("Unknown backend selector");
       return gfx::BackendType::NONE;
   }
 };
 
 // static
 already_AddRefed<TextureClient>
-TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
+TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
                                 gfx::SurfaceFormat aFormat,
                                 gfx::IntSize aSize,
                                 BackendSelector aSelector,
                                 TextureFlags aTextureFlags,
                                 TextureAllocationFlags aAllocFlags)
 {
   // also test the validity of aAllocator
   MOZ_ASSERT(aAllocator && aAllocator->IPCOpen());
@@ -1365,29 +1359,30 @@ MemoryTextureReadLock::GetReadCount()
 }
 
 ShmemTextureReadLock::ShmemTextureReadLock(ClientIPCAllocator* aAllocator)
   : mAllocator(aAllocator)
   , mAllocSuccess(false)
 {
   MOZ_COUNT_CTOR(ShmemTextureReadLock);
   MOZ_ASSERT(mAllocator);
-  MOZ_ASSERT(mAllocator->AsTextureForwarder());
+  if (mAllocator) {
 #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
-  if (mAllocator->AsTextureForwarder()->GetTileLockAllocator()->AllocShmemSection(
-      MOZ_ALIGN_WORD(sizeof(ShmReadLockInfo)), &mShmemSection)) {
-    ShmReadLockInfo* info = GetShmReadLockInfoPtr();
-    info->readCount = 1;
-    mAllocSuccess = true;
+    if (mAllocator->AsLayerForwarder()->GetTileLockAllocator()->AllocShmemSection(
+        MOZ_ALIGN_WORD(sizeof(ShmReadLockInfo)), &mShmemSection)) {
+      ShmReadLockInfo* info = GetShmReadLockInfoPtr();
+      info->readCount = 1;
+      mAllocSuccess = true;
+    }
   }
 }
 
 ShmemTextureReadLock::~ShmemTextureReadLock()
 {
-  auto fwd = mAllocator->AsTextureForwarder();
+  auto fwd = mAllocator->AsLayerForwarder();
   if (fwd) {
     // Release one read count that is added in constructor.
     // The count is kept for calling GetReadCount() by TextureClientPool.
     ReadUnlock();
   }
   MOZ_COUNT_DTOR(ShmemTextureReadLock);
 }
 
@@ -1412,17 +1407,17 @@ int32_t
 ShmemTextureReadLock::ReadUnlock() {
   if (!mAllocSuccess) {
     return 0;
   }
   ShmReadLockInfo* info = GetShmReadLockInfoPtr();
   int32_t readCount = PR_ATOMIC_DECREMENT(&info->readCount);
   MOZ_ASSERT(readCount >= 0);
   if (readCount <= 0) {
-    auto fwd = mAllocator->AsTextureForwarder();
+    auto fwd = mAllocator->AsLayerForwarder();
     if (fwd) {
       fwd->GetTileLockAllocator()->DeallocShmemSection(mShmemSection);
     } else {
       // we are on the compositor process
       FixedSizeSmallShmemSectionAllocator::FreeShmemSection(mShmemSection);
     }
   }
   return readCount;
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -59,17 +59,16 @@ class TextureChild;
 class TextureData;
 struct RawTextureBuffer;
 class RawYCbCrTextureBuffer;
 class TextureClient;
 class ITextureClientRecycleAllocator;
 #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
 class TextureClientPool;
 #endif
-class TextureForwarder;
 class KeepAlive;
 
 /**
  * TextureClient is the abstraction that allows us to share data between the
  * content and the compositor side.
  */
 
 enum TextureAllocationFlags {
@@ -332,17 +331,17 @@ public:
 
   virtual ~TextureClient();
 
   static already_AddRefed<TextureClient>
   CreateWithData(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator);
 
   // Creates and allocates a TextureClient usable with Moz2D.
   static already_AddRefed<TextureClient>
-  CreateForDrawing(TextureForwarder* aAllocator,
+  CreateForDrawing(CompositableForwarder* aAllocator,
                    gfx::SurfaceFormat aFormat,
                    gfx::IntSize aSize,
                    BackendSelector aSelector,
                    TextureFlags aTextureFlags,
                    TextureAllocationFlags flags = ALLOC_DEFAULT);
 
   // Creates and allocates a TextureClient supporting the YCbCr format.
   static already_AddRefed<TextureClient>
--- a/gfx/layers/client/TextureClientPool.cpp
+++ b/gfx/layers/client/TextureClientPool.cpp
@@ -1,17 +1,16 @@
 /* -*- 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 "TextureClientPool.h"
 #include "CompositableClient.h"
 #include "mozilla/layers/CompositableForwarder.h"
-#include "mozilla/layers/TextureForwarder.h"
 #include "mozilla/layers/TiledContentClient.h"
 
 #include "gfxPrefs.h"
 
 #include "nsComponentManagerUtils.h"
 
 #define TCP_LOG(...)
 //#define TCP_LOG(...) printf_stderr(__VA_ARGS__);
@@ -25,17 +24,17 @@ ShrinkCallback(nsITimer *aTimer, void *a
   static_cast<TextureClientPool*>(aClosure)->ShrinkToMinimumSize();
 }
 
 TextureClientPool::TextureClientPool(gfx::SurfaceFormat aFormat,
                                      TextureFlags aFlags,
                                      gfx::IntSize aSize,
                                      uint32_t aMaxTextureClients,
                                      uint32_t aShrinkTimeoutMsec,
-                                     TextureForwarder* aAllocator)
+                                     CompositableForwarder* aAllocator)
   : mFormat(aFormat)
   , mFlags(aFlags)
   , mSize(aSize)
   , mMaxTextureClients(aMaxTextureClients)
   , mShrinkTimeoutMsec(aShrinkTimeoutMsec)
   , mOutstandingClients(0)
   , mSurfaceAllocator(aAllocator)
 {
--- a/gfx/layers/client/TextureClientPool.h
+++ b/gfx/layers/client/TextureClientPool.h
@@ -13,17 +13,17 @@
 #include "nsITimer.h"
 #include <stack>
 #include <list>
 
 namespace mozilla {
 namespace layers {
 
 class ISurfaceAllocator;
-class TextureForwarder;
+class CompositableForwarder;
 class TextureReadLock;
 
 class TextureClientAllocator
 {
 protected:
   virtual ~TextureClientAllocator() {}
 public:
   NS_INLINE_DECL_REFCOUNTING(TextureClientAllocator)
@@ -44,17 +44,17 @@ class TextureClientPool final : public T
   ~TextureClientPool();
 
 public:
   TextureClientPool(gfx::SurfaceFormat aFormat,
                     TextureFlags aFlags,
                     gfx::IntSize aSize,
                     uint32_t aMaxTextureClients,
                     uint32_t aShrinkTimeoutMsec,
-                    TextureForwarder* aAllocator);
+                    CompositableForwarder* aAllocator);
 
   /**
    * Gets an allocated TextureClient of size and format that are determined
    * by the initialisation parameters given to the pool. This will either be
    * a cached client that was returned to the pool, or a newly allocated
    * client if one isn't available.
    *
    * All clients retrieved by this method should be returned using the return
@@ -143,16 +143,15 @@ private:
 
   // On b2g gonk, std::queue might be a better choice.
   // On ICS, fence wait happens implicitly before drawing.
   // Since JB, fence wait happens explicitly when fetching a client from the pool.
   std::stack<RefPtr<TextureClient> > mTextureClients;
 
   std::list<RefPtr<TextureClient>> mTextureClientsDeferred;
   RefPtr<nsITimer> mTimer;
-  // This mSurfaceAllocator owns us, so no need to hold a ref to it
-  TextureForwarder* mSurfaceAllocator;
+  RefPtr<CompositableForwarder> mSurfaceAllocator;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_TEXTURECLIENTPOOL_H */
--- a/gfx/layers/client/TextureClientRecycleAllocator.cpp
+++ b/gfx/layers/client/TextureClientRecycleAllocator.cpp
@@ -1,16 +1,16 @@
 /* -*- 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 "gfxPlatform.h"
 #include "mozilla/layers/ISurfaceAllocator.h"
-#include "mozilla/layers/TextureForwarder.h"
+#include "mozilla/layers/CompositableForwarder.h"
 #include "TextureClientRecycleAllocator.h"
 
 namespace mozilla {
 namespace layers {
 
 // Used to keep TextureClient's reference count stable as not to disrupt recycling.
 class TextureClientHolder
 {
@@ -53,30 +53,30 @@ public:
   {
     if (aTextureClient->GetFormat() != mFormat ||
         aTextureClient->GetSize() != mSize) {
       return false;
     }
     return true;
   }
 
-  already_AddRefed<TextureClient> Allocate(TextureForwarder* aAllocator) override
+  already_AddRefed<TextureClient> Allocate(CompositableForwarder* aAllocator) override
   {
     return mAllocator->Allocate(mFormat,
                                 mSize,
                                 mSelector,
                                 mTextureFlags,
                                 mAllocationFlags);
   }
 
 protected:
   TextureClientRecycleAllocator* mAllocator;
 };
 
-TextureClientRecycleAllocator::TextureClientRecycleAllocator(TextureForwarder* aAllocator)
+TextureClientRecycleAllocator::TextureClientRecycleAllocator(CompositableForwarder* aAllocator)
   : mSurfaceAllocator(aAllocator)
   , mMaxPooledSize(kMaxPooledSized)
   , mLock("TextureClientRecycleAllocatorImp.mLock")
 {
 }
 
 TextureClientRecycleAllocator::~TextureClientRecycleAllocator()
 {
--- a/gfx/layers/client/TextureClientRecycleAllocator.h
+++ b/gfx/layers/client/TextureClientRecycleAllocator.h
@@ -4,17 +4,16 @@
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_TEXTURECLIENT_RECYCLE_ALLOCATOR_H
 #define MOZILLA_GFX_TEXTURECLIENT_RECYCLE_ALLOCATOR_H
 
 #include <map>
 #include <stack>
 #include "mozilla/gfx/Types.h"
-#include "mozilla/layers/TextureForwarder.h"
 #include "mozilla/RefPtr.h"
 #include "TextureClient.h"
 #include "mozilla/Mutex.h"
 
 namespace mozilla {
 namespace layers {
 
 class TextureClientHolder;
@@ -42,17 +41,17 @@ public:
                                  TextureAllocationFlags aAllocationFlags)
     : mFormat(aFormat)
     , mSize(aSize)
     , mSelector(aSelector)
     , mTextureFlags(aTextureFlags | TextureFlags::RECYCLE) // Set recycle flag
     , mAllocationFlags(aAllocationFlags)
   {}
 
-  virtual already_AddRefed<TextureClient> Allocate(TextureForwarder* aAllocator) = 0;
+  virtual already_AddRefed<TextureClient> Allocate(CompositableForwarder* aAllocator) = 0;
   virtual bool IsCompatible(TextureClient* aTextureClient) = 0;
 
   const gfx::SurfaceFormat mFormat;
   const gfx::IntSize mSize;
   const BackendSelector mSelector;
   const TextureFlags mTextureFlags;
   const TextureAllocationFlags mAllocationFlags;
 };
@@ -67,17 +66,17 @@ public:
  * clients.
  */
 class TextureClientRecycleAllocator : public ITextureClientRecycleAllocator
 {
 protected:
   virtual ~TextureClientRecycleAllocator();
 
 public:
-  explicit TextureClientRecycleAllocator(TextureForwarder* aAllocator);
+  explicit TextureClientRecycleAllocator(CompositableForwarder* aAllocator);
 
   void SetMaxPoolSize(uint32_t aMax);
 
   // Creates and allocates a TextureClient.
   already_AddRefed<TextureClient>
   CreateOrRecycle(gfx::SurfaceFormat aFormat,
                   gfx::IntSize aSize,
                   BackendSelector aSelector,
@@ -92,17 +91,17 @@ public:
 protected:
   virtual already_AddRefed<TextureClient>
   Allocate(gfx::SurfaceFormat aFormat,
            gfx::IntSize aSize,
            BackendSelector aSelector,
            TextureFlags aTextureFlags,
            TextureAllocationFlags aAllocFlags);
 
-  RefPtr<TextureForwarder> mSurfaceAllocator;
+  RefPtr<CompositableForwarder> mSurfaceAllocator;
 
   friend class DefaultTextureClientAllocationHelper;
   void RecycleTextureClient(TextureClient* aClient) override;
 
   static const uint32_t kMaxPooledSized = 2;
   uint32_t mMaxPooledSize;
 
   std::map<TextureClient*, RefPtr<TextureClientHolder> > mInUseClients;
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -1108,17 +1108,17 @@ ClientMultiTiledLayerBuffer::ValidateTil
   }
 #endif
 
   SurfaceMode mode;
   gfxContentType content = GetContentType(&mode);
 
   if (aTile.IsPlaceholderTile()) {
     aTile.SetLayerManager(mManager);
-    aTile.SetTextureAllocator(mManager->GetCompositorBridgeChild()->GetTexturePool(
+    aTile.SetTextureAllocator(mManager->GetTexturePool(
       gfxPlatform::GetPlatform()->Optimal2DFormatForContent(content),
       TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD));
   }
   aTile.SetCompositableClient(mCompositableClient);
 
   nsIntRegion offsetScaledDirtyRegion = aDirtyRegion.MovedBy(-aTileOrigin);
   offsetScaledDirtyRegion.ScaleRoundOut(mResolution, mResolution);
 
--- a/gfx/layers/ipc/CompositableForwarder.h
+++ b/gfx/layers/ipc/CompositableForwarder.h
@@ -10,17 +10,16 @@
 #include <stdint.h>                     // for int32_t, uint64_t
 #include "gfxTypes.h"
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/ISurfaceAllocator.h"  // for ISurfaceAllocator
 #include "mozilla/layers/LayersTypes.h"  // for LayersBackend
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
-#include "mozilla/layers/TextureForwarder.h"  // for TextureForwarder
 #include "nsRegion.h"                   // for nsIntRegion
 #include "mozilla/gfx/Rect.h"
 
 namespace mozilla {
 namespace layers {
 
 class CompositableClient;
 class AsyncTransactionTracker;
@@ -36,17 +35,17 @@ class PTextureChild;
  * should be sent to the compositor side.
  * CompositableForwarder is an interface to manage a transaction of
  * compositable objetcs.
  *
  * ShadowLayerForwarder is an example of a CompositableForwarder (that can
  * additionally forward modifications of the Layer tree).
  * ImageBridgeChild is another CompositableForwarder.
  */
-class CompositableForwarder : public TextureForwarder
+class CompositableForwarder : public ClientIPCAllocator
 {
 public:
 
   CompositableForwarder()
     : mSerial(++sSerialCounter)
   {}
 
   /**
@@ -59,16 +58,24 @@ public:
   /**
    * Tell the CompositableHost on the compositor side what TiledLayerBuffer to
    * use for the next composition.
    */
   virtual void UseTiledLayerBuffer(CompositableClient* aCompositable,
                                    const SurfaceDescriptorTiles& aTiledDescriptor) = 0;
 
   /**
+   * Create a TextureChild/Parent pair as as well as the TextureHost on the parent side.
+   */
+  virtual PTextureChild* CreateTexture(
+    const SurfaceDescriptor& aSharedData,
+    LayersBackend aLayersBackend,
+    TextureFlags aFlags) = 0;
+
+  /**
    * Communicate to the compositor that aRegion in the texture identified by
    * aCompositable and aIdentifier has been updated to aThebesBuffer.
    */
   virtual void UpdateTextureRegion(CompositableClient* aCompositable,
                                    const ThebesBufferData& aThebesBufferData,
                                    const nsIntRegion& aUpdatedRegion) = 0;
 
 #ifdef MOZ_WIDGET_GONK
@@ -124,23 +131,54 @@ public:
   virtual void UseComponentAlphaTextures(CompositableClient* aCompositable,
                                          TextureClient* aClientOnBlack,
                                          TextureClient* aClientOnWhite) = 0;
 
   virtual void SendPendingAsyncMessges() = 0;
 
   void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier);
 
+  virtual int32_t GetMaxTextureSize() const override
+  {
+    return mTextureFactoryIdentifier.mMaxTextureSize;
+  }
+
+  /**
+   * Returns the type of backend that is used off the main thread.
+   * We only don't allow changing the backend type at runtime so this value can
+   * be queried once and will not change until Gecko is restarted.
+   */
+  LayersBackend GetCompositorBackendType() const
+  {
+    return mTextureFactoryIdentifier.mParentBackend;
+  }
+
+  bool SupportsTextureBlitting() const
+  {
+    return mTextureFactoryIdentifier.mSupportsTextureBlitting;
+  }
+
+  bool SupportsPartialUploads() const
+  {
+    return mTextureFactoryIdentifier.mSupportsPartialUploads;
+  }
+
+  const TextureFactoryIdentifier& GetTextureFactoryIdentifier() const
+  {
+    return mTextureFactoryIdentifier;
+  }
+
   int32_t GetSerial() { return mSerial; }
 
   SyncObject* GetSyncObject() { return mSyncObject; }
 
   virtual CompositableForwarder* AsCompositableForwarder() override { return this; }
 
 protected:
+  TextureFactoryIdentifier mTextureFactoryIdentifier;
   nsTArray<RefPtr<TextureClient> > mTexturesToRemove;
   nsTArray<RefPtr<CompositableClient>> mCompositableClientsToRemove;
   RefPtr<SyncObject> mSyncObject;
   const int32_t mSerial;
   static mozilla::Atomic<int32_t> sSerialCounter;
 };
 
 } // namespace layers
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -8,17 +8,16 @@
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
 #include <stddef.h>                     // for size_t
 #include "ClientLayerManager.h"         // for ClientLayerManager
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/task.h"                  // for NewRunnableMethod, etc
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/PLayerTransactionChild.h"
-#include "mozilla/layers/TextureClientPool.h" // for TextureClientPool
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsIObserver.h"                // for nsIObserver
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
 #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop, etc
 #include "FrameLayerBuilder.h"
 #include "mozilla/dom/TabChild.h"
@@ -37,37 +36,27 @@ namespace layers {
 
 static StaticRefPtr<CompositorBridgeChild> sCompositorBridge;
 
 Atomic<int32_t> CompositableForwarder::sSerialCounter(0);
 
 CompositorBridgeChild::CompositorBridgeChild(ClientLayerManager *aLayerManager)
   : mLayerManager(aLayerManager)
   , mCanSend(false)
-  , mMessageLoop(MessageLoop::current())
- , mSectionAllocator(nullptr)
 {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  // Ensure destruction on the main thread
-  SetMessageLoopToPostDestructionTo(mMessageLoop);
 }
 
 CompositorBridgeChild::~CompositorBridgeChild()
 {
   RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
   XRE_GetIOMessageLoop()->PostTask(task.forget());
 
   if (mCanSend) {
     gfxCriticalError() << "CompositorBridgeChild was not deinitialized";
   }
-
-  if (mSectionAllocator) {
-    delete mSectionAllocator;
-  }
 }
 
 bool
 CompositorBridgeChild::IsSameProcess() const
 {
   return OtherPid() == base::GetCurrentProcId();
 }
 
@@ -80,26 +69,22 @@ static void DeferredDestroyCompositor(Re
     sCompositorBridge = nullptr;
   }
 }
 
 void
 CompositorBridgeChild::Destroy()
 {
   // This must not be called from the destructor!
-  MOZ_ASSERT(!IsDead());
+  MOZ_ASSERT(mRefCnt != 0);
 
   if (!mCanSend) {
     return;
   }
 
-  for (size_t i = 0; i < mTexturePools.Length(); i++) {
-    mTexturePools[i]->Destroy();
-  }
-
   // Destroying the layer manager may cause all sorts of things to happen, so
   // let's make sure there is still a reference to keep this alive whatever
   // happens.
   RefPtr<CompositorBridgeChild> selfRef = this;
 
   if (mLayerManager) {
     mLayerManager->Destroy();
     mLayerManager = nullptr;
@@ -428,21 +413,16 @@ CompositorBridgeChild::RecvDidComposite(
     RefPtr<ClientLayerManager> m = mLayerManager;
     m->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
   } else if (aId != 0) {
     RefPtr<dom::TabChild> child = dom::TabChild::GetFrom(aId);
     if (child) {
       child->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
     }
   }
-
-  for (size_t i = 0; i < mTexturePools.Length(); i++) {
-    mTexturePools[i]->ReturnDeferredClients();
-  }
-
   return true;
 }
 
 bool
 CompositorBridgeChild::RecvOverfill(const uint32_t &aOverfill)
 {
   for (size_t i = 0; i < mOverfillObservers.Length(); i++) {
     mOverfillObservers[i]->RunOverfillCallback(aOverfill);
@@ -791,87 +771,11 @@ CompositorBridgeChild::AllocPTextureChil
 }
 
 bool
 CompositorBridgeChild::DeallocPTextureChild(PTextureChild* actor)
 {
   return TextureClient::DestroyIPDLActor(actor);
 }
 
-TextureClientPool*
-CompositorBridgeChild::GetTexturePool(SurfaceFormat aFormat, TextureFlags aFlags)
-{
-  for (size_t i = 0; i < mTexturePools.Length(); i++) {
-    if (mTexturePools[i]->GetFormat() == aFormat &&
-        mTexturePools[i]->GetFlags() == aFlags) {
-      return mTexturePools[i];
-    }
-  }
-
-  mTexturePools.AppendElement(
-      new TextureClientPool(aFormat, aFlags,
-                            IntSize(gfxPlatform::GetPlatform()->GetTileWidth(),
-                                    gfxPlatform::GetPlatform()->GetTileHeight()),
-                            gfxPrefs::LayersTileMaxPoolSize(),
-                            gfxPrefs::LayersTileShrinkPoolTimeout(),
-                            this));
-
-  return mTexturePools.LastElement();
-}
-
-void
-CompositorBridgeChild::HandleMemoryPressure()
-{
-  for (size_t i = 0; i < mTexturePools.Length(); i++) {
-    mTexturePools[i]->ShrinkToMinimumSize();
-  }
-}
-
-void
-CompositorBridgeChild::ClearTexturePool()
-{
-  for (size_t i = 0; i < mTexturePools.Length(); i++) {
-    mTexturePools[i]->Clear();
-  }
-}
-
-PTextureChild*
-CompositorBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
-                                     LayersBackend aLayersBackend,
-                                     TextureFlags aFlags)
-{
-  return PCompositorBridgeChild::SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, 0 /* FIXME: Correct ID here? */);
-}
-
-bool
-CompositorBridgeChild::AllocUnsafeShmem(size_t aSize,
-                                   ipc::SharedMemory::SharedMemoryType aType,
-                                   ipc::Shmem* aShmem)
-{
-  return PCompositorBridgeChild::AllocUnsafeShmem(aSize, aType, aShmem);
-}
-
-bool
-CompositorBridgeChild::AllocShmem(size_t aSize,
-                             ipc::SharedMemory::SharedMemoryType aType,
-                             ipc::Shmem* aShmem)
-{
-  return PCompositorBridgeChild::AllocShmem(aSize, aType, aShmem);
-}
-
-void
-CompositorBridgeChild::DeallocShmem(ipc::Shmem& aShmem)
-{
-    PCompositorBridgeChild::DeallocShmem(aShmem);
-}
-
-FixedSizeSmallShmemSectionAllocator*
-CompositorBridgeChild::GetTileLockAllocator()
-{
-  if (!mSectionAllocator) {
-    mSectionAllocator = new FixedSizeSmallShmemSectionAllocator(this);
-  }
-  return mSectionAllocator;
-}
-
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -7,17 +7,16 @@
 #ifndef mozilla_layers_CompositorBridgeChild_h
 #define mozilla_layers_CompositorBridgeChild_h
 
 #include "base/basictypes.h"            // for DISALLOW_EVIL_CONSTRUCTORS
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/layers/PCompositorBridgeChild.h"
-#include "mozilla/layers/TextureForwarder.h" // for TextureForwarder
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsClassHashtable.h"           // for nsClassHashtable
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsHashKeys.h"                 // for nsUint64HashKey
 #include "nsISupportsImpl.h"            // for NS_INLINE_DECL_REFCOUNTING
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
 #include "nsWeakReference.h"
 
@@ -28,23 +27,22 @@ namespace dom {
 } // namespace dom
 
 namespace layers {
 
 using mozilla::dom::TabChild;
 
 class ClientLayerManager;
 class CompositorBridgeParent;
-class TextureClientPool;
 struct FrameMetrics;
 
-class CompositorBridgeChild final : public PCompositorBridgeChild,
-                                    public TextureForwarder,
-                                    public ShmemAllocator
+class CompositorBridgeChild final : public PCompositorBridgeChild
 {
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorBridgeChild)
+
 public:
   explicit CompositorBridgeChild(ClientLayerManager *aLayerManager);
 
   void Destroy();
 
   /**
    * Lookup the FrameMetrics shared by the compositor process with the
    * associated FrameMetrics::ViewID. The returned FrameMetrics is used
@@ -100,20 +98,16 @@ public:
 
   virtual PTextureChild* AllocPTextureChild(const SurfaceDescriptor& aSharedData,
                                             const LayersBackend& aLayersBackend,
                                             const TextureFlags& aFlags,
                                             const uint64_t& aId) override;
 
   virtual bool DeallocPTextureChild(PTextureChild* actor) override;
 
-  virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
-                                       LayersBackend aLayersBackend,
-                                       TextureFlags aFlags) override;
-
   /**
    * Request that the parent tell us when graphics are ready on GPU.
    * When we get that message, we bounce it to the TabParent via
    * the TabChild
    * @param tabChild The object to bounce the note to.  Non-NULL.
    */
   void RequestNotifyAfterRemotePaint(TabChild* aTabChild);
 
@@ -138,39 +132,20 @@ public:
   bool SendStartFrameTimeRecording(const int32_t& bufferSize, uint32_t* startIndex);
   bool SendStopFrameTimeRecording(const uint32_t& startIndex, nsTArray<float>* intervals);
   bool SendNotifyRegionInvalidated(const nsIntRegion& region);
   bool SendRequestNotifyAfterRemotePaint();
   bool SendClearVisibleRegions(uint64_t aLayersId, uint32_t aPresShellId);
   bool SendUpdateVisibleRegion(VisibilityCounter aCounter,
                                const ScrollableLayerGuid& aGuid,
                                const mozilla::CSSIntRegion& aRegion);
-  bool IsSameProcess() const override;
+  bool IsSameProcess() const;
 
   static void ShutDown();
 
-  TextureClientPool* GetTexturePool(gfx::SurfaceFormat aFormat, TextureFlags aFlags);
-  void ClearTexturePool();
-
-  void HandleMemoryPressure();
-
-  virtual MessageLoop* GetMessageLoop() const override { return mMessageLoop; }
-
-  virtual bool AllocUnsafeShmem(size_t aSize,
-                                mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
-                                mozilla::ipc::Shmem* aShmem) override;
-  virtual bool AllocShmem(size_t aSize,
-                          mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
-                          mozilla::ipc::Shmem* aShmem) override;
-  virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
-
-  virtual ShmemAllocator* AsShmemAllocator() override { return this; }
-
-  FixedSizeSmallShmemSectionAllocator* GetTileLockAllocator() override;
-
 private:
   // Private destructor, to discourage deletion outside of Release():
   virtual ~CompositorBridgeChild();
 
   virtual PLayerTransactionChild*
     AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
                                 const uint64_t& aId,
                                 TextureFactoryIdentifier* aTextureFactoryIdentifier,
@@ -232,20 +207,14 @@ private:
 
   DISALLOW_EVIL_CONSTRUCTORS(CompositorBridgeChild);
 
   // When we receive overfill numbers, notify these client layer managers
   AutoTArray<ClientLayerManager*,0> mOverfillObservers;
 
   // True until the beginning of the two-step shutdown sequence of this actor.
   bool mCanSend;
-
-  MessageLoop* mMessageLoop;
-
-  AutoTArray<RefPtr<TextureClientPool>,2> mTexturePools;
-
-  FixedSizeSmallShmemSectionAllocator* mSectionAllocator;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_layers_CompositorBrigedChild_h
--- a/gfx/layers/ipc/ISurfaceAllocator.cpp
+++ b/gfx/layers/ipc/ISurfaceAllocator.cpp
@@ -14,169 +14,10 @@ NS_IMPL_ISUPPORTS(GfxMemoryImageReporter
 
 mozilla::Atomic<ptrdiff_t> GfxMemoryImageReporter::sAmount(0);
 
 mozilla::ipc::SharedMemory::SharedMemoryType OptimalShmemType()
 {
   return ipc::SharedMemory::SharedMemoryType::TYPE_BASIC;
 }
 
-// XXX - We should actually figure out the minimum shmem allocation size on
-// a certain platform and use that.
-const uint32_t sShmemPageSize = 4096;
-
-#ifdef DEBUG
-const uint32_t sSupportedBlockSize = 4;
-#endif
-
-FixedSizeSmallShmemSectionAllocator::FixedSizeSmallShmemSectionAllocator(ClientIPCAllocator* aShmProvider)
-: mShmProvider(aShmProvider)
-{
-  MOZ_ASSERT(mShmProvider && mShmProvider->AsShmemAllocator());
-}
-
-FixedSizeSmallShmemSectionAllocator::~FixedSizeSmallShmemSectionAllocator()
-{
-  ShrinkShmemSectionHeap();
-}
-
-bool
-FixedSizeSmallShmemSectionAllocator::AllocShmemSection(uint32_t aSize, ShmemSection* aShmemSection)
-{
-  // For now we only support sizes of 4. If we want to support different sizes
-  // some more complicated bookkeeping should be added.
-  MOZ_ASSERT(aSize == sSupportedBlockSize);
-  MOZ_ASSERT(aShmemSection);
-
-  if (!IPCOpen()) {
-    gfxCriticalError() << "Attempt to allocate a ShmemSection after shutdown.";
-    return false;
-  }
-
-  uint32_t allocationSize = (aSize + sizeof(ShmemSectionHeapAllocation));
-
-  for (size_t i = 0; i < mUsedShmems.size(); i++) {
-    ShmemSectionHeapHeader* header = mUsedShmems[i].get<ShmemSectionHeapHeader>();
-    if ((header->mAllocatedBlocks + 1) * allocationSize + sizeof(ShmemSectionHeapHeader) < sShmemPageSize) {
-      aShmemSection->shmem() = mUsedShmems[i];
-      MOZ_ASSERT(mUsedShmems[i].IsWritable());
-      break;
-    }
-  }
-
-  if (!aShmemSection->shmem().IsWritable()) {
-    ipc::Shmem tmp;
-    if (!GetShmAllocator()->AllocUnsafeShmem(sShmemPageSize, OptimalShmemType(), &tmp)) {
-      return false;
-    }
-
-    ShmemSectionHeapHeader* header = tmp.get<ShmemSectionHeapHeader>();
-    header->mTotalBlocks = 0;
-    header->mAllocatedBlocks = 0;
-
-    mUsedShmems.push_back(tmp);
-    aShmemSection->shmem() = tmp;
-  }
-
-  MOZ_ASSERT(aShmemSection->shmem().IsWritable());
-
-  ShmemSectionHeapHeader* header = aShmemSection->shmem().get<ShmemSectionHeapHeader>();
-  uint8_t* heap = aShmemSection->shmem().get<uint8_t>() + sizeof(ShmemSectionHeapHeader);
-
-  ShmemSectionHeapAllocation* allocHeader = nullptr;
-
-  if (header->mTotalBlocks > header->mAllocatedBlocks) {
-    // Search for the first available block.
-    for (size_t i = 0; i < header->mTotalBlocks; i++) {
-      allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);
-
-      if (allocHeader->mStatus == STATUS_FREED) {
-        break;
-      }
-      heap += allocationSize;
-    }
-    MOZ_ASSERT(allocHeader && allocHeader->mStatus == STATUS_FREED);
-    MOZ_ASSERT(allocHeader->mSize == sSupportedBlockSize);
-  } else {
-    heap += header->mTotalBlocks * allocationSize;
-
-    header->mTotalBlocks++;
-    allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);
-    allocHeader->mSize = aSize;
-  }
-
-  MOZ_ASSERT(allocHeader);
-  header->mAllocatedBlocks++;
-  allocHeader->mStatus = STATUS_ALLOCATED;
-
-  aShmemSection->size() = aSize;
-  aShmemSection->offset() = (heap + sizeof(ShmemSectionHeapAllocation)) - aShmemSection->shmem().get<uint8_t>();
-  ShrinkShmemSectionHeap();
-  return true;
-}
-
-void
-FixedSizeSmallShmemSectionAllocator::FreeShmemSection(mozilla::layers::ShmemSection& aShmemSection)
-{
-  MOZ_ASSERT(aShmemSection.size() == sSupportedBlockSize);
-  MOZ_ASSERT(aShmemSection.offset() < sShmemPageSize - sSupportedBlockSize);
-
-  if (!aShmemSection.shmem().IsWritable()) {
-    return;
-  }
-
-  ShmemSectionHeapAllocation* allocHeader =
-    reinterpret_cast<ShmemSectionHeapAllocation*>(aShmemSection.shmem().get<char>() +
-                                                  aShmemSection.offset() -
-                                                  sizeof(ShmemSectionHeapAllocation));
-
-  MOZ_ASSERT(allocHeader->mSize == aShmemSection.size());
-
-  DebugOnly<bool> success = allocHeader->mStatus.compareExchange(STATUS_ALLOCATED, STATUS_FREED);
-  // If this fails something really weird is going on.
-  MOZ_ASSERT(success);
-
-  ShmemSectionHeapHeader* header = aShmemSection.shmem().get<ShmemSectionHeapHeader>();
-  header->mAllocatedBlocks--;
-}
-
-void
-FixedSizeSmallShmemSectionAllocator::DeallocShmemSection(mozilla::layers::ShmemSection& aShmemSection)
-{
-  if (!IPCOpen()) {
-    gfxCriticalNote << "Attempt to dealloc a ShmemSections after shutdown.";
-    return;
-  }
-
-  FreeShmemSection(aShmemSection);
-  ShrinkShmemSectionHeap();
-}
-
-
-void
-FixedSizeSmallShmemSectionAllocator::ShrinkShmemSectionHeap()
-{
-  if (!IPCOpen()) {
-    mUsedShmems.clear();
-    return;
-  }
-
-  // The loop will terminate as we either increase i, or decrease size
-  // every time through.
-  size_t i = 0;
-  while (i < mUsedShmems.size()) {
-    ShmemSectionHeapHeader* header = mUsedShmems[i].get<ShmemSectionHeapHeader>();
-    if (header->mAllocatedBlocks == 0) {
-      GetShmAllocator()->DeallocShmem(mUsedShmems[i]);
-      // We don't particularly care about order, move the last one in the array
-      // to this position.
-      if (i < mUsedShmems.size() - 1) {
-        mUsedShmems[i] = mUsedShmems[mUsedShmems.size() - 1];
-      }
-      mUsedShmems.pop_back();
-    } else {
-      i++;
-    }
-  }
-}
-
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/ISurfaceAllocator.h
+++ b/gfx/layers/ipc/ISurfaceAllocator.h
@@ -38,17 +38,16 @@ class Shmem;
 namespace gfx {
 class DataSourceSurface;
 } // namespace gfx
 
 namespace layers {
 
 class CompositableForwarder;
 class ShadowLayerForwarder;
-class TextureForwarder;
 
 class ShmemAllocator;
 class ShmemSectionAllocator;
 class LegacySurfaceDescriptorAllocator;
 class ClientIPCAllocator;
 class HostIPCAllocator;
 
 enum BufferCapabilities {
@@ -85,18 +84,16 @@ public:
   // down-casting
 
   virtual ShmemAllocator* AsShmemAllocator() { return nullptr; }
 
   virtual ShmemSectionAllocator* AsShmemSectionAllocator() { return nullptr; }
 
   virtual CompositableForwarder* AsCompositableForwarder() { return nullptr; }
 
-  virtual TextureForwarder* AsTextureForwarder() { return nullptr; }
-
   virtual ShadowLayerForwarder* AsLayerForwarder() { return nullptr; }
 
   virtual ClientIPCAllocator* AsClientAllocator() { return nullptr; }
 
   virtual HostIPCAllocator* AsHostIPCAllocator() { return nullptr; }
 
   virtual LegacySurfaceDescriptorAllocator*
   AsLegacySurfaceDescriptorAllocator() { return nullptr; }
@@ -240,60 +237,12 @@ public:
 private:
   // Typically we use |size_t| in memory reporters, but in the past this
   // variable has sometimes gone negative due to missing DidAlloc() calls.
   // Therefore, we use a signed type so that any such negative values show up
   // as negative in about:memory, rather than as enormous positive numbers.
   static mozilla::Atomic<ptrdiff_t> sAmount;
 };
 
-/// A simple shmem section allocator that can only allocate small
-/// fixed size elements (only intended to be used to store tile
-/// copy-on-write locks for now).
-class FixedSizeSmallShmemSectionAllocator final : public ShmemSectionAllocator
-{
-public:
-  enum AllocationStatus
-  {
-    STATUS_ALLOCATED,
-    STATUS_FREED
-  };
-
-  struct ShmemSectionHeapHeader
-  {
-    Atomic<uint32_t> mTotalBlocks;
-    Atomic<uint32_t> mAllocatedBlocks;
-  };
-
-  struct ShmemSectionHeapAllocation
-  {
-    Atomic<uint32_t> mStatus;
-    uint32_t mSize;
-  };
-
-  explicit FixedSizeSmallShmemSectionAllocator(ClientIPCAllocator* aShmProvider);
-
-  ~FixedSizeSmallShmemSectionAllocator();
-
-  virtual bool AllocShmemSection(uint32_t aSize, ShmemSection* aShmemSection) override;
-
-  virtual void DeallocShmemSection(ShmemSection& aShmemSection) override;
-
-  virtual void MemoryPressure() override { ShrinkShmemSectionHeap(); }
-
-  // can be called on the compositor process.
-  static void FreeShmemSection(ShmemSection& aShmemSection);
-
-  void ShrinkShmemSectionHeap();
-
-  ShmemAllocator* GetShmAllocator() { return mShmProvider->AsShmemAllocator(); }
-
-  bool IPCOpen() const { return mShmProvider->IPCOpen(); }
-
-protected:
-  std::vector<mozilla::ipc::Shmem> mUsedShmems;
-  ClientIPCAllocator* mShmProvider;
-};
-
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -196,45 +196,224 @@ private:
   Transaction& operator=(const Transaction&);
 };
 struct AutoTxnEnd {
   explicit AutoTxnEnd(Transaction* aTxn) : mTxn(aTxn) {}
   ~AutoTxnEnd() { mTxn->End(); }
   Transaction* mTxn;
 };
 
+
+// XXX - We should actually figure out the minimum shmem allocation size on
+// a certain platform and use that.
+const uint32_t sShmemPageSize = 4096;
+
+#ifdef DEBUG
+const uint32_t sSupportedBlockSize = 4;
+#endif
+
+FixedSizeSmallShmemSectionAllocator::FixedSizeSmallShmemSectionAllocator(ClientIPCAllocator* aShmProvider)
+: mShmProvider(aShmProvider)
+{
+  MOZ_ASSERT(mShmProvider && mShmProvider->AsShmemAllocator());
+}
+
+FixedSizeSmallShmemSectionAllocator::~FixedSizeSmallShmemSectionAllocator()
+{
+  ShrinkShmemSectionHeap();
+}
+
+bool
+FixedSizeSmallShmemSectionAllocator::AllocShmemSection(uint32_t aSize, ShmemSection* aShmemSection)
+{
+  // For now we only support sizes of 4. If we want to support different sizes
+  // some more complicated bookkeeping should be added.
+  MOZ_ASSERT(aSize == sSupportedBlockSize);
+  MOZ_ASSERT(aShmemSection);
+
+  if (!IPCOpen()) {
+    gfxCriticalError() << "Attempt to allocate a ShmemSection after shutdown.";
+    return false;
+  }
+
+  uint32_t allocationSize = (aSize + sizeof(ShmemSectionHeapAllocation));
+
+  for (size_t i = 0; i < mUsedShmems.size(); i++) {
+    ShmemSectionHeapHeader* header = mUsedShmems[i].get<ShmemSectionHeapHeader>();
+    if ((header->mAllocatedBlocks + 1) * allocationSize + sizeof(ShmemSectionHeapHeader) < sShmemPageSize) {
+      aShmemSection->shmem() = mUsedShmems[i];
+      MOZ_ASSERT(mUsedShmems[i].IsWritable());
+      break;
+    }
+  }
+
+  if (!aShmemSection->shmem().IsWritable()) {
+    ipc::Shmem tmp;
+    if (!GetShmAllocator()->AllocUnsafeShmem(sShmemPageSize, OptimalShmemType(), &tmp)) {
+      return false;
+    }
+
+    ShmemSectionHeapHeader* header = tmp.get<ShmemSectionHeapHeader>();
+    header->mTotalBlocks = 0;
+    header->mAllocatedBlocks = 0;
+
+    mUsedShmems.push_back(tmp);
+    aShmemSection->shmem() = tmp;
+  }
+
+  MOZ_ASSERT(aShmemSection->shmem().IsWritable());
+
+  ShmemSectionHeapHeader* header = aShmemSection->shmem().get<ShmemSectionHeapHeader>();
+  uint8_t* heap = aShmemSection->shmem().get<uint8_t>() + sizeof(ShmemSectionHeapHeader);
+
+  ShmemSectionHeapAllocation* allocHeader = nullptr;
+
+  if (header->mTotalBlocks > header->mAllocatedBlocks) {
+    // Search for the first available block.
+    for (size_t i = 0; i < header->mTotalBlocks; i++) {
+      allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);
+
+      if (allocHeader->mStatus == STATUS_FREED) {
+        break;
+      }
+      heap += allocationSize;
+    }
+    MOZ_ASSERT(allocHeader && allocHeader->mStatus == STATUS_FREED);
+    MOZ_ASSERT(allocHeader->mSize == sSupportedBlockSize);
+  } else {
+    heap += header->mTotalBlocks * allocationSize;
+
+    header->mTotalBlocks++;
+    allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);
+    allocHeader->mSize = aSize;
+  }
+
+  MOZ_ASSERT(allocHeader);
+  header->mAllocatedBlocks++;
+  allocHeader->mStatus = STATUS_ALLOCATED;
+
+  aShmemSection->size() = aSize;
+  aShmemSection->offset() = (heap + sizeof(ShmemSectionHeapAllocation)) - aShmemSection->shmem().get<uint8_t>();
+  ShrinkShmemSectionHeap();
+  return true;
+}
+
+void
+FixedSizeSmallShmemSectionAllocator::FreeShmemSection(mozilla::layers::ShmemSection& aShmemSection)
+{
+  MOZ_ASSERT(aShmemSection.size() == sSupportedBlockSize);
+  MOZ_ASSERT(aShmemSection.offset() < sShmemPageSize - sSupportedBlockSize);
+
+  if (!aShmemSection.shmem().IsWritable()) {
+    return;
+  }
+
+  ShmemSectionHeapAllocation* allocHeader =
+    reinterpret_cast<ShmemSectionHeapAllocation*>(aShmemSection.shmem().get<char>() +
+                                                  aShmemSection.offset() -
+                                                  sizeof(ShmemSectionHeapAllocation));
+
+  MOZ_ASSERT(allocHeader->mSize == aShmemSection.size());
+
+  DebugOnly<bool> success = allocHeader->mStatus.compareExchange(STATUS_ALLOCATED, STATUS_FREED);
+  // If this fails something really weird is going on.
+  MOZ_ASSERT(success);
+
+  ShmemSectionHeapHeader* header = aShmemSection.shmem().get<ShmemSectionHeapHeader>();
+  header->mAllocatedBlocks--;
+}
+
+void
+FixedSizeSmallShmemSectionAllocator::DeallocShmemSection(mozilla::layers::ShmemSection& aShmemSection)
+{
+  if (!IPCOpen()) {
+    gfxCriticalNote << "Attempt to dealloc a ShmemSections after shutdown.";
+    return;
+  }
+
+  FreeShmemSection(aShmemSection);
+  ShrinkShmemSectionHeap();
+}
+
+
+void
+FixedSizeSmallShmemSectionAllocator::ShrinkShmemSectionHeap()
+{
+  if (!IPCOpen()) {
+    mUsedShmems.clear();
+    return;
+  }
+
+  // The loop will terminate as we either increase i, or decrease size
+  // every time through.
+  size_t i = 0;
+  while (i < mUsedShmems.size()) {
+    ShmemSectionHeapHeader* header = mUsedShmems[i].get<ShmemSectionHeapHeader>();
+    if (header->mAllocatedBlocks == 0) {
+      GetShmAllocator()->DeallocShmem(mUsedShmems[i]);
+      // We don't particularly care about order, move the last one in the array
+      // to this position.
+      if (i < mUsedShmems.size() - 1) {
+        mUsedShmems[i] = mUsedShmems[mUsedShmems.size() - 1];
+      }
+      mUsedShmems.pop_back();
+    } else {
+      i++;
+    }
+  }
+}
+
+FixedSizeSmallShmemSectionAllocator*
+ShadowLayerForwarder::GetTileLockAllocator()
+{
+  MOZ_ASSERT(IPCOpen());
+  if (!IPCOpen()) {
+    return nullptr;
+  }
+
+  if (!mSectionAllocator) {
+    mSectionAllocator = new FixedSizeSmallShmemSectionAllocator(this);
+  }
+  return mSectionAllocator;
+}
+
 void
 CompositableForwarder::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier)
 {
   mTextureFactoryIdentifier = aIdentifier;
 
   mSyncObject = SyncObject::CreateSyncObject(aIdentifier.mSyncHandle);
 }
 
 ShadowLayerForwarder::ShadowLayerForwarder()
  : mMessageLoop(MessageLoop::current())
  , mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
  , mIsFirstPaint(false)
  , mWindowOverlayChanged(false)
  , mPaintSyncId(0)
+ , mSectionAllocator(nullptr)
 {
   mTxn = new Transaction();
 }
 
 ShadowLayerForwarder::~ShadowLayerForwarder()
 {
   MOZ_ASSERT(mTxn->Finished(), "unfinished transaction?");
   if (!mTxn->mDestroyedActors.IsEmpty()) {
     mTxn->FallbackDestroyActors();
   }
   delete mTxn;
   if (mShadowManager) {
     mShadowManager->SetForwarder(nullptr);
     mShadowManager->Destroy();
   }
+
+  if (mSectionAllocator) {
+    delete mSectionAllocator;
+  }
 }
 
 void
 ShadowLayerForwarder::BeginTransaction(const gfx::IntRect& aTargetBounds,
                                        ScreenRotation aRotation,
                                        dom::ScreenOrientationInternal aOrientation)
 {
   MOZ_ASSERT(HasShadowManager(), "no manager to forward to");
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -125,16 +125,18 @@ public:
 
   virtual ShmemAllocator* AsShmemAllocator() override { return this; }
 
   virtual ShadowLayerForwarder* AsLayerForwarder() override { return this; }
 
   virtual LegacySurfaceDescriptorAllocator*
   AsLegacySurfaceDescriptorAllocator() override { return this; }
 
+  FixedSizeSmallShmemSectionAllocator* GetTileLockAllocator();
+
   /**
    * Setup the IPDL actor for aCompositable to be part of layers
    * transactions.
    */
   virtual void Connect(CompositableClient* aCompositable,
                        ImageContainer* aImageContainer) override;
 
   virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
@@ -396,16 +398,17 @@ private:
   Transaction* mTxn;
   MessageLoop* mMessageLoop;
   std::vector<CompositableOperation> mPendingAsyncMessages;
   DiagnosticTypes mDiagnosticTypes;
   bool mIsFirstPaint;
   bool mWindowOverlayChanged;
   int32_t mPaintSyncId;
   InfallibleTArray<PluginWindowData> mPluginWindowData;
+  FixedSizeSmallShmemSectionAllocator* mSectionAllocator;
 };
 
 class CompositableClient;
 
 /**
  * A ShadowableLayer is a Layer can be shared with a parent context
  * through a ShadowLayerForwarder.  A ShadowableLayer maps to a
  * Shadow*Layer in a parent context.
@@ -432,12 +435,60 @@ public:
 
   virtual CompositableClient* GetCompositableClient() { return nullptr; }
 protected:
   ShadowableLayer() : mShadow(nullptr) {}
 
   PLayerChild* mShadow;
 };
 
+/// A simple shmem section allocator that can only allocate small
+/// fixed size elements (only intended to be used to store tile
+/// copy-on-write locks for now).
+class FixedSizeSmallShmemSectionAllocator final : public ShmemSectionAllocator
+{
+public:
+  enum AllocationStatus
+  {
+    STATUS_ALLOCATED,
+    STATUS_FREED
+  };
+
+  struct ShmemSectionHeapHeader
+  {
+    Atomic<uint32_t> mTotalBlocks;
+    Atomic<uint32_t> mAllocatedBlocks;
+  };
+
+  struct ShmemSectionHeapAllocation
+  {
+    Atomic<uint32_t> mStatus;
+    uint32_t mSize;
+  };
+
+  explicit FixedSizeSmallShmemSectionAllocator(ClientIPCAllocator* aShmProvider);
+
+  ~FixedSizeSmallShmemSectionAllocator();
+
+  virtual bool AllocShmemSection(uint32_t aSize, ShmemSection* aShmemSection) override;
+
+  virtual void DeallocShmemSection(ShmemSection& aShmemSection) override;
+
+  virtual void MemoryPressure() override { ShrinkShmemSectionHeap(); }
+
+  // can be called on the compositor process.
+  static void FreeShmemSection(ShmemSection& aShmemSection);
+
+  void ShrinkShmemSectionHeap();
+
+  ShmemAllocator* GetShmAllocator() { return mShmProvider->AsShmemAllocator(); }
+
+  bool IPCOpen() const { return mShmProvider->IPCOpen(); }
+
+protected:
+  std::vector<mozilla::ipc::Shmem> mUsedShmems;
+  ClientIPCAllocator* mShmProvider;
+};
+
 } // namespace layers
 } // namespace mozilla
 
 #endif // ifndef mozilla_layers_ShadowLayers_h
deleted file mode 100644
--- a/gfx/layers/ipc/TextureForwarder.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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/. */
-
-#ifndef MOZILLA_LAYERS_TEXTUREFORWARDER
-#define MOZILLA_LAYERS_TEXTUREFORWARDER
-
-#include <stdint.h>                     // for int32_t, uint64_t
-#include "gfxTypes.h"
-#include "mozilla/Attributes.h"         // for override
-#include "mozilla/layers/ISurfaceAllocator.h"  // for ISurfaceAllocator
-#include "mozilla/layers/LayersTypes.h"  // for LayersBackend
-#include "mozilla/layers/TextureClient.h"  // for TextureClient
-#include "nsRegion.h"                   // for nsIntRegion
-#include "mozilla/gfx/Rect.h"
-
-namespace mozilla {
-namespace layers {
-
-class TextureForwarder : public ClientIPCAllocator
-{
-public:
-
-  TextureForwarder()
-  {}
-
-  /**
-   * Create a TextureChild/Parent pair as as well as the TextureHost on the parent side.
-   */
-  virtual PTextureChild* CreateTexture(
-    const SurfaceDescriptor& aSharedData,
-    LayersBackend aLayersBackend,
-    TextureFlags aFlags) = 0;
-
-  virtual TextureForwarder* AsTextureForwarder() override { return this; }
-
-  virtual int32_t GetMaxTextureSize() const override
-  {
-    return mTextureFactoryIdentifier.mMaxTextureSize;
-  }
-
-  /**
-   * Returns the type of backend that is used off the main thread.
-   * We only don't allow changing the backend type at runtime so this value can
-   * be queried once and will not change until Gecko is restarted.
-   */
-  LayersBackend GetCompositorBackendType() const
-  {
-    return mTextureFactoryIdentifier.mParentBackend;
-  }
-
-  bool SupportsTextureBlitting() const
-  {
-    return mTextureFactoryIdentifier.mSupportsTextureBlitting;
-  }
-
-  bool SupportsPartialUploads() const
-  {
-    return mTextureFactoryIdentifier.mSupportsPartialUploads;
-  }
-
-  const TextureFactoryIdentifier& GetTextureFactoryIdentifier() const
-  {
-    return mTextureFactoryIdentifier;
-  }
-
-  virtual FixedSizeSmallShmemSectionAllocator* GetTileLockAllocator() { return nullptr; };
-
-protected:
-  TextureFactoryIdentifier mTextureFactoryIdentifier;
-};
-
-} // namespace layers
-} // namespace mozilla
-
-#endif
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -173,17 +173,16 @@ EXPORTS.mozilla.layers += [
     'ipc/RemoteContentController.h',
     'ipc/ShadowLayerChild.h',
     'ipc/ShadowLayers.h',
     'ipc/ShadowLayersManager.h',
     'ipc/SharedBufferManagerChild.h',
     'ipc/SharedBufferManagerParent.h',
     'ipc/SharedPlanarYCbCrImage.h',
     'ipc/SharedRGBImage.h',
-    'ipc/TextureForwarder.h',
     'LayerMetricsWrapper.h',
     'LayersTypes.h',
     'opengl/CompositingRenderTargetOGL.h',
     'opengl/CompositorOGL.h',
     'opengl/GrallocTextureClient.h',
     'opengl/GrallocTextureHost.h',
     'opengl/MacIOSurfaceTextureClientOGL.h',
     'opengl/MacIOSurfaceTextureHostOGL.h',