Backed out 17 changesets (bug 897452) for OSX crashes on a CLOSED TREE.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 11 Dec 2013 14:52:50 -0500
changeset 160315 ff1bf2049ecf9b76e9d82c7bf9d408fd3954ac1f
parent 160314 b7db9113622eae53b9218b9353179621c0b81d3b
child 160316 926aeca75e6c493a2fc55232e9dc62bcab6ff01c
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
bugs897452
milestone29.0a1
backs out11ad8608bc275d18f3538a18f4c64d626a86767f
6bcc629e76f90eccedfc5488e3660775fb49540d
b91c858a43f50c5d72806d781620421377107239
38ba49ee3e97803301250ed4c499472f5767eb76
ea184ef847625f7ca45aed5c19f53a7f5749be86
686cc512214973f72f5e7658b0af0d48294552b7
3685a8018e49749a0741fde57a307ebb2aa9b624
be7ef62400680dc2d88d38853d0090b8581a1224
f95c20e70947326609728306e72d470e8a5f4fdf
4a370d2a1c62e1b584785fa7bbaf162bfbf7349f
1222f6ab66d214bd0403b02ee1513c471940b7f0
5e9d3c681ee96cdf52a37c80d11eeee21bf05f03
3b9ddce12b7a96ccfbbb11b38ab1ed79638c0478
7aec6387f3e96adf7207e48e6ff41d6e5cc8302d
eb1fe464fdafca11118d775096a3eb293e562020
07deaa53b6fd2b66e4cf300dfcd8df9bbe80030e
ddab7d071d6934009375dff8ac568b1fea4cc5ec
Backed out 17 changesets (bug 897452) for OSX crashes on a CLOSED TREE. Backed out changeset 11ad8608bc27 (bug 897452) Backed out changeset 6bcc629e76f9 (bug 897452) Backed out changeset b91c858a43f5 (bug 897452) Backed out changeset 38ba49ee3e97 (bug 897452) Backed out changeset ea184ef84762 (bug 897452) Backed out changeset 686cc5122149 (bug 897452) Backed out changeset 3685a8018e49 (bug 897452) Backed out changeset be7ef6240068 (bug 897452) Backed out changeset f95c20e70947 (bug 897452) Backed out changeset 4a370d2a1c62 (bug 897452) Backed out changeset 1222f6ab66d2 (bug 897452) Backed out changeset 5e9d3c681ee9 (bug 897452) Backed out changeset 3b9ddce12b7a (bug 897452) Backed out changeset 7aec6387f3e9 (bug 897452) Backed out changeset eb1fe464fdaf (bug 897452) Backed out changeset 07deaa53b6fd (bug 897452) Backed out changeset ddab7d071d69 (bug 897452)
gfx/layers/AtomicRefCountedWithFinalize.h
gfx/layers/ImageContainer.cpp
gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
gfx/layers/basic/MacIOSurfaceTextureHostBasic.h
gfx/layers/basic/TextureHostBasic.cpp
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CanvasClient.h
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/CompositableClient.cpp
gfx/layers/client/CompositableClient.h
gfx/layers/client/ContentClient.cpp
gfx/layers/client/ContentClient.h
gfx/layers/client/ImageClient.cpp
gfx/layers/client/ImageClient.h
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/client/TiledContentClient.h
gfx/layers/composite/CompositableHost.cpp
gfx/layers/composite/CompositableHost.h
gfx/layers/composite/ContentHost.cpp
gfx/layers/composite/ContentHost.h
gfx/layers/composite/ImageHost.cpp
gfx/layers/composite/ImageHost.h
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/composite/TiledContentHost.h
gfx/layers/ipc/CompositableForwarder.h
gfx/layers/ipc/CompositableTransactionParent.cpp
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeChild.h
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
gfx/layers/ipc/LayerTransactionChild.cpp
gfx/layers/ipc/LayerTransactionChild.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/ipc/LayersMessages.ipdlh
gfx/layers/ipc/PImageBridge.ipdl
gfx/layers/ipc/PLayerTransaction.ipdl
gfx/layers/ipc/PTexture.ipdl
gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
gfx/layers/ipc/ShadowLayerUtilsGralloc.h
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/moz.build
gfx/layers/opengl/GrallocTextureHost.cpp
gfx/layers/opengl/GrallocTextureHost.h
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
gfx/layers/opengl/TextureHostOGL.cpp
gfx/layers/opengl/TextureHostOGL.h
gfx/tests/gtest/TestTextures.cpp
deleted file mode 100644
--- a/gfx/layers/AtomicRefCountedWithFinalize.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef MOZILLA_ATOMICREFCOUNTEDWITHFINALIZE_H_
-#define MOZILLA_ATOMICREFCOUNTEDWITHFINALIZE_H_
-
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-
-template<typename T>
-class AtomicRefCountedWithFinalize
-{
-  protected:
-    AtomicRefCountedWithFinalize()
-      : mRefCount(0)
-    {}
-
-    ~AtomicRefCountedWithFinalize() {}
-
-  public:
-    void AddRef() {
-      MOZ_ASSERT(mRefCount >= 0);
-      ++mRefCount;
-    }
-
-    void Release() {
-      MOZ_ASSERT(mRefCount > 0);
-      if (0 == --mRefCount) {
-#ifdef DEBUG
-        mRefCount = detail::DEAD;
-#endif
-        static_cast<T*>(this)->Finalize();
-        delete this;
-      }
-    }
-
-private:
-    Atomic<int> mRefCount;
-};
-
-}
-
-#endif
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -212,17 +212,16 @@ ImageContainer::SetCurrentImage(Image *a
  void
 ImageContainer::ClearAllImages()
 {
   if (IsAsync()) {
     // Let ImageClient release all TextureClients.
     ImageBridgeChild::FlushAllImages(mImageClient, this, false);
     return;
   }
-
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   SetCurrentImageInternal(nullptr);
 }
 
 void
 ImageContainer::ClearAllImagesExceptFront()
 {
   if (IsAsync()) {
--- a/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
+++ b/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
@@ -30,20 +30,21 @@ MacIOSurfaceTextureSourceBasic::GetSize(
 
 gfx::SurfaceFormat
 MacIOSurfaceTextureSourceBasic::GetFormat() const
 {
   return mSurface->HasAlpha() ? gfx::FORMAT_R8G8B8A8 : gfx::FORMAT_B8G8R8X8;
 }
 
 MacIOSurfaceTextureHostBasic::MacIOSurfaceTextureHostBasic(
+    uint64_t aID,
     TextureFlags aFlags,
     const SurfaceDescriptorMacIOSurface& aDescriptor
 )
-  : TextureHost(aFlags)
+  : TextureHost(aID, aFlags)
 {
   mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
                                          aDescriptor.scaleFactor(),
                                          aDescriptor.hasAlpha());
 }
 
 gfx::SourceSurface*
 MacIOSurfaceTextureSourceBasic::GetSurface()
--- a/gfx/layers/basic/MacIOSurfaceTextureHostBasic.h
+++ b/gfx/layers/basic/MacIOSurfaceTextureHostBasic.h
@@ -51,18 +51,19 @@ protected:
 /**
  * A TextureHost for shared MacIOSurface
  *
  * Most of the logic actually happens in MacIOSurfaceTextureSourceBasic.
  */
 class MacIOSurfaceTextureHostBasic : public TextureHost
 {
 public:
-  MacIOSurfaceTextureHostBasic(TextureFlags aFlags,
-                               const SurfaceDescriptorMacIOSurface& aDescriptor);
+  MacIOSurfaceTextureHostBasic(uint64_t aID,
+                             TextureFlags aFlags,
+                             const SurfaceDescriptorMacIOSurface& aDescriptor);
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
   virtual bool Lock() MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
 
   virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE
--- a/gfx/layers/basic/TextureHostBasic.cpp
+++ b/gfx/layers/basic/TextureHostBasic.cpp
@@ -8,32 +8,33 @@
 
 using namespace mozilla::gl;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 TemporaryRef<TextureHost>
-CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
+CreateTextureHostBasic(uint64_t aID,
+                       const SurfaceDescriptor& aDesc,
                        ISurfaceAllocator* aDeallocator,
                        TextureFlags aFlags)
 {
   RefPtr<TextureHost> result;
   switch (aDesc.type()) {
 #ifdef XP_MACOSX
     case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
       const SurfaceDescriptorMacIOSurface& desc =
         aDesc.get_SurfaceDescriptorMacIOSurface();
-      result = new MacIOSurfaceTextureHostBasic(aFlags, desc);
+      result = new MacIOSurfaceTextureHostBasic(aID, aFlags, desc);
       break;
     }
 #endif
     default: {
-      result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
+      result = CreateBackendIndependentTextureHost(aID, aDesc, aDeallocator, aFlags);
       break;
     }
   }
 
   return result;
 }
 
 } // namespace layers
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -53,17 +53,17 @@ CanvasClient::CreateCanvasClient(CanvasC
   return new CanvasClient2D(aForwarder, aFlags);
 }
 
 void
 CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
 {
   if (mBuffer &&
       (mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) {
-    mBuffer->ForceRemove();
+    RemoveTextureClient(mBuffer);
     mBuffer = nullptr;
   }
 
   bool bufferCreated = false;
   if (!mBuffer) {
     bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE);
     gfxContentType contentType = isOpaque
                                                 ? GFX_CONTENT_COLOR
@@ -102,16 +102,24 @@ CanvasClient2D::Update(gfx::IntSize aSiz
 TemporaryRef<BufferTextureClient>
 CanvasClient2D::CreateBufferTextureClient(gfx::SurfaceFormat aFormat, TextureFlags aFlags)
 {
   return CompositableClient::CreateBufferTextureClient(aFormat,
                                                        mTextureInfo.mTextureFlags | aFlags);
 }
 
 void
+CanvasClient2D::OnActorDestroy()
+{
+  if (mBuffer) {
+    mBuffer->OnActorDestroy();
+  }
+}
+
+void
 DeprecatedCanvasClient2D::Updated()
 {
   mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->LockSurfaceDescriptor());
 }
 
 
 DeprecatedCanvasClient2D::DeprecatedCanvasClient2D(CompositableForwarder* aFwd,
                                                    TextureFlags aFlags)
@@ -153,16 +161,24 @@ DeprecatedCanvasClient2D::Update(gfx::In
   }
 
   gfxASurface* surface = mDeprecatedTextureClient->LockSurface();
   aLayer->UpdateSurface(surface);
   mDeprecatedTextureClient->Unlock();
 }
 
 void
+DeprecatedCanvasClient2D::OnActorDestroy()
+{
+  if (mDeprecatedTextureClient) {
+    mDeprecatedTextureClient->OnActorDestroy();
+  }
+}
+
+void
 DeprecatedCanvasClientSurfaceStream::Updated()
 {
   mForwarder->UpdateTextureNoSwap(this, 1, mDeprecatedTextureClient->LockSurfaceDescriptor());
 }
 
 
 DeprecatedCanvasClientSurfaceStream::DeprecatedCanvasClientSurfaceStream(CompositableForwarder* aFwd,
                                                                          TextureFlags aFlags)
@@ -220,10 +236,18 @@ DeprecatedCanvasClientSurfaceStream::Upd
     // Ref this so the SurfaceStream doesn't disappear unexpectedly. The
     // Compositor will need to unref it when finished.
     aLayer->mGLContext->AddRef();
   }
 
   aLayer->Painted();
 }
 
+void
+DeprecatedCanvasClientSurfaceStream::OnActorDestroy()
+{
+  if (mDeprecatedTextureClient) {
+    mDeprecatedTextureClient->OnActorDestroy();
+  }
+}
+
 }
 }
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -86,16 +86,18 @@ public:
   CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
                             TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT) MOZ_OVERRIDE;
 
   virtual void OnDetach() MOZ_OVERRIDE
   {
     mBuffer = nullptr;
   }
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 private:
   RefPtr<TextureClient> mBuffer;
 };
 
 class DeprecatedCanvasClient2D : public CanvasClient
 {
 public:
   DeprecatedCanvasClient2D(CompositableForwarder* aLayerForwarder,
@@ -110,16 +112,18 @@ public:
   virtual void Updated() MOZ_OVERRIDE;
 
   virtual void SetDescriptorFromReply(TextureIdentifier aTextureId,
                                       const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE
   {
     mDeprecatedTextureClient->SetDescriptorFromReply(aDescriptor);
   }
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 private:
   RefPtr<DeprecatedTextureClient> mDeprecatedTextureClient;
 };
 
 // Used for GL canvases where we don't need to do any readback, i.e., with a
 // GL backend.
 class DeprecatedCanvasClientSurfaceStream : public CanvasClient
 {
@@ -136,16 +140,18 @@ public:
   virtual void Updated() MOZ_OVERRIDE;
 
   virtual void SetDescriptorFromReply(TextureIdentifier aTextureId,
                                       const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE
   {
     mDeprecatedTextureClient->SetDescriptorFromReply(aDescriptor);
   }
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 private:
   RefPtr<DeprecatedTextureClient> mDeprecatedTextureClient;
 };
 
 }
 }
 
 #endif
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -363,16 +363,27 @@ ClientLayerManager::ForwardTransaction()
         CompositableChild* compositableChild =
           static_cast<CompositableChild*>(ots.compositableChild());
         MOZ_ASSERT(compositableChild);
 
         compositableChild->GetCompositableClient()
           ->SetDescriptorFromReply(ots.textureId(), ots.image());
         break;
       }
+      case EditReply::TReplyTextureRemoved: {
+        // XXX - to manage reuse of gralloc buffers, we'll need to add some
+        // glue code here to find the TextureClient and invoke a callback to
+        // let the camera know that the gralloc buffer is not used anymore on
+        // the compositor side and that it can reuse it.
+        const ReplyTextureRemoved& rep = reply.get_ReplyTextureRemoved();
+        CompositableClient* compositable
+          = static_cast<CompositableChild*>(rep.compositableChild())->GetCompositableClient();
+        compositable->OnReplyTextureRemoved(rep.textureId());
+        break;
+      }
 
       default:
         NS_RUNTIMEABORT("not reached");
       }
     }
 
     if (sent) {
       mNeedsComposite = false;
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -19,27 +19,45 @@
 #endif
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 CompositableClient::CompositableClient(CompositableForwarder* aForwarder)
-: mCompositableChild(nullptr)
+: mNextTextureID(1)
+, mCompositableChild(nullptr)
 , mForwarder(aForwarder)
 {
   MOZ_COUNT_CTOR(CompositableClient);
 }
 
 
 CompositableClient::~CompositableClient()
 {
   MOZ_COUNT_DTOR(CompositableClient);
   Destroy();
+
+  FlushTexturesToRemoveCallbacks();
+  MOZ_ASSERT(mTexturesToRemove.Length() == 0, "would leak textures pending for deletion");
+}
+
+void
+CompositableClient::FlushTexturesToRemoveCallbacks()
+{
+  std::map<uint64_t,TextureClientData*>::iterator it
+    = mTexturesToRemoveCallbacks.begin();
+  std::map<uint64_t,TextureClientData*>::iterator stop
+    = mTexturesToRemoveCallbacks.end();
+  for (; it != stop; ++it) {
+    it->second->DeallocateSharedData(GetForwarder());
+    delete it->second;
+  }
+  mTexturesToRemoveCallbacks.clear();
 }
 
 LayersBackend
 CompositableClient::GetCompositorBackendType() const
 {
   return mForwarder->GetCompositorBackendType();
 }
 
@@ -228,21 +246,75 @@ CompositableClient::CreateTextureClientF
     result = CreateBufferTextureClient(aFormat, aTextureFlags);
   }
 
   MOZ_ASSERT(!result || result->AsTextureClientDrawTarget(),
              "Not a TextureClientDrawTarget?");
   return result;
 }
 
+uint64_t
+CompositableClient::NextTextureID()
+{
+  ++mNextTextureID;
+  // 0 is always an invalid ID
+  if (mNextTextureID == 0) {
+    ++mNextTextureID;
+  }
+
+  return mNextTextureID;
+}
+
 bool
 CompositableClient::AddTextureClient(TextureClient* aClient)
 {
-  return aClient->InitIPDLActor(mForwarder);
+  aClient->SetID(NextTextureID());
+  return mForwarder->AddTexture(this, aClient);
+}
+
+void
+CompositableClient::RemoveTextureClient(TextureClient* aClient)
+{
+  MOZ_ASSERT(aClient);
+  mTexturesToRemove.AppendElement(TextureIDAndFlags(aClient->GetID(),
+                                                    aClient->GetFlags()));
+  if (aClient->GetFlags() & TEXTURE_DEALLOCATE_CLIENT) {
+    TextureClientData* data = aClient->DropTextureData();
+    if (data) {
+      mTexturesToRemoveCallbacks[aClient->GetID()] = data;
+    }
+  }
+  aClient->ClearID();
+  aClient->MarkInvalid();
+}
+
+void
+CompositableClient::OnReplyTextureRemoved(uint64_t aTextureID)
+{
+  std::map<uint64_t,TextureClientData*>::iterator it
+    = mTexturesToRemoveCallbacks.find(aTextureID);
+  if (it != mTexturesToRemoveCallbacks.end()) {
+    it->second->DeallocateSharedData(GetForwarder());
+    delete it->second;
+    mTexturesToRemoveCallbacks.erase(it);
+  }
 }
 
 void
 CompositableClient::OnTransaction()
 {
+  for (unsigned i = 0; i < mTexturesToRemove.Length(); ++i) {
+    const TextureIDAndFlags& texture = mTexturesToRemove[i];
+    mForwarder->RemoveTexture(this, texture.mID, texture.mFlags);
+  }
+  mTexturesToRemove.Clear();
 }
 
+
+void
+CompositableChild::ActorDestroy(ActorDestroyReason why)
+{
+  if (mCompositableClient && why == AbnormalShutdown) {
+    mCompositableClient->OnActorDestroy();
+  }
+}
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -128,30 +128,72 @@ public:
   uint64_t GetAsyncID() const;
 
   /**
    * Tells the Compositor to create a TextureHost for this TextureClient.
    */
   virtual bool AddTextureClient(TextureClient* aClient);
 
   /**
+   * Tells the Compositor to delete the TextureHost corresponding to this
+   * TextureClient.
+   */
+  virtual void RemoveTextureClient(TextureClient* aClient);
+
+  /**
    * A hook for the Compositable to execute whatever it held off for next transaction.
    */
   virtual void OnTransaction();
 
   /**
    * A hook for the when the Compositable is detached from it's layer.
    */
   virtual void OnDetach() {}
 
+  /**
+   * When texture deallocation must happen on the client side, we need to first
+   * ensure that the compositor has already let go of the data in order
+   * to safely deallocate it.
+   *
+   * This is implemented by registering a callback to postpone deallocation or
+   * recycling of the shared data.
+   *
+   * This hook is called when the compositor notifies the client that it is not
+   * holding any more references to the shared data so that this compositable
+   * can run the corresponding callback.
+   */
+  void OnReplyTextureRemoved(uint64_t aTextureID);
+
+  /**
+   * Run all he registered callbacks (see the comment for OnReplyTextureRemoved).
+   * Only call this if you know what you are doing.
+   */
+  void FlushTexturesToRemoveCallbacks();
+
+  /**
+   * Our IPDL actor is being destroyed, get rid of any shmem resources now.
+   */
+  virtual void OnActorDestroy() = 0;
+
 protected:
+  // return the next texture ID
+  uint64_t NextTextureID();
+
+  struct TextureIDAndFlags {
+    TextureIDAndFlags(uint64_t aID, TextureFlags aFlags)
+    : mID(aID), mFlags(aFlags) {}
+    uint64_t mID;
+    TextureFlags mFlags;
+  };
+  // The textures to destroy in the next transaction;
+  nsTArray<TextureIDAndFlags> mTexturesToRemove;
+  std::map<uint64_t, TextureClientData*> mTexturesToRemoveCallbacks;
+  uint64_t mNextTextureID;
   CompositableChild* mCompositableChild;
   CompositableForwarder* mForwarder;
-
-  friend class CompositableChild;
 };
 
 /**
  * IPDL actor used by CompositableClient to match with its corresponding
  * CompositableHost on the compositor side.
  *
  * CompositableChild is owned by a CompositableClient.
  */
@@ -175,21 +217,17 @@ public:
     mCompositableClient = aClient;
   }
 
   CompositableClient* GetCompositableClient() const
   {
     return mCompositableClient;
   }
 
-  virtual void ActorDestroy(ActorDestroyReason) MOZ_OVERRIDE {
-    if (mCompositableClient) {
-      mCompositableClient->mCompositableChild = nullptr;
-    }
-  }
+  virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
   void SetAsyncID(uint64_t aID) { mID = aID; }
   uint64_t GetAsyncID() const
   {
     return mID;
   }
 private:
   CompositableClient* mCompositableClient;
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -143,16 +143,19 @@ ContentClientRemoteBuffer::BeginPaint()
 
 void
 ContentClientRemoteBuffer::EndPaint()
 {
   // XXX: We might still not have a texture client if PaintThebes
   // decided we didn't need one yet because the region to draw was empty.
   SetBufferProvider(nullptr);
   SetBufferProviderOnWhite(nullptr);
+  for (size_t i = 0; i < mOldTextures.Length(); ++i) {
+    RemoveTextureClient(mOldTextures[i]);
+  }
   mOldTextures.Clear();
 
   if (mTextureClient) {
     mTextureClient->Unlock();
   }
   if (mTextureClientOnWhite) {
     mTextureClientOnWhite->Unlock();
   }
@@ -291,16 +294,30 @@ ContentClientRemoteBuffer::Updated(const
 void
 ContentClientRemoteBuffer::SwapBuffers(const nsIntRegion& aFrontUpdatedRegion)
 {
   MOZ_ASSERT(mTextureClient);
   mFrontAndBackBufferDiffer = true;
 }
 
 void
+ContentClientRemoteBuffer::OnActorDestroy()
+{
+  if (mTextureClient) {
+    mTextureClient->OnActorDestroy();
+  }
+  if (mTextureClientOnWhite) {
+    mTextureClientOnWhite->OnActorDestroy();
+  }
+  for (size_t i = 0; i < mOldTextures.Length(); ++i) {
+    mOldTextures[i]->OnActorDestroy();
+  }
+}
+
+void
 DeprecatedContentClientRemoteBuffer::DestroyBuffers()
 {
   if (!mDeprecatedTextureClient) {
     return;
   }
 
   mDeprecatedTextureClient = nullptr;
   mDeprecatedTextureClientOnWhite = nullptr;
@@ -475,16 +492,31 @@ DeprecatedContentClientRemoteBuffer::Swa
 
   mFrontAndBackBufferDiffer = true;
   mDeprecatedTextureClient->SetAccessMode(DeprecatedTextureClient::ACCESS_READ_WRITE);
   if (mDeprecatedTextureClientOnWhite) {
     mDeprecatedTextureClientOnWhite->SetAccessMode(DeprecatedTextureClient::ACCESS_READ_WRITE);
   }
 }
 
+
+void
+DeprecatedContentClientRemoteBuffer::OnActorDestroy()
+{
+  if (mDeprecatedTextureClient) {
+    mDeprecatedTextureClient->OnActorDestroy();
+  }
+  if (mDeprecatedTextureClientOnWhite) {
+    mDeprecatedTextureClientOnWhite->OnActorDestroy();
+  }
+  for (size_t i = 0; i < mOldTextures.Length(); ++i) {
+    mOldTextures[i]->OnActorDestroy();
+  }
+}
+ 
 void
 ContentClientDoubleBuffered::CreateFrontBuffer(const nsIntRect& aBufferRect)
 {
   if (!CreateAndAllocateTextureClient(mFrontClient, TEXTURE_ON_BLACK) ||
       !AddTextureClient(mFrontClient)) {
     AbortTextureClientCreation();
     return;
   }
@@ -629,16 +661,36 @@ ContentClientDoubleBuffered::UpdateDesti
     if (isClippingCheap) {
       gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
     }
 
     aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
   }
 }
 
+void
+ContentClientDoubleBuffered::OnActorDestroy()
+{
+  if (mTextureClient) {
+    mTextureClient->OnActorDestroy();
+  }
+  if (mTextureClientOnWhite) {
+    mTextureClientOnWhite->OnActorDestroy();
+  }
+  for (size_t i = 0; i < mOldTextures.Length(); ++i) {
+    mOldTextures[i]->OnActorDestroy();
+  }
+  if (mFrontClient) {
+    mFrontClient->OnActorDestroy();
+  }
+  if (mFrontClientOnWhite) {
+    mFrontClientOnWhite->OnActorDestroy();
+  }
+}
+
 DeprecatedContentClientDoubleBuffered::~DeprecatedContentClientDoubleBuffered()
 {
   if (mDeprecatedTextureClient) {
     MOZ_ASSERT(mFrontClient);
     mDeprecatedTextureClient->SetDescriptor(SurfaceDescriptor());
     mFrontClient->SetDescriptor(SurfaceDescriptor());
   }
   if (mDeprecatedTextureClientOnWhite) {
@@ -729,16 +781,36 @@ DeprecatedContentClientDoubleBuffered::S
   mFrontClient->SetAccessMode(DeprecatedTextureClient::ACCESS_READ_ONLY);
   if (mFrontClientOnWhite) {
     mFrontClientOnWhite->SetAccessMode(DeprecatedTextureClient::ACCESS_READ_ONLY);
   }
 
   DeprecatedContentClientRemoteBuffer::SwapBuffers(aFrontUpdatedRegion);
 }
 
+void
+DeprecatedContentClientDoubleBuffered::OnActorDestroy()
+{
+  if (mDeprecatedTextureClient) {
+    mDeprecatedTextureClient->OnActorDestroy();
+  }
+  if (mDeprecatedTextureClientOnWhite) {
+    mDeprecatedTextureClientOnWhite->OnActorDestroy();
+  }
+  for (size_t i = 0; i < mOldTextures.Length(); ++i) {
+    mOldTextures[i]->OnActorDestroy();
+  }
+  if (mFrontClient) {
+    mFrontClient->OnActorDestroy();
+  }
+  if (mFrontClientOnWhite) {
+    mFrontClientOnWhite->OnActorDestroy();
+  }
+}
+
 struct AutoDeprecatedTextureClient {
   AutoDeprecatedTextureClient()
     : mTexture(nullptr)
   {}
   ~AutoDeprecatedTextureClient()
   {
     if (mTexture) {
       mTexture->Unlock();
--- a/gfx/layers/client/ContentClient.h
+++ b/gfx/layers/client/ContentClient.h
@@ -154,16 +154,18 @@ public:
 
   virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     MOZ_CRASH("Should not be called on non-remote ContentClient");
   }
+
+  virtual void OnActorDestroy() MOZ_OVERRIDE {}
 };
 
 /**
  * A ContentClientRemote backed by a RotatedContentBuffer.
  *
  * When using a ContentClientRemote, SurfaceDescriptors are created on
  * the rendering side and destroyed on the compositing side. They are only
  * passed from one side to the other when the TextureClient/Hosts are created.
@@ -231,16 +233,18 @@ public:
   virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     return mTextureInfo;
   }
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 protected:
   void DestroyBuffers();
 
   virtual nsIntRegion GetUpdatedRegion(const nsIntRegion& aRegionToDraw,
                                        const nsIntRegion& aVisibleRegion,
                                        bool aDidSelfCopy);
 
   void BuildTextureClients(gfx::SurfaceFormat aFormat,
@@ -331,16 +335,18 @@ public:
   virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     return mTextureInfo;
   }
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 protected:
   void DestroyBuffers();
 
   virtual nsIntRegion GetUpdatedRegion(const nsIntRegion& aRegionToDraw,
                                        const nsIntRegion& aVisibleRegion,
                                        bool aDidSelfCopy);
 
   // create and configure mDeprecatedTextureClient
@@ -391,16 +397,18 @@ public:
     mTextureInfo.mCompositableType = COMPOSITABLE_CONTENT_DOUBLE;
   }
   virtual ~ContentClientDoubleBuffered() {}
 
   virtual void SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) MOZ_OVERRIDE;
 
   virtual void SyncFrontBufferToBackBuffer() MOZ_OVERRIDE;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 protected:
   virtual void CreateFrontBuffer(const nsIntRect& aBufferRect) MOZ_OVERRIDE;
   virtual void DestroyFrontBuffer() MOZ_OVERRIDE;
 
 private:
   void UpdateDestinationFrom(const RotatedBuffer& aSource,
                              const nsIntRegion& aUpdateRegion);
 
@@ -428,16 +436,18 @@ public:
     mTextureInfo.mCompositableType = BUFFER_CONTENT_DIRECT;
   }
   ~DeprecatedContentClientDoubleBuffered();
 
   virtual void SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) MOZ_OVERRIDE;
 
   virtual void SyncFrontBufferToBackBuffer() MOZ_OVERRIDE;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 protected:
   virtual void CreateFrontBufferAndNotify(const nsIntRect& aBufferRect) MOZ_OVERRIDE;
   virtual void DestroyFrontBuffer() MOZ_OVERRIDE;
   virtual void LockFrontBuffer() MOZ_OVERRIDE;
 
 private:
   void UpdateDestinationFrom(const RotatedBuffer& aSource,
                              const nsIntRegion& aUpdateRegion);
@@ -534,16 +544,18 @@ public:
     if (IsSurfaceDescriptorValid(mUpdateDescriptor)) {
       mForwarder->DestroySharedSurface(&mUpdateDescriptor);
     }
     if (IsSurfaceDescriptorValid(mUpdateDescriptorOnWhite)) {
       mForwarder->DestroySharedSurface(&mUpdateDescriptorOnWhite);
     }
   }
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE {}
+
 private:
 
   enum BufferType{
     BUFFER_BLACK,
     BUFFER_WHITE
   };
 
   void NotifyBufferCreated(ContentType aType, uint32_t aFlags)
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -96,30 +96,30 @@ TextureInfo ImageClientSingle::GetTextur
 {
   return TextureInfo(COMPOSITABLE_IMAGE);
 }
 
 void
 ImageClientSingle::FlushAllImages(bool aExceptFront)
 {
   if (!aExceptFront && mFrontBuffer) {
-    mFrontBuffer->ForceRemove();
+    RemoveTextureClient(mFrontBuffer);
     mFrontBuffer = nullptr;
   }
 }
 
 void
 ImageClientBuffered::FlushAllImages(bool aExceptFront)
 {
   if (!aExceptFront && mFrontBuffer) {
-    mFrontBuffer->ForceRemove();
+    RemoveTextureClient(mFrontBuffer);
     mFrontBuffer = nullptr;
   }
   if (mBackBuffer) {
-    mBackBuffer->ForceRemove();
+    RemoveTextureClient(mBackBuffer);
     mBackBuffer = nullptr;
   }
 }
 
 bool
 ImageClientSingle::UpdateImage(ImageContainer* aContainer,
                                uint32_t aContentFlags)
 {
@@ -140,34 +140,34 @@ ImageClientSingle::UpdateImage(ImageCont
 
     if (texture->IsSharedWithCompositor()) {
       // XXX - temporary fix for bug 911941
       // This will be changed with bug 912907
       return false;
     }
 
     if (mFrontBuffer) {
-      mFrontBuffer->ForceRemove();
+      RemoveTextureClient(mFrontBuffer);
     }
     mFrontBuffer = texture;
     if (!AddTextureClient(texture)) {
       mFrontBuffer = nullptr;
       return false;
     }
     GetForwarder()->UpdatedTexture(this, texture, nullptr);
     GetForwarder()->UseTexture(this, texture);
   } else if (image->GetFormat() == PLANAR_YCBCR) {
     PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image);
     const PlanarYCbCrData* data = ycbcr->GetData();
     if (!data) {
       return false;
     }
 
     if (mFrontBuffer && mFrontBuffer->IsImmutable()) {
-      mFrontBuffer->ForceRemove();
+      RemoveTextureClient(mFrontBuffer);
       mFrontBuffer = nullptr;
     }
 
     bool bufferCreated = false;
     if (!mFrontBuffer) {
       mFrontBuffer = CreateBufferTextureClient(gfx::FORMAT_YUV, TEXTURE_FLAGS_DEFAULT);
       gfx::IntSize ySize(data->mYSize.width, data->mYSize.height);
       gfx::IntSize cbCrSize(data->mCbCrSize.width, data->mCbCrSize.height);
@@ -200,17 +200,17 @@ ImageClientSingle::UpdateImage(ImageCont
     }
 
   } else if (image->GetFormat() == SHARED_TEXTURE) {
     SharedTextureImage* sharedImage = static_cast<SharedTextureImage*>(image);
     const SharedTextureImage::Data *data = sharedImage->GetData();
     gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
 
     if (mFrontBuffer) {
-      mFrontBuffer->ForceRemove();
+      RemoveTextureClient(mFrontBuffer);
       mFrontBuffer = nullptr;
     }
 
     RefPtr<SharedTextureClientOGL> buffer = new SharedTextureClientOGL(mTextureFlags);
     buffer->InitWith(data->mHandle, size, data->mShareType, data->mInverted);
     mFrontBuffer = buffer;
     if (!AddTextureClient(mFrontBuffer)) {
       mFrontBuffer = nullptr;
@@ -221,17 +221,17 @@ ImageClientSingle::UpdateImage(ImageCont
   } else {
     nsRefPtr<gfxASurface> surface = image->GetAsSurface();
     MOZ_ASSERT(surface);
 
     gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
 
     if (mFrontBuffer &&
         (mFrontBuffer->IsImmutable() || mFrontBuffer->GetSize() != size)) {
-      mFrontBuffer->ForceRemove();
+      RemoveTextureClient(mFrontBuffer);
       mFrontBuffer = nullptr;
     }
 
     bool bufferCreated = false;
     if (!mFrontBuffer) {
       gfxImageFormat format
         = gfxPlatform::GetPlatform()->OptimalFormatForContent(surface->GetContentType());
       mFrontBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format),
@@ -275,16 +275,35 @@ ImageClientBuffered::UpdateImage(ImageCo
                                  uint32_t aContentFlags)
 {
   RefPtr<TextureClient> temp = mFrontBuffer;
   mFrontBuffer = mBackBuffer;
   mBackBuffer = temp;
   return ImageClientSingle::UpdateImage(aContainer, aContentFlags);
 }
 
+void
+ImageClientSingle::OnActorDestroy()
+{
+  if (mFrontBuffer) {
+    mFrontBuffer->OnActorDestroy();
+  }
+}
+
+void
+ImageClientBuffered::OnActorDestroy()
+{
+  if (mFrontBuffer) {
+    mFrontBuffer->OnActorDestroy();
+  }
+  if (mBackBuffer) {
+    mBackBuffer->OnActorDestroy();
+  }
+}
+
 bool
 ImageClientSingle::AddTextureClient(TextureClient* aTexture)
 {
   MOZ_ASSERT((mTextureFlags & aTexture->GetFlags()) == mTextureFlags);
   return CompositableClient::AddTextureClient(aTexture);
 }
 
 TemporaryRef<BufferTextureClient>
@@ -460,16 +479,24 @@ DeprecatedImageClientSingle::Updated()
 ImageClientBridge::ImageClientBridge(CompositableForwarder* aFwd,
                                      TextureFlags aFlags)
 : ImageClient(aFwd, BUFFER_BRIDGE)
 , mAsyncContainerID(0)
 , mLayer(nullptr)
 {
 }
 
+void
+DeprecatedImageClientSingle::OnActorDestroy()
+{
+  if (mDeprecatedTextureClient) {
+    mDeprecatedTextureClient->OnActorDestroy();
+  }
+}
+
 bool
 ImageClientBridge::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags)
 {
   if (!GetForwarder() || !mLayer) {
     return false;
   }
   if (mAsyncContainerID == aContainer->GetAsyncContainerID()) {
     return true;
--- a/gfx/layers/client/ImageClient.h
+++ b/gfx/layers/client/ImageClient.h
@@ -97,16 +97,18 @@ public:
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE;
 
   virtual already_AddRefed<Image> CreateImage(const uint32_t *aFormats,
                                               uint32_t aNumFormats) MOZ_OVERRIDE;
 
   virtual void FlushAllImages(bool aExceptFront) MOZ_OVERRIDE;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 protected:
   RefPtr<TextureClient> mFrontBuffer;
   // Some layers may want to enforce some flags to all their textures
   // (like disallowing tiling)
   TextureFlags mTextureFlags;
 };
 
 /**
@@ -120,16 +122,18 @@ public:
                       CompositableType aType);
 
   virtual bool UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags);
 
   virtual void OnDetach() MOZ_OVERRIDE;
 
   virtual void FlushAllImages(bool aExceptFront) MOZ_OVERRIDE;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 protected:
   RefPtr<TextureClient> mBackBuffer;
 };
 
 /**
  * An image client which uses a single texture client, may be single or double
  * buffered. (As opposed to using two texture clients for buffering, as in
  * ContentClientDoubleBuffered, or using multiple clients for YCbCr or tiled
@@ -164,16 +168,18 @@ public:
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     return mTextureInfo;
   }
 
   virtual already_AddRefed<Image> CreateImage(const uint32_t *aFormats,
                                               uint32_t aNumFormats) MOZ_OVERRIDE;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 private:
   RefPtr<DeprecatedTextureClient> mDeprecatedTextureClient;
   TextureInfo mTextureInfo;
 };
 
 /**
  * Image class to be used for async image uploads using the image bridge
  * protocol.
@@ -205,16 +211,18 @@ public:
 
   virtual already_AddRefed<Image> CreateImage(const uint32_t *aFormats,
                                               uint32_t aNumFormats) MOZ_OVERRIDE
   {
     NS_WARNING("Should not create an image through an ImageClientBridge");
     return nullptr;
   }
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE {}
+
 protected:
   uint64_t mAsyncContainerID;
   ShadowableLayer* mLayer;
 };
 
 }
 }
 
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -14,17 +14,16 @@
 #include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/ISurfaceAllocator.h"
 #include "mozilla/layers/ImageDataSerializer.h"
 #include "mozilla/layers/ShadowLayers.h"  // for ShadowLayerForwarder
 #include "mozilla/layers/SharedPlanarYCbCrImage.h"
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
-#include "mozilla/layers/PTextureChild.h"
 #include "nsDebug.h"                    // for NS_ASSERTION, NS_WARNING, etc
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 #include "ImageContainer.h"             // for PlanarYCbCrImage, etc
 #include "mozilla/gfx/2D.h"
 
 #ifdef MOZ_ANDROID_OMTC
 #  include "gfxReusableImageSurfaceWrapper.h"
 #  include "gfxImageSurface.h"
@@ -34,136 +33,16 @@
 #endif
 
 using namespace mozilla::gl;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
-/**
- * TextureChild is the content-side incarnation of the PTexture IPDL actor.
- *
- * TextureChild is used to synchronize a texture client and its corresponding
- * TextureHost if needed (a TextureClient that is not shared with the compositor
- * does not have a TextureChild)
- *
- * During the deallocation phase, a TextureChild may hold its recently destroyed
- * TextureClient's data until the compositor side confirmed that it is safe to
- * deallocte or recycle the it.
- */
-class TextureChild : public PTextureChild
-{
-public:
-  TextureChild()
-  : mForwarder(nullptr)
-  , mTextureData(nullptr)
-  , mTextureClient(nullptr)
-  {
-    MOZ_COUNT_CTOR(TextureChild);
-  }
-
-  ~TextureChild()
-  {
-    MOZ_COUNT_DTOR(TextureChild);
-  }
-
-  bool Recv__delete__() MOZ_OVERRIDE;
-
-  /**
-   * Only used during the deallocation phase iff we need synchronization between
-   * the client and host side for deallocation (that is, when the data is going
-   * to be deallocated or recycled on the client side).
-   */
-  void SetTextureData(TextureClientData* aData)
-  {
-    mTextureData = aData;
-  }
-
-  void DeleteTextureData();
-
-  CompositableForwarder* GetForwarder() { return mForwarder; }
-
-  ISurfaceAllocator* GetAllocator() { return mForwarder; }
-
-  void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
-
-private:
-
-  CompositableForwarder* mForwarder;
-  TextureClientData* mTextureData;
-  TextureClient* mTextureClient;
-
-  friend class TextureClient;
-};
-
-void
-TextureChild::DeleteTextureData()
-{
-  if (mTextureData) {
-    mTextureData->DeallocateSharedData(GetAllocator());
-    delete mTextureData;
-    mTextureData = nullptr;
-  }
-}
-
-bool
-TextureChild::Recv__delete__()
-{
-  DeleteTextureData();
-  return true;
-}
-
-void
-TextureChild::ActorDestroy(ActorDestroyReason why)
-{
-  if (mTextureClient) {
-    mTextureClient->mActor = nullptr;
-  }
-}
-
-// static
-PTextureChild*
-TextureClient::CreateIPDLActor()
-{
-  return new TextureChild();
-}
-
-// static
-bool
-TextureClient::DestroyIPDLActor(PTextureChild* actor)
-{
-  delete actor;
-  return true;
-}
-
-bool
-TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
-{
-  MOZ_ASSERT(!mActor);
-  MOZ_ASSERT(aForwarder);
-
-  SurfaceDescriptor desc;
-  if (!ToSurfaceDescriptor(desc)) {
-    return false;
-  }
-
-  mActor = static_cast<TextureChild*>(aForwarder->CreateEmptyTextureChild());
-  mActor->mForwarder = aForwarder;
-  mActor->mTextureClient = this;
-  mShared = true;
-  return mActor->SendInit(desc, GetFlags());
-}
-
-PTextureChild*
-TextureClient::GetIPDLActor()
-{
-  return mActor;
-}
-
 class ShmemTextureClientData : public TextureClientData
 {
 public:
   ShmemTextureClientData(ipc::Shmem& aShmem)
   : mShmem(aShmem)
   {
     MOZ_COUNT_CTOR(ShmemTextureClientData);
   }
@@ -196,17 +75,16 @@ public:
   {
     MOZ_ASSERT(!mBuffer, "Forgot to deallocate the shared texture data?");
     MOZ_COUNT_CTOR(MemoryTextureClientData);
   }
 
   virtual void DeallocateSharedData(ISurfaceAllocator*)
   {
     delete[] mBuffer;
-    mBuffer = nullptr;
   }
 
 private:
   uint8_t* mBuffer;
 };
 
 TextureClientData*
 MemoryTextureClient::DropTextureData()
@@ -228,53 +106,24 @@ ShmemTextureClient::DropTextureData()
   }
   TextureClientData* result = new ShmemTextureClientData(mShmem);
   MarkInvalid();
   mShmem = ipc::Shmem();
   return result;
 }
 
 TextureClient::TextureClient(TextureFlags aFlags)
-  : mActor(nullptr)
+  : mID(0)
   , mFlags(aFlags)
   , mShared(false)
   , mValid(true)
 {}
 
 TextureClient::~TextureClient()
-{
-  // All the destruction code that may lead to virtual method calls must
-  // be in Finalize() which is called just before the destructor.
-}
-
-void TextureClient::ForceRemove()
-{
-  if (mValid && mActor) {
-    if (GetFlags() & TEXTURE_DEALLOCATE_CLIENT) {
-      mActor->SetTextureData(DropTextureData());
-      mActor->SendRemoveTextureSync();
-      mActor->DeleteTextureData();
-    } else {
-      mActor->SendRemoveTexture();
-    }
-  }
-  MarkInvalid();
-}
-
-void
-TextureClient::Finalize()
-{
-  if (mActor) {
-    // this will call ForceRemove in the right thread, using a sync proxy if needed
-    mActor->GetForwarder()->RemoveTexture(this);
-
-    // mActor has a raw pointer to us, mActor->mTextureClient. Null it before we die.
-    mActor->mTextureClient = nullptr;
-  }
-}
+{}
 
 bool
 TextureClient::ShouldDeallocateInDestructor() const
 {
   if (!IsAllocated()) {
     return false;
   }
 
@@ -383,18 +232,18 @@ MemoryTextureClient::MemoryTextureClient
   , mBufSize(0)
 {
   MOZ_COUNT_CTOR(MemoryTextureClient);
 }
 
 MemoryTextureClient::~MemoryTextureClient()
 {
   MOZ_COUNT_DTOR(MemoryTextureClient);
-  if (mBuffer && ShouldDeallocateInDestructor()) {
-    // if the buffer has never been shared we must deallocate it or it would
+  if (ShouldDeallocateInDestructor() && mBuffer) {
+    // if the buffer has never been shared we must deallocate it or ir would
     // leak.
     GfxMemoryImageReporter::WillFree(mBuffer);
     delete mBuffer;
   }
 }
 
 BufferTextureClient::BufferTextureClient(CompositableClient* aCompositable,
                                          gfx::SurfaceFormat aFormat,
@@ -559,16 +408,25 @@ DeprecatedTextureClient::DeprecatedTextu
 }
 
 DeprecatedTextureClient::~DeprecatedTextureClient()
 {
   MOZ_COUNT_DTOR(DeprecatedTextureClient);
   MOZ_ASSERT(mDescriptor.type() == SurfaceDescriptor::T__None, "Need to release surface!");
 }
 
+void
+DeprecatedTextureClient::OnActorDestroy()
+{
+  if (ISurfaceAllocator::IsShmem(&mDescriptor)) {
+    mDescriptor = SurfaceDescriptor();
+  }
+}
+
+
 DeprecatedTextureClientShmem::DeprecatedTextureClientShmem(CompositableForwarder* aForwarder,
                                        const TextureInfo& aTextureInfo)
   : DeprecatedTextureClient(aForwarder, aTextureInfo)
 {
 }
 
 DeprecatedTextureClientShmem::~DeprecatedTextureClientShmem()
 {
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -19,34 +19,31 @@
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat
 #include "mozilla/ipc/Shmem.h"          // for Shmem
 #include "mozilla/layers/CompositorTypes.h"  // for TextureFlags, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsISupportsImpl.h"            // for TextureImage::AddRef, etc
-#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
 
 class gfxReusableSurfaceWrapper;
 class gfxASurface;
 class gfxImageSurface;
 
 namespace mozilla {
 namespace layers {
 
 class ContentClient;
 class CompositableForwarder;
 class ISurfaceAllocator;
 class CompositableClient;
 class PlanarYCbCrImage;
 class PlanarYCbCrData;
 class Image;
-class PTextureChild;
-class TextureChild;
 
 /**
  * TextureClient is the abstraction that allows us to share data between the
  * content and the compositor side.
  * TextureClient can also provide with some more "producer" facing APIs
  * such as TextureClientSurface and TextureClientYCbCr, that can be queried
  * using AsTextureCLientSurface(), etc.
  */
@@ -109,23 +106,24 @@ public:
 /**
  * Holds the shared data of a TextureClient, to be destroyed later.
  *
  * TextureClient's destructor initiates the destruction sequence of the
  * texture client/host pair. If the shared data is to be deallocated on the
  * host side, there is nothing to do.
  * On the other hand, if the client data must be deallocated on the client
  * side, the CompositableClient will ask the TextureClient to drop its shared
- * data in the form of a TextureClientData object. This data will be kept alive
- * until the host side confirms that it is not using the data anymore and that
- * it is completely safe to deallocate the shared data.
+ * data in the form of a TextureClientData object. The compositable will keep
+ * this object until it has received from the host side the confirmation that
+ * the compositor is not using the texture and that it is completely safe to
+ * deallocate the shared data.
  *
  * See:
- *  - The PTexture IPDL protocol
- *  - CompositableChild in TextureClient.cpp
+ *  - CompositableClient::RemoveTextureClient
+ *  - CompositableClient::OnReplyTextureRemoved
  */
 class TextureClientData {
 public:
   virtual void DeallocateSharedData(ISurfaceAllocator* allocator) = 0;
   virtual ~TextureClientData() {}
 };
 
 /**
@@ -146,18 +144,17 @@ public:
  * TextureClient/Host pair only owns one buffer of image data through its
  * lifetime. This means that the lifetime of the underlying shared data
  * matches the lifetime of the TextureClient/Host pair. It also means
  * TextureClient/Host do not implement double buffering, which is the
  * responsibility of the compositable (which would use two Texture pairs).
  * In order to send several different buffers to the compositor side, use
  * several TextureClients.
  */
-class TextureClient
-  : public AtomicRefCountedWithFinalize<TextureClient>
+class TextureClient : public AtomicRefCounted<TextureClient>
 {
 public:
   TextureClient(TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
   virtual ~TextureClient();
 
   virtual TextureClientSurface* AsTextureClientSurface() { return nullptr; }
   virtual TextureClientDrawTarget* AsTextureClientDrawTarget() { return nullptr; }
   virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; }
@@ -175,25 +172,38 @@ public:
   /**
    * Returns true if this texture has a lock/unlock mechanism.
    * Textures that do not implement locking should be immutable or should
    * use immediate uploads (see TextureFlags in CompositorTypes.h)
    */
   virtual bool ImplementsLocking() const { return false; }
 
   /**
-   * Allocate and deallocate a TextureChild actor.
+   * Sets this texture's ID.
    *
-   * TextureChild is an implementation detail of TextureHost that is not
-   * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
-   * are for use with the maging IPDL protocols only (so that they can
-   * implement AllocPextureChild and DeallocPTextureChild).
+   * This ID is used to match a texture client with his corresponding TextureHost.
+   * Only the CompositableClient should be allowed to set or clear the ID.
+   * Zero is always an invalid ID.
+   * For a given compositableClient, there can never be more than one texture
+   * client with the same non-zero ID.
+   * Texture clients from different compositables may have the same ID.
    */
-  static PTextureChild* CreateIPDLActor();
-  static bool DestroyIPDLActor(PTextureChild* actor);
+  void SetID(uint64_t aID)
+  {
+    MOZ_ASSERT(mID == 0 && aID != 0);
+    mID = aID;
+    mShared = true;
+  }
+  void ClearID()
+  {
+    MOZ_ASSERT(mID != 0);
+    mID = 0;
+  }
+
+  uint64_t GetID() const { return mID; }
 
   virtual bool IsAllocated() const = 0;
 
   virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
 
   virtual gfx::IntSize GetSize() const = 0;
 
   /**
@@ -234,60 +244,31 @@ public:
   bool IsValid() const { return mValid; }
 
   /**
    * An invalid TextureClient cannot provide access to its shared data
    * anymore. This usually means it will soon be destroyed.
    */
   void MarkInvalid() { mValid = false; }
 
-  /**
-   * Create and init the TextureChild/Parent IPDL actor pair.
-   *
-   * Should be called only once per TextureClient.
-   */
-  bool InitIPDLActor(CompositableForwarder* aForwarder);
-
-  /**
-   * Return a pointer to the IPDLActor.
-   *
-   * This is to be used with IPDL messages only. Do not store the returned
-   * pointer.
-   */
-  PTextureChild* GetIPDLActor();
-
-  /**
-   * TODO[nical] doc!
-   */
-  void ForceRemove();
-
-private:
-  /**
-   * Called once, just before the destructor.
-   *
-   * Here goes the shut-down code that uses virtual methods.
-   * Must only be called by Release().
-   */
-  void Finalize();
-
-  friend class AtomicRefCountedWithFinalize<TextureClient>;
+  // If a texture client holds a reference to shmem, it should override this
+  // method to forget about the shmem _without_ releasing it.
+  virtual void OnActorDestroy() {}
 
 protected:
   void AddFlags(TextureFlags  aFlags)
   {
     MOZ_ASSERT(!IsSharedWithCompositor());
     mFlags |= aFlags;
   }
 
-  TextureChild* mActor;
+  uint64_t mID;
   TextureFlags mFlags;
   bool mShared;
   bool mValid;
-
-  friend class TextureChild;
 };
 
 /**
  * TextureClient that wraps a random access buffer such as a Shmem or raw memory.
  * This class must be inherited to implement the memory allocation and access bits.
  * (see ShmemTextureClient and MemoryTextureClient)
  */
 class BufferTextureClient : public TextureClient
@@ -375,16 +356,21 @@ public:
   virtual bool IsAllocated() const MOZ_OVERRIDE { return mAllocated; }
 
   virtual TextureClientData* DropTextureData() MOZ_OVERRIDE;
 
   ISurfaceAllocator* GetAllocator() const;
 
   ipc::Shmem& GetShmem() { return mShmem; }
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE
+  {
+    mShmem = ipc::Shmem();
+  }
+
 protected:
   ipc::Shmem mShmem;
   RefPtr<ISurfaceAllocator> mAllocator;
   bool mAllocated;
 };
 
 /**
  * TextureClient that wraps raw memory.
@@ -551,16 +537,18 @@ public:
 
   AccessMode GetAccessMode() const
   {
     return mAccessMode;
   }
 
   virtual gfxContentType GetContentType() = 0;
 
+  void OnActorDestroy();
+
 protected:
   DeprecatedTextureClient(CompositableForwarder* aForwarder,
                 const TextureInfo& aTextureInfo);
 
   CompositableForwarder* mForwarder;
   // So far all DeprecatedTextureClients use a SurfaceDescriptor, so it makes sense to
   // keep the reference here.
   SurfaceDescriptor mDescriptor;
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -247,16 +247,24 @@ public:
                          LayerManager::DrawThebesLayerCallback aCallback,
                          void* aCallbackData);
 
   SurfaceDescriptorTiles GetSurfaceDescriptorTiles();
 
   static BasicTiledLayerBuffer OpenDescriptor(ISurfaceAllocator* aAllocator,
                                               const SurfaceDescriptorTiles& aDescriptor);
 
+  void OnActorDestroy()
+  {
+    for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
+      if (mRetainedTiles[i].IsPlaceholderTile()) continue;
+      mRetainedTiles[i].mDeprecatedTextureClient->OnActorDestroy();
+    }
+  }
+
 protected:
   BasicTiledLayerTile ValidateTile(BasicTiledLayerTile aTile,
                                    const nsIntPoint& aTileRect,
                                    const nsIntRegion& dirtyRect);
 
   // If this returns true, we perform the paint operation into a single large
   // buffer and copy it out to the tiles instead of calling PaintThebes() on
   // each tile individually. Somewhat surprisingly, this turns out to be faster
@@ -336,16 +344,22 @@ public:
   }
 
   enum TiledBufferType {
     TILED_BUFFER,
     LOW_PRECISION_TILED_BUFFER
   };
   void LockCopyAndWrite(TiledBufferType aType);
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE
+  {
+    mTiledBuffer.OnActorDestroy();
+    mLowPrecisionTiledBuffer.OnActorDestroy();
+  }
+
 private:
   BasicTiledLayerBuffer mTiledBuffer;
   BasicTiledLayerBuffer mLowPrecisionTiledBuffer;
 };
 
 }
 }
 
--- a/gfx/layers/composite/CompositableHost.cpp
+++ b/gfx/layers/composite/CompositableHost.cpp
@@ -31,32 +31,92 @@ CompositableHost::CompositableHost(const
   , mKeepAttached(false)
 {
   MOZ_COUNT_CTOR(CompositableHost);
 }
 
 CompositableHost::~CompositableHost()
 {
   MOZ_COUNT_DTOR(CompositableHost);
+
+  RefPtr<TextureHost> it = mFirstTexture;
+  while (it) {
+    if (!(it->GetFlags() & TEXTURE_DEALLOCATE_CLIENT)) {
+      it->DeallocateSharedData();
+    }
+    it = it->GetNextSibling();
+  }
+}
+
+void
+CompositableHost::AddTextureHost(TextureHost* aTexture)
+{
+  MOZ_ASSERT(aTexture);
+  MOZ_ASSERT(GetTextureHost(aTexture->GetID()) == nullptr,
+             "A texture is already present with this ID");
+  RefPtr<TextureHost> second = mFirstTexture;
+  mFirstTexture = aTexture;
+  aTexture->SetNextSibling(second);
+  aTexture->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
 }
 
 void
-CompositableHost::UseTextureHost(TextureHost* aTexture)
+CompositableHost::RemoveTextureHost(TextureHost* aTexture)
 {
-  if (!aTexture) {
-    return;
+  uint64_t textureID = aTexture->GetID();
+  if (mFirstTexture && mFirstTexture->GetID() == textureID) {
+    mFirstTexture = mFirstTexture->GetNextSibling();
+    aTexture->SetNextSibling(nullptr);
+  }
+  RefPtr<TextureHost> it = mFirstTexture;
+  while (it) {
+    if (it->GetNextSibling() &&
+        it->GetNextSibling()->GetID() == textureID) {
+      it->SetNextSibling(it->GetNextSibling()->GetNextSibling());
+      aTexture->SetNextSibling(nullptr);
+    }
+    it = it->GetNextSibling();
+  }
+  if (!mFirstTexture && mBackendData) {
+    mBackendData->ClearData();
   }
-  aTexture->SetCompositor(GetCompositor());
-  aTexture->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
+}
+
+TextureHost*
+CompositableHost::GetTextureHost(uint64_t aTextureID)
+{
+  RefPtr<TextureHost> it = mFirstTexture;
+  while (it) {
+    if (it->GetID() == aTextureID) {
+      return it;
+    }
+    it = it->GetNextSibling();
+  }
+  return nullptr;
+}
+
+void
+CompositableHost::OnActorDestroy()
+{
+  TextureHost* it = mFirstTexture;
+  while (it) {
+    it->OnActorDestroy();
+    it = it->GetNextSibling();
+  }
 }
 
 void
 CompositableHost::SetCompositor(Compositor* aCompositor)
 {
   mCompositor = aCompositor;
+  RefPtr<TextureHost> it = mFirstTexture;
+  while (!!it) {
+    it->SetCompositor(aCompositor);
+    it = it->GetNextSibling();
+  }
 }
 
 bool
 CompositableHost::Update(const SurfaceDescriptor& aImage,
                          SurfaceDescriptor* aResult)
 {
   if (!GetDeprecatedTextureHost()) {
     *aResult = aImage;
@@ -199,16 +259,23 @@ CompositableHost::DumpTextureHost(FILE* 
   surf->DumpAsDataURL(aFile ? aFile : stderr);
 }
 #endif
 
 void
 CompositableParent::ActorDestroy(ActorDestroyReason why)
 {
   if (mHost) {
+    // XXX: sadness warning. We should be able to do this whenever we get ActorDestroy,
+    // not just for abnormal shutdowns (which is the only case we _need_ to - so that
+    // we don't double release our shmems). But, for some reason, that causes a
+    // crash, we don't know why. (Bug 925773).
+    if (why == AbnormalShutdown) {
+      mHost->OnActorDestroy();
+    }
     mHost->Detach(nullptr, CompositableHost::FORCE_DETACH);
   }
 }
 
 CompositableParent::CompositableParent(CompositableParentManager* aMgr,
                                        const TextureInfo& aTextureInfo,
                                        uint64_t aID)
 : mManager(aMgr)
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -103,16 +103,22 @@ public:
     return mBackendData;
   }
 
   virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
   {
     mBackendData = aBackendData;
   }
 
+  /**
+   * Our IPDL actor is being destroyed, get rid of any shmem resources now and
+   * don't worry about compositing anymore.
+   */
+  virtual void OnActorDestroy();
+
   // If base class overrides, it should still call the parent implementation
   virtual void SetCompositor(Compositor* aCompositor);
 
   // composite the contents of this buffer host to the compositor's surface
   virtual void Composite(EffectChain& aEffectChain,
                          float aOpacity,
                          const gfx::Matrix4x4& aTransform,
                          const gfx::Filter& aFilter,
@@ -283,23 +289,33 @@ public:
   static void DumpDeprecatedTextureHost(FILE* aFile, DeprecatedTextureHost* aTexture);
   static void DumpTextureHost(FILE* aFile, TextureHost* aTexture);
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() { return nullptr; }
 #endif
 
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix) { }
 
-  virtual void UseTextureHost(TextureHost* aTexture);
+  void AddTextureHost(TextureHost* aTexture);
+  virtual void UseTextureHost(TextureHost* aTexture) {}
+  // If a texture host is flagged for deferred removal, the compositable will
+  // get an option to run any cleanup code early, that is when it would have
+  // been run if the texture host was not marked deferred.
+  // If the compositable does not cleanup the texture host now, it is the
+  // compositable's responsibility to cleanup the texture host before the
+  // texture host dies.
+  virtual void RemoveTextureHost(TextureHost* aTexture);
+  TextureHost* GetTextureHost(uint64_t aTextureID);
 
 protected:
   TextureInfo mTextureInfo;
   Compositor* mCompositor;
   Layer* mLayer;
   RefPtr<CompositableBackendSpecificData> mBackendData;
+  RefPtr<TextureHost> mFirstTexture;
   bool mAttached;
   bool mKeepAttached;
 };
 
 class CompositableParentManager;
 
 /**
  * IPDL actor used by CompositableHost to match with its corresponding
--- a/gfx/layers/composite/ContentHost.cpp
+++ b/gfx/layers/composite/ContentHost.cpp
@@ -27,24 +27,70 @@ namespace layers {
 ContentHostBase::ContentHostBase(const TextureInfo& aTextureInfo)
   : ContentHost(aTextureInfo)
   , mPaintWillResample(false)
   , mInitialised(false)
 {}
 
 ContentHostBase::~ContentHostBase()
 {
+  DestroyTextureHost();
+  DestroyTextureHostOnWhite();
 }
 
 TextureHost*
 ContentHostBase::GetAsTextureHost()
 {
   return mTextureHost;
 }
 
+void
+ContentHostBase::DestroyTextureHost()
+{
+  // The third clause in the if statement checks that we are in fact done with
+  // this texture. We don't want to prematurely deallocate a texture we might
+  // use again or double deallocate. Deallocation will happen in
+  // RemoveTextureHost.
+  // Note that GetTextureHost is linear in the number of texture hosts, but as
+  // long as that number is small (I expect a maximum of 6 for now) then it
+  // should be ok.
+  if (mTextureHost &&
+      mTextureHost->GetFlags() & TEXTURE_DEALLOCATE_DEFERRED &&
+      !GetTextureHost(mTextureHost->GetID())) {
+    MOZ_ASSERT(!(mTextureHost->GetFlags() & TEXTURE_DEALLOCATE_CLIENT));
+    mTextureHost->DeallocateSharedData();
+  }
+  mTextureHost = nullptr;
+}
+
+void
+ContentHostBase::DestroyTextureHostOnWhite()
+{
+  if (mTextureHostOnWhite &&
+      mTextureHostOnWhite->GetFlags() & TEXTURE_DEALLOCATE_DEFERRED &&
+      !GetTextureHost(mTextureHostOnWhite->GetID())) {
+    MOZ_ASSERT(!(mTextureHostOnWhite->GetFlags() & TEXTURE_DEALLOCATE_CLIENT));
+    mTextureHostOnWhite->DeallocateSharedData();
+  }
+  mTextureHostOnWhite = nullptr;
+}
+
+void
+ContentHostBase::RemoveTextureHost(TextureHost* aTexture)
+{
+  if ((aTexture->GetFlags() & TEXTURE_DEALLOCATE_DEFERRED) &&
+      !(mTextureHost && mTextureHost == aTexture) &&
+      !(mTextureHostOnWhite && mTextureHostOnWhite == aTexture)) {
+    MOZ_ASSERT(!(aTexture->GetFlags() & TEXTURE_DEALLOCATE_CLIENT));
+    aTexture->DeallocateSharedData();
+  }
+
+  CompositableHost::RemoveTextureHost(aTexture);
+}
+
 class MOZ_STACK_CLASS AutoLockTextureHost
 {
 public:
   AutoLockTextureHost(TextureHost* aHost)
     : mHost(aHost)
   {
     mLockSuccess = mHost ? mHost->Lock() : true;
   }
@@ -235,20 +281,20 @@ ContentHostBase::Composite(EffectChain& 
   GetCompositor()->DrawDiagnostics(diagnostics, *aVisibleRegion, aClipRect, aTransform);
 }
 
 
 void
 ContentHostBase::UseTextureHost(TextureHost* aTexture)
 {
   if (aTexture->GetFlags() & TEXTURE_ON_WHITE) {
-    mTextureHost = nullptr;
+    DestroyTextureHost();
     mTextureHostOnWhite = aTexture;
   } else {
-    mTextureHostOnWhite = nullptr;
+    DestroyTextureHostOnWhite();
     mTextureHost = aTexture;
   }
 }
 
 void
 ContentHostBase::SetCompositor(Compositor* aCompositor)
 {
   CompositableHost::SetCompositor(aCompositor);
@@ -284,16 +330,28 @@ ContentHostBase::Dump(FILE* aFile,
     fprintf(aFile, "<li> <a href=");
     DumpTextureHost(aFile, mTextureHostOnWhite);
     fprintf(aFile, "> Front buffer on white </a> </li> ");
   }
   fprintf(aFile, "</ul>");
 }
 #endif
 
+void
+ContentHostBase::OnActorDestroy()
+{
+  if (mTextureHost) {
+    mTextureHost->OnActorDestroy();
+  }
+  if (mTextureHostOnWhite) {
+    mTextureHostOnWhite->OnActorDestroy();
+  }
+  CompositableHost::OnActorDestroy();
+}
+
 DeprecatedContentHostBase::DeprecatedContentHostBase(const TextureInfo& aTextureInfo)
   : ContentHost(aTextureInfo)
   , mPaintWillResample(false)
   , mInitialised(false)
 {}
 
 DeprecatedContentHostBase::~DeprecatedContentHostBase()
 {}
@@ -311,16 +369,33 @@ DeprecatedContentHostBase::DestroyFrontH
              "We won't be able to destroy our SurfaceDescriptor");
   MOZ_ASSERT(!mDeprecatedTextureHostOnWhite || mDeprecatedTextureHostOnWhite->GetDeAllocator(),
              "We won't be able to destroy our SurfaceDescriptor");
   mDeprecatedTextureHost = nullptr;
   mDeprecatedTextureHostOnWhite = nullptr;
 }
 
 void
+DeprecatedContentHostBase::OnActorDestroy()
+{
+  if (mDeprecatedTextureHost) {
+    mDeprecatedTextureHost->OnActorDestroy();
+  }
+  if (mDeprecatedTextureHostOnWhite) {
+    mDeprecatedTextureHostOnWhite->OnActorDestroy();
+  }
+  if (mNewFrontHost) {
+    mNewFrontHost->OnActorDestroy();
+  }
+  if (mNewFrontHostOnWhite) {
+    mNewFrontHostOnWhite->OnActorDestroy();
+  }
+}
+
+void
 DeprecatedContentHostBase::Composite(EffectChain& aEffectChain,
                            float aOpacity,
                            const gfx::Matrix4x4& aTransform,
                            const Filter& aFilter,
                            const Rect& aClipRect,
                            const nsIntRegion* aVisibleRegion,
                            TiledLayerProperties* aLayerProperties)
 {
@@ -769,16 +844,39 @@ DeprecatedContentHostDoubleBuffered::Des
                "We won't be able to destroy our SurfaceDescriptor");
     mBackHostOnWhite = nullptr;
   }
 
   // don't touch mDeprecatedTextureHost, we might need it for compositing
 }
 
 void
+DeprecatedContentHostDoubleBuffered::OnActorDestroy()
+{
+  if (mDeprecatedTextureHost) {
+    mDeprecatedTextureHost->OnActorDestroy();
+  }
+  if (mDeprecatedTextureHostOnWhite) {
+    mDeprecatedTextureHostOnWhite->OnActorDestroy();
+  }
+  if (mNewFrontHost) {
+    mNewFrontHost->OnActorDestroy();
+  }
+  if (mNewFrontHostOnWhite) {
+    mNewFrontHostOnWhite->OnActorDestroy();
+  }
+  if (mBackHost) {
+    mBackHost->OnActorDestroy();
+  }
+  if (mBackHostOnWhite) {
+    mBackHostOnWhite->OnActorDestroy();
+  }
+}
+
+void
 DeprecatedContentHostDoubleBuffered::UpdateThebes(const ThebesBufferData& aData,
                                         const nsIntRegion& aUpdated,
                                         const nsIntRegion& aOldValidRegionBack,
                                         nsIntRegion* aUpdatedRegionBack)
 {
   if (!mDeprecatedTextureHost && !mNewFrontHost) {
     mInitialised = false;
 
--- a/gfx/layers/composite/ContentHost.h
+++ b/gfx/layers/composite/ContentHost.h
@@ -112,26 +112,34 @@ public:
 #endif
 
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix) MOZ_OVERRIDE;
 
   virtual TextureHost* GetAsTextureHost() MOZ_OVERRIDE;
 
   virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
 
+  virtual void RemoveTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
+
   virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 protected:
   virtual nsIntPoint GetOriginOffset()
   {
     return mBufferRect.TopLeft() - mBufferRotation;
   }
 
   bool PaintWillResample() { return mPaintWillResample; }
 
+  // These must be called before forgetting mTextureHost or mTextureHostOnWhite
+  void DestroyTextureHost();
+  void DestroyTextureHostOnWhite();
+
   nsIntRect mBufferRect;
   nsIntPoint mBufferRotation;
   RefPtr<TextureHost> mTextureHost;
   RefPtr<TextureHost> mTextureHostOnWhite;
   bool mPaintWillResample;
   bool mInitialised;
 };
 class DeprecatedContentHostBase : public ContentHost
@@ -172,16 +180,18 @@ public:
   virtual DeprecatedTextureHost* GetDeprecatedTextureHost() MOZ_OVERRIDE;
 
   virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
   // The client has destroyed its texture clients and we should destroy our
   // texture hosts and SurfaceDescriptors. Note that we don't immediately
   // destroy our front buffer so that we can continue to composite.
   virtual void DestroyTextures() = 0;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 protected:
   virtual nsIntPoint GetOriginOffset()
   {
     return mBufferRect.TopLeft() - mBufferRotation;
   }
 
   bool PaintWillResample() { return mPaintWillResample; }
 
@@ -244,16 +254,18 @@ public:
                             nsIntRegion* aUpdatedRegionBack);
 
   virtual void EnsureDeprecatedTextureHost(TextureIdentifier aTextureId,
                                  const SurfaceDescriptor& aSurface,
                                  ISurfaceAllocator* aAllocator,
                                  const TextureInfo& aTextureInfo) MOZ_OVERRIDE;
   virtual void DestroyTextures() MOZ_OVERRIDE;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
+
 #ifdef MOZ_DUMP_PAINTING
   virtual void Dump(FILE* aFile=nullptr,
                     const char* aPrefix="",
                     bool aDumpHtml=false) MOZ_OVERRIDE;
 #endif
 
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
 protected:
--- a/gfx/layers/composite/ImageHost.cpp
+++ b/gfx/layers/composite/ImageHost.cpp
@@ -33,24 +33,26 @@ ImageHost::ImageHost(const TextureInfo& 
   , mHasPictureRect(false)
 {}
 
 ImageHost::~ImageHost() {}
 
 void
 ImageHost::UseTextureHost(TextureHost* aTexture)
 {
-  if (mFrontBuffer) {
-    // XXX - When we implement sharing textures between several compositables
-    // we will need to not remove the compositor if there is another compositable
-    // using the texture.
-    mFrontBuffer->SetCompositor(nullptr);
+  mFrontBuffer = aTexture;
+}
+
+void
+ImageHost::RemoveTextureHost(TextureHost* aTexture)
+{
+  CompositableHost::RemoveTextureHost(aTexture);
+  if (mFrontBuffer && mFrontBuffer->GetID() == aTexture->GetID()) {
+    mFrontBuffer = nullptr;
   }
-  CompositableHost::UseTextureHost(aTexture);
-  mFrontBuffer = aTexture;
 }
 
 TextureHost*
 ImageHost::GetAsTextureHost()
 {
   return mFrontBuffer;
 }
 
@@ -67,20 +69,16 @@ ImageHost::Composite(EffectChain& aEffec
     // should only happen when a tab is dragged to another window and
     // async-video is still sending frames but we haven't attached the
     // set the new compositor yet.
     return;
   }
   if (!mFrontBuffer) {
     return;
   }
-
-  // Make sure the front buffer has a compositor
-  mFrontBuffer->SetCompositor(GetCompositor());
-
   if (!mFrontBuffer->Lock()) {
     NS_WARNING("failed to lock front buffer");
     return;
   }
   RefPtr<NewTextureSource> source = mFrontBuffer->GetTextureSources();
   if (!source) {
     return;
   }
@@ -152,25 +150,16 @@ ImageHost::Composite(EffectChain& aEffec
     GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE,
                                      rect, aClipRect,
                                      aTransform);
   }
   mFrontBuffer->Unlock();
 }
 
 void
-ImageHost::SetCompositor(Compositor* aCompositor)
-{
-  if (mFrontBuffer && mCompositor != aCompositor) {
-    mFrontBuffer->SetCompositor(aCompositor);
-  }
-  CompositableHost::SetCompositor(aCompositor);
-}
-
-void
 ImageHost::PrintInfo(nsACString& aTo, const char* aPrefix)
 {
   aTo += aPrefix;
   aTo += nsPrintfCString("ImageHost (0x%p)", this);
 
   AppendToString(aTo, mPictureRect, " [picture-rect=", "]");
 
   if (mFrontBuffer) {
--- a/gfx/layers/composite/ImageHost.h
+++ b/gfx/layers/composite/ImageHost.h
@@ -50,28 +50,35 @@ public:
                          const gfx::Matrix4x4& aTransform,
                          const gfx::Filter& aFilter,
                          const gfx::Rect& aClipRect,
                          const nsIntRegion* aVisibleRegion = nullptr,
                          TiledLayerProperties* aLayerProperties = nullptr) MOZ_OVERRIDE;
 
   virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
 
-  virtual TextureHost* GetAsTextureHost() MOZ_OVERRIDE;
+  virtual void RemoveTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
 
-  virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
+  virtual TextureHost* GetAsTextureHost() MOZ_OVERRIDE;
 
   virtual void SetPictureRect(const nsIntRect& aPictureRect) MOZ_OVERRIDE
   {
     mPictureRect = aPictureRect;
     mHasPictureRect = true;
   }
 
   virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE
+  {
+    if (mFrontBuffer) {
+      mFrontBuffer->OnActorDestroy();
+    }
+  }
+
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
 
 #ifdef MOZ_DUMP_PAINTING
   virtual void Dump(FILE* aFile=NULL,
                     const char* aPrefix="",
                     bool aDumpHtml=false) MOZ_OVERRIDE;
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
@@ -122,16 +129,23 @@ public:
     mPictureRect = aPictureRect;
     mHasPictureRect = true;
   }
 
   virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE
+  {
+    if (mDeprecatedTextureHost) {
+      mDeprecatedTextureHost->OnActorDestroy();
+    }
+  }
+
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
 
 #ifdef MOZ_DUMP_PAINTING
   virtual void Dump(FILE* aFile=nullptr,
                     const char* aPrefix="",
                     bool aDumpHtml=false) MOZ_OVERRIDE;
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -13,78 +13,22 @@
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/ISurfaceAllocator.h"  // for ISurfaceAllocator
 #include "mozilla/layers/ImageDataSerializer.h"
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
 #include "nsAString.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsPrintfCString.h"            // for nsPrintfCString
-#include "mozilla/layers/PTextureParent.h"
 
 struct nsIntPoint;
 
 namespace mozilla {
 namespace layers {
 
-/**
- * TextureParent is the host-side IPDL glue between TextureClient and TextureHost.
- * It is an IPDL actor just like LayerParent, CompositableParent, etc.
- */
-class TextureParent : public PTextureParent
-{
-public:
-  TextureParent(ISurfaceAllocator* aAllocator);
-
-  ~TextureParent();
-
-  bool RecvInit(const SurfaceDescriptor& aSharedData,
-                const TextureFlags& aFlags) MOZ_OVERRIDE;
-
-  virtual bool RecvRemoveTexture() MOZ_OVERRIDE;
-
-  virtual bool RecvRemoveTextureSync() MOZ_OVERRIDE;
-
-  TextureHost* GetTextureHost() { return mTextureHost; }
-
-  void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
-
-  ISurfaceAllocator* mAllocator;
-  RefPtr<TextureHost> mTextureHost;
-};
-
-// static
-PTextureParent*
-TextureHost::CreateIPDLActor(ISurfaceAllocator* aAllocator)
-{
-  return new TextureParent(aAllocator);
-}
-
-// static
-bool
-TextureHost::DestroyIPDLActor(PTextureParent* actor)
-{
-  delete actor;
-  return true;
-}
-
-// static
-bool
-TextureHost::SendDeleteIPDLActor(PTextureParent* actor)
-{
-  return PTextureParent::Send__delete__(actor);
-}
-
-// static
-TextureHost*
-TextureHost::AsTextureHost(PTextureParent* actor)
-{
-  return actor? static_cast<TextureParent*>(actor)->mTextureHost : nullptr;
-}
-
 // implemented in TextureOGL.cpp
 TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostOGL(SurfaceDescriptorType aDescriptorType,
                                                            uint32_t aDeprecatedTextureHostFlags,
                                                            uint32_t aTextureFlags);
 // implemented in BasicCompositor.cpp
 TemporaryRef<DeprecatedTextureHost> CreateBasicDeprecatedTextureHost(SurfaceDescriptorType aDescriptorType,
                                                              uint32_t aDeprecatedTextureHostFlags,
                                                              uint32_t aTextureFlags);
@@ -132,72 +76,78 @@ DeprecatedTextureHost::CreateDeprecatedT
                                           aDeprecatedTextureHostFlags,
                                           aTextureFlags);
     default:
       MOZ_CRASH("Couldn't create texture host");
   }
 }
 
 // implemented in TextureHostOGL.cpp
-TemporaryRef<TextureHost> CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
+TemporaryRef<TextureHost> CreateTextureHostOGL(uint64_t aID,
+                                               const SurfaceDescriptor& aDesc,
                                                ISurfaceAllocator* aDeallocator,
                                                TextureFlags aFlags);
 
 // implemented in TextureHostBasic.cpp
-TemporaryRef<TextureHost> CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
-                                                 ISurfaceAllocator* aDeallocator,
-                                                 TextureFlags aFlags);
+TemporaryRef<TextureHost> CreateTextureHostBasic(uint64_t aID,
+                                               const SurfaceDescriptor& aDesc,
+                                               ISurfaceAllocator* aDeallocator,
+                                               TextureFlags aFlags);
 
 // static
 TemporaryRef<TextureHost>
-TextureHost::Create(const SurfaceDescriptor& aDesc,
+TextureHost::Create(uint64_t aID,
+                    const SurfaceDescriptor& aDesc,
                     ISurfaceAllocator* aDeallocator,
                     TextureFlags aFlags)
 {
   switch (Compositor::GetBackend()) {
     case LAYERS_OPENGL:
-      return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
+      return CreateTextureHostOGL(aID, aDesc, aDeallocator, aFlags);
     case LAYERS_BASIC:
-      return CreateTextureHostBasic(aDesc, aDeallocator, aFlags);
+      return CreateTextureHostBasic(aID, aDesc, aDeallocator, aFlags);
 #ifdef MOZ_WIDGET_GONK
     case LAYERS_NONE:
       // Power on video reqests to allocate TextureHost,
       // when Compositor is still not present. This is a very hacky workaround.
       // See Bug 944420.
-      return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
+      return CreateTextureHostOGL(aID, aDesc, aDeallocator, aFlags);
 #endif
 #ifdef XP_WIN
     case LAYERS_D3D11:
     case LAYERS_D3D9:
       // XXX - not implemented yet
 #endif
     default:
       MOZ_CRASH("Couldn't create texture host");
       return nullptr;
   }
 }
 
 TemporaryRef<TextureHost>
-CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
+CreateBackendIndependentTextureHost(uint64_t aID,
+                                    const SurfaceDescriptor& aDesc,
                                     ISurfaceAllocator* aDeallocator,
                                     TextureFlags aFlags)
 {
   RefPtr<TextureHost> result;
   switch (aDesc.type()) {
     case SurfaceDescriptor::TSurfaceDescriptorShmem: {
       const SurfaceDescriptorShmem& descriptor = aDesc.get_SurfaceDescriptorShmem();
-      result = new ShmemTextureHost(descriptor.data(),
+      result = new ShmemTextureHost(aID,
+                                    descriptor.data(),
                                     descriptor.format(),
                                     aDeallocator,
                                     aFlags);
       break;
     }
     case SurfaceDescriptor::TSurfaceDescriptorMemory: {
       const SurfaceDescriptorMemory& descriptor = aDesc.get_SurfaceDescriptorMemory();
-      result = new MemoryTextureHost(reinterpret_cast<uint8_t*>(descriptor.data()),
+      result = new MemoryTextureHost(aID,
+                                     reinterpret_cast<uint8_t*>(descriptor.data()),
                                      descriptor.format(),
                                      aFlags);
       break;
     }
     default: {
       NS_WARNING("No backend independent TextureHost for this descriptor type");
     }
   }
@@ -206,33 +156,27 @@ CreateBackendIndependentTextureHost(cons
 
 void
 TextureHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
 {
     mCompositableBackendData = aBackendData;
 }
 
 
-TextureHost::TextureHost(TextureFlags aFlags)
-    : mFlags(aFlags)
+TextureHost::TextureHost(uint64_t aID,
+                         TextureFlags aFlags)
+    : mID(aID)
+    , mNextTexture(nullptr)
+    , mFlags(aFlags)
 {}
 
 TextureHost::~TextureHost()
 {
 }
 
-void TextureHost::Finalize()
-{
-  if (GetFlags() & TEXTURE_DEALLOCATE_DEFERRED) {
-    MOZ_ASSERT(!(GetFlags() & TEXTURE_DEALLOCATE_CLIENT));
-    DeallocateSharedData();
-    DeallocateDeviceData();
-  }
-}
-
 void
 TextureHost::PrintInfo(nsACString& aTo, const char* aPrefix)
 {
   aTo += aPrefix;
   aTo += nsPrintfCString("%s (0x%p)", Name(), this);
   AppendToString(aTo, GetSize(), " [size=", "]");
   AppendToString(aTo, GetFormat(), " [format=", "]");
   AppendToString(aTo, mFlags, " [flags=", "]");
@@ -304,17 +248,17 @@ DeprecatedTextureHost::SwapTextures(cons
   // register the TextureHost with the GrallocBufferActor.
   // The reason why this SetBuffer calls is needed here is that just above we
   // overwrote *mBuffer in place, so we need to tell the new mBuffer about this
   // TextureHost.
   SetBuffer(mBuffer, mDeAllocator);
 }
 
 void
-DeprecatedTextureHost::OnShutdown()
+DeprecatedTextureHost::OnActorDestroy()
 {
   if (ISurfaceAllocator::IsShmem(mBuffer)) {
     *mBuffer = SurfaceDescriptor();
     mBuffer = nullptr;
   }
 }
 
 void
@@ -330,19 +274,20 @@ DeprecatedTextureHost::PrintInfo(nsACStr
 void
 DeprecatedTextureHost::SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator)
 {
   MOZ_ASSERT(!mBuffer || mBuffer == aBuffer, "Will leak the old mBuffer");
   mBuffer = aBuffer;
   mDeAllocator = aAllocator;
 }
 
-BufferTextureHost::BufferTextureHost(gfx::SurfaceFormat aFormat,
+BufferTextureHost::BufferTextureHost(uint64_t aID,
+                                     gfx::SurfaceFormat aFormat,
                                      TextureFlags aFlags)
-: TextureHost(aFlags)
+: TextureHost(aID, aFlags)
 , mCompositor(nullptr)
 , mFormat(aFormat)
 , mUpdateSerial(1)
 , mLocked(false)
 , mPartialUpdate(false)
 {}
 
 BufferTextureHost::~BufferTextureHost()
@@ -434,29 +379,16 @@ BufferTextureHost::MaybeUpload(nsIntRegi
   }
   mFirstSource->SetUpdateSerial(mUpdateSerial);
   return true;
 }
 
 bool
 BufferTextureHost::Upload(nsIntRegion *aRegion)
 {
-  if (!GetBuffer()) {
-    // We don't have a buffer; a possible cause is that the IPDL actor
-    // is already dead. This inevitably happens as IPDL actors can die
-    // at any time, so we want to silently return in this case.
-    return false;
-  }
-  if (!mCompositor) {
-    NS_WARNING("Tried to upload without a compositor. Skipping texture upload...");
-    // If we are in this situation it means we should have called SetCompositor
-    // earlier. It is conceivable that on certain rare conditions with async-video
-    // we may end up here for the first frame, but this should not happen repeatedly.
-    return false;
-  }
   if (mFormat == gfx::FORMAT_UNKNOWN) {
     NS_WARNING("BufferTextureHost: unsupported format!");
     return false;
   } else if (mFormat == gfx::FORMAT_YUV) {
     YCbCrImageDataDeserializer yuvDeserializer(GetBuffer());
     MOZ_ASSERT(yuvDeserializer.IsValid());
 
     if (!mCompositor->SupportsEffect(EFFECT_YCBCR)) {
@@ -557,21 +489,22 @@ BufferTextureHost::GetAsSurface()
     if (!deserializer.IsValid()) {
       return nullptr;
     }
     result = deserializer.GetAsSurface();
   }
   return result.forget();
 }
 
-ShmemTextureHost::ShmemTextureHost(const ipc::Shmem& aShmem,
+ShmemTextureHost::ShmemTextureHost(uint64_t aID,
+                                   const ipc::Shmem& aShmem,
                                    gfx::SurfaceFormat aFormat,
                                    ISurfaceAllocator* aDeallocator,
                                    TextureFlags aFlags)
-: BufferTextureHost(aFormat, aFlags)
+: BufferTextureHost(aID, aFormat, aFlags)
 , mShmem(new ipc::Shmem(aShmem))
 , mDeallocator(aDeallocator)
 {
   MOZ_COUNT_CTOR(ShmemTextureHost);
 }
 
 ShmemTextureHost::~ShmemTextureHost()
 {
@@ -582,46 +515,37 @@ ShmemTextureHost::~ShmemTextureHost()
 
 void
 ShmemTextureHost::DeallocateSharedData()
 {
   if (mShmem) {
     MOZ_ASSERT(mDeallocator,
                "Shared memory would leak without a ISurfaceAllocator");
     mDeallocator->DeallocShmem(*mShmem);
-    delete mShmem;
     mShmem = nullptr;
   }
 }
 
 void
-ShmemTextureHost::ForgetSharedData()
-{
-  if (mShmem) {
-    delete mShmem;
-    mShmem = nullptr;
-  }
-}
-
-void
-ShmemTextureHost::OnShutdown()
+ShmemTextureHost::OnActorDestroy()
 {
   delete mShmem;
   mShmem = nullptr;
 }
 
 uint8_t* ShmemTextureHost::GetBuffer()
 {
   return mShmem ? mShmem->get<uint8_t>() : nullptr;
 }
 
-MemoryTextureHost::MemoryTextureHost(uint8_t* aBuffer,
+MemoryTextureHost::MemoryTextureHost(uint64_t aID,
+                                     uint8_t* aBuffer,
                                      gfx::SurfaceFormat aFormat,
                                      TextureFlags aFlags)
-: BufferTextureHost(aFormat, aFlags)
+: BufferTextureHost(aID, aFormat, aFlags)
 , mBuffer(aBuffer)
 {
   MOZ_COUNT_CTOR(MemoryTextureHost);
 }
 
 MemoryTextureHost::~MemoryTextureHost()
 {
   DeallocateDeviceData();
@@ -635,87 +559,15 @@ MemoryTextureHost::DeallocateSharedData(
 {
   if (mBuffer) {
     GfxMemoryImageReporter::WillFree(mBuffer);
   }
   delete[] mBuffer;
   mBuffer = nullptr;
 }
 
-void
-MemoryTextureHost::ForgetSharedData()
-{
-  mBuffer = nullptr;
-}
-
 uint8_t* MemoryTextureHost::GetBuffer()
 {
   return mBuffer;
 }
 
-TextureParent::TextureParent(ISurfaceAllocator* aAllocator)
-: mAllocator(aAllocator)
-{
-  MOZ_COUNT_CTOR(TextureParent);
-}
-
-TextureParent::~TextureParent()
-{
-  MOZ_COUNT_DTOR(TextureParent);
-  mTextureHost = nullptr;
-}
-
-bool
-TextureParent::RecvInit(const SurfaceDescriptor& aSharedData,
-                        const TextureFlags& aFlags)
-{
-  mTextureHost = TextureHost::Create(aSharedData,
-                                     mAllocator,
-                                     aFlags);
-  return !!mTextureHost;
-}
-
-bool
-TextureParent::RecvRemoveTexture()
-{
-  return PTextureParent::Send__delete__(this);
-}
-
-bool
-TextureParent::RecvRemoveTextureSync()
-{
-  // we don't need to send a reply in the synchronous case since the child side
-  // has the guarantee that this message has been handled synchronously.
-  return PTextureParent::Send__delete__(this);
-}
-
-void
-TextureParent::ActorDestroy(ActorDestroyReason why)
-{
-  if (!mTextureHost) {
-    return;
-  }
-
-  switch (why) {
-  case AncestorDeletion:
-    NS_WARNING("PTexture deleted after ancestor");
-    // fall-through to deletion path
-  case Deletion:
-    if (!(mTextureHost->GetFlags() & TEXTURE_DEALLOCATE_CLIENT) &&
-        !(mTextureHost->GetFlags() & TEXTURE_DEALLOCATE_DEFERRED)) {
-      mTextureHost->DeallocateSharedData();
-    }
-    break;
-
-  case NormalShutdown:
-  case AbnormalShutdown:
-    mTextureHost->OnShutdown();
-    break;
-
-  case FailedConstructor:
-    NS_RUNTIMEABORT("FailedConstructor isn't possible in PTexture");
-  }
-  mTextureHost->ForgetSharedData();
-  mTextureHost = nullptr;
-}
-
 } // namespace
 } // namespace
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -18,17 +18,16 @@
 #include "mozilla/layers/CompositorTypes.h"  // for TextureFlags, etc
 #include "mozilla/layers/LayersTypes.h"  // for LayerRenderState, etc
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 #include "nscore.h"                     // for nsACString
-#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
 
 class gfxImageSurface;
 class gfxReusableSurfaceWrapper;
 struct nsIntPoint;
 struct nsIntSize;
 struct nsIntRect;
 
 namespace mozilla {
@@ -42,19 +41,18 @@ class Compositor;
 class CompositableHost;
 class CompositableBackendSpecificData;
 class SurfaceDescriptor;
 class ISurfaceAllocator;
 class TextureSourceOGL;
 class TextureSourceD3D9;
 class TextureSourceD3D11;
 class TextureSourceBasic;
+class TextureParent;
 class DataTextureSource;
-class PTextureParent;
-class TextureParent;
 
 /**
  * A view on a TextureHost where the texture is internally represented as tiles
  * (contrast with a tiled buffer, where each texture is a tile). For iteration by
  * the texture's buffer host.
  * This is only useful when the underlying surface is too big to fit in one
  * device texture, which forces us to split it in smaller parts.
  * Tiled Compositable is a different thing.
@@ -254,38 +252,29 @@ private:
  * lifetime. This means that the lifetime of the underlying shared data
  * matches the lifetime of the TextureClient/Host pair. It also means
  * TextureClient/Host do not implement double buffering, which is the
  * reponsibility of the compositable (which would use two Texture pairs).
  *
  * The Lock/Unlock mecanism here mirrors Lock/Unlock in TextureClient.
  *
  */
-class TextureHost
-  : public AtomicRefCountedWithFinalize<TextureHost>
+class TextureHost : public RefCounted<TextureHost>
 {
-  /**
-   * Called once, just before the destructor.
-   *
-   * Here goes the shut-down code that uses virtual methods.
-   * Must only be called by Release().
-   */
-  void Finalize();
-
-  friend class AtomicRefCountedWithFinalize<TextureHost>;
-
 public:
-  TextureHost(TextureFlags aFlags);
+  TextureHost(uint64_t aID,
+              TextureFlags aFlags);
 
   virtual ~TextureHost();
 
   /**
    * Factory method.
    */
-  static TemporaryRef<TextureHost> Create(const SurfaceDescriptor& aDesc,
+  static TemporaryRef<TextureHost> Create(uint64_t aID,
+                                          const SurfaceDescriptor& aDesc,
                                           ISurfaceAllocator* aDeallocator,
                                           TextureFlags aFlags);
 
   /**
    * Lock the texture host for compositing.
    */
   virtual bool Lock() { return true; }
 
@@ -338,26 +327,38 @@ public:
 
   /**
    * Should be overridden in order to deallocate the data that is shared with
    * the content side, such as shared memory.
    */
   virtual void DeallocateSharedData() {}
 
   /**
-   * Should be overridden in order to force the TextureHost to drop all references
-   * to it's shared data.
+   * An ID to differentiate TextureHosts of a given CompositableHost.
    *
-   * This is important to ensure the correctness of the deallocation protocol.
+   * A TextureHost and its corresponding TextureClient always have the same ID.
+   * TextureHosts of a given CompositableHost always have different IDs.
+   * TextureHosts of different CompositableHosts, may have the same ID.
+   * Zero is always an invalid ID.
    */
-  virtual void ForgetSharedData() {}
+  uint64_t GetID() const { return mID; }
 
   virtual gfx::IntSize GetSize() const = 0;
 
   /**
+   * TextureHosts are kept as a linked list in their compositable
+   * XXX - This is just a poor man's PTexture. The purpose of this list is
+   * to keep TextureHost alive which should be independent from compositables.
+   * It will be removed when we add the PTetxure protocol (which will more
+   * gracefully handle the lifetime of textures). See bug 897452
+   */
+  TextureHost* GetNextSibling() const { return mNextTexture; }
+  void SetNextSibling(TextureHost* aNext) { mNextTexture = aNext; }
+
+  /**
    * Debug facility.
    * XXX - cool kids use Moz2D. See bug 882113.
    */
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() = 0;
 
   /**
    * XXX - Flags should only be set at creation time, this will be removed.
    */
@@ -366,57 +367,38 @@ public:
   /**
    * XXX - Flags should only be set at creation time, this will be removed.
    */
   void AddFlag(TextureFlags aFlag) { mFlags |= aFlag; }
 
   TextureFlags GetFlags() { return mFlags; }
 
   /**
-   * Allocate and deallocate a TextureParent actor.
-   *
-   * TextureParent< is an implementation detail of TextureHost that is not
-   * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
-   * are for use with the managing IPDL protocols only (so that they can
-   * implement AllocPTextureParent and DeallocPTextureParent).
-   */
-  static PTextureParent* CreateIPDLActor(ISurfaceAllocator* aAllocator);
-  static bool DestroyIPDLActor(PTextureParent* actor);
-
-  /**
-   * Destroy the TextureChild/Parent pair.
-   */
-  static bool SendDeleteIPDLActor(PTextureParent* actor);
-
-  /**
-   * Get the TextureHost corresponding to the actor passed in parameter.
-   */
-  static TextureHost* AsTextureHost(PTextureParent* actor);
-
-  /**
    * Specific to B2G's Composer2D
    * XXX - more doc here
    */
   virtual LayerRenderState GetRenderState()
   {
     // By default we return an empty render state, this should be overridden
     // by the TextureHost implementations that are used on B2G with Composer2D
     return LayerRenderState();
   }
 
   virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData);
 
   // If a texture host holds a reference to shmem, it should override this method
   // to forget about the shmem _without_ releasing it.
-  virtual void OnShutdown() {}
+  virtual void OnActorDestroy() {}
 
   virtual const char *Name() { return "TextureHost"; }
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
 
 protected:
+  uint64_t mID;
+  RefPtr<TextureHost> mNextTexture;
   TextureFlags mFlags;
   RefPtr<CompositableBackendSpecificData> mCompositableBackendData;
 };
 
 /**
  * TextureHost that wraps a random access buffer such as a Shmem or some raw
  * memory.
  *
@@ -427,17 +409,18 @@ protected:
  *
  * Uploads happen when Lock is called.
  *
  * BufferTextureHost supports YCbCr and flavours of RGBA images (RGBX, A, etc.).
  */
 class BufferTextureHost : public TextureHost
 {
 public:
-  BufferTextureHost(gfx::SurfaceFormat aFormat,
+  BufferTextureHost(uint64_t aID,
+                    gfx::SurfaceFormat aFormat,
                     TextureFlags aFlags);
 
   ~BufferTextureHost();
 
   virtual uint8_t* GetBuffer() = 0;
 
   virtual void Updated(const nsIntRegion* aRegion = nullptr) MOZ_OVERRIDE;
 
@@ -482,57 +465,55 @@ protected:
 /**
  * TextureHost that wraps shared memory.
  * the corresponding texture on the client side is ShmemTextureClient.
  * This TextureHost is backend-independent.
  */
 class ShmemTextureHost : public BufferTextureHost
 {
 public:
-  ShmemTextureHost(const mozilla::ipc::Shmem& aShmem,
+  ShmemTextureHost(uint64_t aID,
+                   const mozilla::ipc::Shmem& aShmem,
                    gfx::SurfaceFormat aFormat,
                    ISurfaceAllocator* aDeallocator,
                    TextureFlags aFlags);
 
   ~ShmemTextureHost();
 
   virtual void DeallocateSharedData() MOZ_OVERRIDE;
 
-  virtual void ForgetSharedData() MOZ_OVERRIDE;
-
   virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
 
   virtual const char *Name() MOZ_OVERRIDE { return "ShmemTextureHost"; }
 
-  virtual void OnShutdown() MOZ_OVERRIDE;
+  virtual void OnActorDestroy() MOZ_OVERRIDE;
 
 protected:
   mozilla::ipc::Shmem* mShmem;
   RefPtr<ISurfaceAllocator> mDeallocator;
 };
 
 /**
  * TextureHost that wraps raw memory.
  * The corresponding texture on the client side is MemoryTextureClient.
  * Can obviously not be used in a cross process setup.
  * This TextureHost is backend-independent.
  */
 class MemoryTextureHost : public BufferTextureHost
 {
 public:
-  MemoryTextureHost(uint8_t* aBuffer,
+  MemoryTextureHost(uint64_t aID,
+                    uint8_t* aBuffer,
                     gfx::SurfaceFormat aFormat,
                     TextureFlags aFlags);
 
   ~MemoryTextureHost();
 
   virtual void DeallocateSharedData() MOZ_OVERRIDE;
 
-  virtual void ForgetSharedData() MOZ_OVERRIDE;
-
   virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
 
   virtual const char *Name() MOZ_OVERRIDE { return "MemoryTextureHost"; }
 
 protected:
   uint8_t* mBuffer;
 };
 
@@ -725,17 +706,17 @@ public:
   // only made virtual to allow overriding in GrallocDeprecatedTextureHostOGL, for hacky fix in gecko 23 for bug 862324.
   // see bug 865908 about fixing this.
   virtual void SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator);
 
   // used only for hacky fix in gecko 23 for bug 862324
   // see bug 865908 about fixing this.
   virtual void ForgetBuffer() {}
 
-  void OnShutdown();
+  void OnActorDestroy();
 
 protected:
   /**
    * Should be implemented by the backend-specific DeprecatedTextureHost classes
    *
    * It should not take a reference to aImage, unless it knows the data
    * to be thread-safe.
    */
@@ -828,16 +809,17 @@ private:
   gfx::IntPoint mOrigin;
 };
 
 /**
  * Creates a TextureHost that can be used with any of the existing backends
  * Not all SurfaceDescriptor types are supported
  */
 TemporaryRef<TextureHost>
-CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
+CreateBackendIndependentTextureHost(uint64_t aID,
+                                    const SurfaceDescriptor& aDesc,
                                     ISurfaceAllocator* aDeallocator,
                                     TextureFlags aFlags);
 
 }
 }
 
 #endif
--- a/gfx/layers/composite/TiledContentHost.h
+++ b/gfx/layers/composite/TiledContentHost.h
@@ -114,16 +114,26 @@ public:
   // by the sum of the resolutions of all parent layers' FrameMetrics.
   const CSSToScreenScale& GetFrameResolution() { return mFrameResolution; }
 
   void SetCompositor(Compositor* aCompositor)
   {
     mCompositor = aCompositor;
   }
 
+  void OnActorDestroy()
+  {
+    Iterator end = TilesEnd();
+    for (Iterator it = TilesBegin(); it != end; ++it) {
+      if (it->mDeprecatedTextureHost) {
+        it->mDeprecatedTextureHost->OnActorDestroy();
+      }
+    }
+  }
+
 protected:
   TiledTexture ValidateTile(TiledTexture aTile,
                             const nsIntPoint& aTileRect,
                             const nsIntRegion& dirtyRect);
 
   // do nothing, the desctructor in the texture host takes care of releasing resources
   void ReleaseTile(TiledTexture aTile) {}
 
@@ -234,16 +244,22 @@ public:
     mVideoMemoryTiledBuffer.SetCompositor(aCompositor);
     mLowPrecisionVideoMemoryTiledBuffer.SetCompositor(aCompositor);
   }
 
   virtual void Attach(Layer* aLayer,
                       Compositor* aCompositor,
                       AttachFlags aFlags = NO_FLAGS) MOZ_OVERRIDE;
 
+  virtual void OnActorDestroy() MOZ_OVERRIDE
+  {
+    mVideoMemoryTiledBuffer.OnActorDestroy();
+    mLowPrecisionVideoMemoryTiledBuffer.OnActorDestroy();
+  }
+
 #ifdef MOZ_DUMP_PAINTING
   virtual void Dump(FILE* aFile=nullptr,
                     const char* aPrefix="",
                     bool aDumpHtml=false) MOZ_OVERRIDE;
 #endif
 
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
 
--- a/gfx/layers/ipc/CompositableForwarder.h
+++ b/gfx/layers/ipc/CompositableForwarder.h
@@ -24,18 +24,16 @@ namespace layers {
 class CompositableClient;
 class TextureFactoryIdentifier;
 class SurfaceDescriptor;
 class SurfaceDescriptorTiles;
 class ThebesBufferData;
 class DeprecatedTextureClient;
 class TextureClient;
 class BasicTiledLayerBuffer;
-class PTextureChild;
-class TextureClientData;
 
 /**
  * A transaction is a set of changes that happenned on the content side, that
  * 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
@@ -91,24 +89,16 @@ public:
    * that is TextureClient/Hosts.
    */
   virtual void DestroyThebesBuffer(CompositableClient* aCompositable) = 0;
 
   virtual void PaintedTiledLayerBuffer(CompositableClient* aCompositable,
                                        const SurfaceDescriptorTiles& aTiledDescriptor) = 0;
 
   /**
-   * Create an unitialized TextureChild.
-   *
-   * This does not trigger the the creation of a TextureHost on the compositor
-   * side (see PTexture::Init).
-   */
-  virtual PTextureChild* CreateEmptyTextureChild() = 0;
-
-  /**
    * Communicate to the compositor that the texture identified by aCompositable
    * and aTextureId has been updated to aImage.
    */
   virtual void UpdateTexture(CompositableClient* aCompositable,
                              TextureIdentifier aTextureId,
                              SurfaceDescriptor* aDescriptor) = 0;
 
   /**
@@ -155,20 +145,35 @@ public:
    * posted to the parent.  During the parent-side transaction, the
    * shadow is told to destroy its front buffer.  This can happen when
    * a new front/back buffer pair have been created because of a layer
    * resize, e.g.
    */
   virtual void DestroyedThebesBuffer(const SurfaceDescriptor& aBackBufferToDestroy) = 0;
 
   /**
-   * Tell the compositor side to delete the TextureHost corresponding to the
-   * TextureClient passed in parameter.
+   * Tell the compositor side to create a TextureHost that corresponds to
+   * aClient.
    */
-  virtual void RemoveTexture(TextureClient* aTexture) = 0;
+  virtual bool AddTexture(CompositableClient* aCompositable,
+                          TextureClient* aClient) = 0;
+
+  /**
+   * Tell the compositor side to delete the TextureHost corresponding to
+   * aTextureID.
+   * By default the shared Data is deallocated along with the TextureHost, but
+   * this behaviour can be overriden by the TextureFlags passed here.
+   * XXX - This is kind of bad, but for now we have to do this, because of some
+   * edge cases caused by the lifetime of the TextureHost being limited by the
+   * lifetime of the CompositableHost. We should be able to remove this flags
+   * parameter when we remove the lifetime constraint.
+   */
+  virtual void RemoveTexture(CompositableClient* aCompositable,
+                             uint64_t aTextureID,
+                             TextureFlags aFlags) = 0;
 
   /**
    * Tell the CompositableHost on the compositor side what texture to use for
    * the next composition.
    */
   virtual void UseTexture(CompositableClient* aCompositable,
                           TextureClient* aClient) = 0;
 
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp
+++ b/gfx/layers/ipc/CompositableTransactionParent.cpp
@@ -217,38 +217,100 @@ CompositableParentManager::ReceiveCompos
       NS_ASSERTION(tileComposer, "compositable is not a tile composer");
 
       const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor();
       tileComposer->PaintedTiledLayerBuffer(this, tileDesc);
       break;
     }
     case CompositableOperation::TOpUseTexture: {
       const OpUseTexture& op = aEdit.get_OpUseTexture();
+      if (op.textureID() == 0) {
+        NS_WARNING("Invalid texture ID");
+        break;
+      }
       CompositableHost* compositable = AsCompositable(op);
-      RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
+      RefPtr<TextureHost> tex = compositable->GetTextureHost(op.textureID());
 
       MOZ_ASSERT(tex.get());
       compositable->UseTextureHost(tex);
 
       if (IsAsync()) {
         ScheduleComposition(op);
       }
       break;
     }
+    case CompositableOperation::TOpAddTexture: {
+      const OpAddTexture& op = aEdit.get_OpAddTexture();
+      if (op.textureID() == 0) {
+        NS_WARNING("Invalid texture ID");
+        break;
+      }
+      CompositableHost* compositable = AsCompositable(op);
+      RefPtr<TextureHost> tex = TextureHost::Create(op.textureID(),
+                                                    op.data(),
+                                                    this,
+                                                    op.textureFlags());
+      MOZ_ASSERT(tex.get());
+      tex->SetCompositor(compositable->GetCompositor());
+      // set CompositableBackendSpecificData
+      // on gonk, create EGLImage if possible.
+      // create EGLImage during buffer swap could reduce the graphic driver's task
+      // during rendering.
+      compositable->AddTextureHost(tex);
+      MOZ_ASSERT(compositable->GetTextureHost(op.textureID()) == tex.get());
+      break;
+    }
+    case CompositableOperation::TOpRemoveTexture: {
+      const OpRemoveTexture& op = aEdit.get_OpRemoveTexture();
+      if (op.textureID() == 0) {
+        NS_WARNING("Invalid texture ID");
+        break;
+      }
+      CompositableHost* compositable = AsCompositable(op);
+
+      RefPtr<TextureHost> texture = compositable->GetTextureHost(op.textureID());
+      MOZ_ASSERT(texture);
+
+      TextureFlags flags = texture->GetFlags();
+
+      if (!(flags & TEXTURE_DEALLOCATE_CLIENT) &&
+          !(flags & TEXTURE_DEALLOCATE_DEFERRED)) {
+        texture->DeallocateSharedData();
+      }
+
+      compositable->RemoveTextureHost(texture);
+
+      // if it is not the host that deallocates the shared data, then we need
+      // to notfy the client side to tell when it is safe to deallocate or
+      // reuse it.
+      if (flags & TEXTURE_DEALLOCATE_CLIENT) {
+        replyv.push_back(ReplyTextureRemoved(op.compositableParent(), nullptr,
+                                             op.textureID()));
+      }
+
+      break;
+    }
     case CompositableOperation::TOpUpdateTexture: {
       const OpUpdateTexture& op = aEdit.get_OpUpdateTexture();
+      if (op.textureID() == 0) {
+        NS_WARNING("Invalid texture ID");
+        break;
+      }
       CompositableHost* compositable = AsCompositable(op);
       MOZ_ASSERT(compositable);
-      RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent());
+      RefPtr<TextureHost> texture = compositable->GetTextureHost(op.textureID());
       MOZ_ASSERT(texture);
 
       texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion
                        ? &op.region().get_nsIntRegion()
                        : nullptr); // no region means invalidate the entire surface
 
+
+      compositable->UseTextureHost(texture);
+
       break;
     }
 
     default: {
       MOZ_ASSERT(false, "bad type");
     }
   }
 
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -31,17 +31,16 @@
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsISupportsImpl.h"            // for ImageContainer::AddRef, etc
 #include "nsTArray.h"                   // for nsAutoTArray, nsTArray, etc
 #include "nsTArrayForwardDeclare.h"     // for AutoInfallibleTArray
 #include "nsThreadUtils.h"              // for NS_IsMainThread
 #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop
 #include "mozilla/StaticPtr.h"          // for StaticRefPtr
-#include "mozilla/layers/TextureClient.h"
 
 struct nsIntRect;
  
 using namespace base;
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace ipc {
@@ -99,33 +98,67 @@ struct CompositableTransaction
 };
 
 struct AutoEndTransaction {
   AutoEndTransaction(CompositableTransaction* aTxn) : mTxn(aTxn) {}
   ~AutoEndTransaction() { mTxn->End(); }
   CompositableTransaction* mTxn;
 };
 
+bool
+ImageBridgeChild::AddTexture(CompositableClient* aCompositable,
+                             TextureClient* aTexture)
+{
+  SurfaceDescriptor descriptor;
+  if (!aTexture->ToSurfaceDescriptor(descriptor)) {
+    NS_WARNING("ImageBridge: Failed to serialize a TextureClient");
+    return false;
+  }
+  mTxn->AddEdit(OpAddTexture(nullptr, aCompositable->GetIPDLActor(),
+                             aTexture->GetID(),
+                             descriptor,
+                             aTexture->GetFlags()));
+  return true;
+}
+
+void
+ImageBridgeChild::RemoveTexture(CompositableClient* aCompositable,
+                                uint64_t aTexture,
+                                TextureFlags aFlags)
+{
+  if (aFlags & TEXTURE_DEALLOCATE_CLIENT) {
+    // if deallocation happens on the host side, we need the transaction
+    // to be synchronous.
+    mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
+                                  aTexture,
+                                  aFlags));
+  } else {
+    mTxn->AddNoSwapEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
+                                        aTexture,
+                                        aFlags));
+  }
+}
+
 void
 ImageBridgeChild::UseTexture(CompositableClient* aCompositable,
                              TextureClient* aTexture)
 {
   mTxn->AddNoSwapEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(),
-                                   nullptr, aTexture->GetIPDLActor()));
+                                   aTexture->GetID()));
 }
 
 void
 ImageBridgeChild::UpdatedTexture(CompositableClient* aCompositable,
                                  TextureClient* aTexture,
                                  nsIntRegion* aRegion)
 {
   MaybeRegion region = aRegion ? MaybeRegion(*aRegion)
                                : MaybeRegion(null_t());
   mTxn->AddNoSwapEdit(OpUpdateTexture(nullptr, aCompositable->GetIPDLActor(),
-                                      nullptr, aTexture->GetIPDLActor(),
+                                      aTexture->GetID(),
                                       region));
 }
 
 void
 ImageBridgeChild::UpdateTexture(CompositableClient* aCompositable,
                                 TextureIdentifier aTextureId,
                                 SurfaceDescriptor* aDescriptor)
 {
@@ -427,16 +460,17 @@ void ImageBridgeChild::FlushAllImagesNow
   MOZ_ASSERT(aClient);
   sImageBridgeChildSingleton->BeginTransaction();
   if (aContainer && !aExceptFront) {
     aContainer->ClearCurrentImage();
   }
   aClient->FlushAllImages(aExceptFront);
   aClient->OnTransaction();
   sImageBridgeChildSingleton->EndTransaction();
+  aClient->FlushTexturesToRemoveCallbacks();
 }
 
 void
 ImageBridgeChild::BeginTransaction()
 {
   MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?");
   mTxn->Begin();
 }
@@ -484,16 +518,28 @@ ImageBridgeChild::EndTransaction()
           static_cast<CompositableChild*>(ots.compositableChild());
 
       MOZ_ASSERT(compositableChild);
 
       compositableChild->GetCompositableClient()
         ->SetDescriptorFromReply(ots.textureId(), ots.image());
       break;
     }
+    case EditReply::TReplyTextureRemoved: {
+      // We receive this reply when a Texture is removed and when it is not
+      // the responsibility of the compositor side to deallocate memory.
+      // This would be, for instance, the place to implement a mechanism to
+      // notify the B2G camera that the gralloc buffer is not used by the
+      // compositor anymore and that it can be recycled.
+      const ReplyTextureRemoved& rep = reply.get_ReplyTextureRemoved();
+      CompositableClient* compositable
+        = static_cast<CompositableChild*>(rep.compositableChild())->GetCompositableClient();
+      compositable->OnReplyTextureRemoved(rep.textureId());
+      break;
+    }
     default:
       NS_RUNTIMEABORT("not reached");
     }
   }
 }
 
 
 PImageBridgeChild*
@@ -889,59 +935,10 @@ ImageBridgeChild::AllocGrallocBuffer(con
                                        aUsage,
                                        aHandle);
 #else
   NS_RUNTIMEABORT("not implemented");
   return nullptr;
 #endif
 }
 
-PTextureChild*
-ImageBridgeChild::AllocPTextureChild()
-{
-  return TextureClient::CreateIPDLActor();
-}
-
-bool
-ImageBridgeChild::DeallocPTextureChild(PTextureChild* actor)
-{
-  return TextureClient::DestroyIPDLActor(actor);
-}
-
-PTextureChild*
-ImageBridgeChild::CreateEmptyTextureChild()
-{
-  return SendPTextureConstructor();
-}
-
-static void RemoveTextureSync(TextureClient* aTexture, ReentrantMonitor* aBarrier, bool* aDone)
-{
-  aTexture->ForceRemove();
-
-  ReentrantMonitorAutoEnter autoMon(*aBarrier);
-  *aDone = true;
-  aBarrier->NotifyAll();
-}
-
-void ImageBridgeChild::RemoveTexture(TextureClient* aTexture)
-{
-  if (InImageBridgeChildThread()) {
-    aTexture->ForceRemove();
-    return;
-  }
-
-  ReentrantMonitor barrier("RemoveTexture Lock");
-  ReentrantMonitorAutoEnter autoMon(barrier);
-  bool done = false;
-
-  sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
-    NewRunnableFunction(&RemoveTextureSync, aTexture, &barrier, &done));
-
-  // should stop the thread until the ImageClient has been created on
-  // the other thread
-  while (!done) {
-    barrier.Wait();
-  }
-}
-
 } // layers
 } // mozilla
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -190,22 +190,16 @@ public:
 
   virtual PGrallocBufferChild*
   AllocPGrallocBufferChild(const gfxIntSize&, const uint32_t&, const uint32_t&,
                            MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE;
 
   virtual bool
   DeallocPGrallocBufferChild(PGrallocBufferChild* actor) MOZ_OVERRIDE;
 
-  virtual PTextureChild*
-  AllocPTextureChild() MOZ_OVERRIDE;
-
-  virtual bool
-  DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
-
   /**
    * Allocate a gralloc SurfaceDescriptor remotely.
    */
   bool
   AllocSurfaceDescriptorGralloc(const gfxIntSize& aSize,
                                 const uint32_t& aFormat,
                                 const uint32_t& aUsage,
                                 SurfaceDescriptor* aBuffer);
@@ -256,30 +250,41 @@ public:
    */
   static void FlushAllImagesNow(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront);
 
   // CompositableForwarder
 
   virtual void Connect(CompositableClient* aCompositable) MOZ_OVERRIDE;
 
   /**
+   * See CompositableForwarder::AddTexture
+   */
+  virtual bool AddTexture(CompositableClient* aCompositable,
+                          TextureClient* aClient) MOZ_OVERRIDE;
+
+  /**
+   * See CompositableForwarder::RemoveTexture
+   */
+  virtual void RemoveTexture(CompositableClient* aCompositable,
+                             uint64_t aTextureID,
+                             TextureFlags aFlags) MOZ_OVERRIDE;
+
+  /**
    * See CompositableForwarder::UpdatedTexture
    */
   virtual void UpdatedTexture(CompositableClient* aCompositable,
                               TextureClient* aTexture,
                               nsIntRegion* aRegion) MOZ_OVERRIDE;
 
   /**
    * See CompositableForwarder::UseTexture
    */
   virtual void UseTexture(CompositableClient* aCompositable,
                           TextureClient* aClient) MOZ_OVERRIDE;
 
-  virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE;
-
   virtual void PaintedTiledLayerBuffer(CompositableClient* aCompositable,
                                        const SurfaceDescriptorTiles& aTileLayerDescriptor) MOZ_OVERRIDE
   {
     NS_RUNTIMEABORT("should not be called");
   }
 
   /**
    * Communicate to the compositor that the texture identified by aCompositable
@@ -368,18 +373,16 @@ public:
   /**
    * See ISurfaceAllocator.h
    * Can be used from any thread.
    * If used outside the ImageBridgeChild thread, it will proxy a synchronous
    * call on the ImageBridgeChild thread.
    */
   virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem);
 
-  virtual PTextureChild* CreateEmptyTextureChild() MOZ_OVERRIDE;
-
 protected:
   ImageBridgeChild();
   bool DispatchAllocShmemInternal(size_t aSize,
                                   SharedMemory::SharedMemoryType aType,
                                   Shmem* aShmem,
                                   bool aUnsafe);
 
   CompositableTransaction* mTxn;
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -25,17 +25,16 @@
 #include "mozilla/layers/Compositor.h"
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT, etc
 #include "nsISupportsImpl.h"            // for ImageBridgeParent::Release, etc
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
 #include "nsTArrayForwardDeclare.h"     // for InfallibleTArray
 #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop
-#include "mozilla/layers/TextureHost.h"
 
 using namespace base;
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace layers {
 
 class PGrallocBufferParent;
@@ -123,26 +122,16 @@ ImageBridgeParent::Create(Transport* aTr
   loop->PostTask(FROM_HERE,
                  NewRunnableFunction(ConnectImageBridgeInParentProcess,
                                      bridge.get(), aTransport, processHandle));
   return bridge.get();
 }
 
 bool ImageBridgeParent::RecvStop()
 {
-  // If there is any texture still alive we have to force it to deallocate the
-  // device data (GL textures, etc.) now because shortly after SenStop() returns
-  // on the child side the widget will be destroyed along with it's associated
-  // GL context.
-  InfallibleTArray<PTextureParent*> textures;
-  ManagedPTextureParent(textures);
-  for (unsigned int i = 0; i < textures.Length(); ++i) {
-    RefPtr<TextureHost> tex = TextureHost::AsTextureHost(textures[i]);
-    tex->DeallocateDeviceData();
-  }
   return true;
 }
 
 static  uint64_t GenImageContainerID() {
   static uint64_t sNextImageID = 1;
 
   ++sNextImageID;
   return sNextImageID;
@@ -184,28 +173,16 @@ ImageBridgeParent::AllocPCompositablePar
 }
 
 bool ImageBridgeParent::DeallocPCompositableParent(PCompositableParent* aActor)
 {
   delete aActor;
   return true;
 }
 
-PTextureParent*
-ImageBridgeParent::AllocPTextureParent()
-{
-  return TextureHost::CreateIPDLActor(this);
-}
-
-bool
-ImageBridgeParent::DeallocPTextureParent(PTextureParent* actor)
-{
-  return TextureHost::DestroyIPDLActor(actor);
-}
-
 MessageLoop * ImageBridgeParent::GetMessageLoop() {
   return mMessageLoop;
 }
 
 void
 ImageBridgeParent::DeferredDestroy()
 {
   mSelfRef = nullptr;
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -60,19 +60,16 @@ public:
   virtual bool RecvUpdateNoSwap(const EditArray& aEdits);
 
   virtual bool IsAsync() const MOZ_OVERRIDE { return true; }
 
   PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo,
                                                 uint64_t*) MOZ_OVERRIDE;
   bool DeallocPCompositableParent(PCompositableParent* aActor) MOZ_OVERRIDE;
 
-  virtual PTextureParent* AllocPTextureParent() MOZ_OVERRIDE;
-  virtual bool DeallocPTextureParent(PTextureParent* actor) MOZ_OVERRIDE;
-
   bool RecvStop() MOZ_OVERRIDE;
 
   MessageLoop * GetMessageLoop();
 
 
   // ISurfaceAllocator
 
   bool AllocShmem(size_t aSize,
--- a/gfx/layers/ipc/LayerTransactionChild.cpp
+++ b/gfx/layers/ipc/LayerTransactionChild.cpp
@@ -8,17 +8,16 @@
 #include "LayerTransactionChild.h"
 #include "mozilla/layers/CompositableClient.h"  // for CompositableChild
 #include "mozilla/layers/LayersSurfaces.h"  // for PGrallocBufferChild
 #include "mozilla/layers/PCompositableChild.h"  // for PCompositableChild
 #include "mozilla/layers/PLayerChild.h"  // for PLayerChild
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT, etc
 #include "nsTArray.h"                   // for nsTArray
-#include "mozilla/layers/TextureClient.h"
 
 namespace mozilla {
 namespace layers {
 
 class PGrallocBufferChild;
 
 void
 LayerTransactionChild::Destroy()
@@ -92,22 +91,10 @@ LayerTransactionChild::ActorDestroy(Acto
   // shutdown. Its better just to crash here. On desktop though, we have a chance
   // of recovering.
   if (why == AbnormalShutdown) {
     NS_RUNTIMEABORT("ActorDestroy by IPC channel failure at LayerTransactionChild");
   }
 #endif
 }
 
-PTextureChild*
-LayerTransactionChild::AllocPTextureChild()
-{
-  return TextureClient::CreateIPDLActor();
-}
-
-bool
-LayerTransactionChild::DeallocPTextureChild(PTextureChild* actor)
-{
-  return TextureClient::DestroyIPDLActor(actor);
-}
-
 }  // namespace layers
 }  // namespace mozilla
--- a/gfx/layers/ipc/LayerTransactionChild.h
+++ b/gfx/layers/ipc/LayerTransactionChild.h
@@ -53,20 +53,16 @@ protected:
   virtual bool
   DeallocPGrallocBufferChild(PGrallocBufferChild* actor) MOZ_OVERRIDE;
 
   virtual PLayerChild* AllocPLayerChild() MOZ_OVERRIDE;
   virtual bool DeallocPLayerChild(PLayerChild* actor) MOZ_OVERRIDE;
 
   virtual PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo) MOZ_OVERRIDE;
   virtual bool DeallocPCompositableChild(PCompositableChild* actor) MOZ_OVERRIDE;
-
-  virtual PTextureChild* AllocPTextureChild() MOZ_OVERRIDE;
-  virtual bool DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
-
   virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
   void AddIPDLReference() {
     MOZ_ASSERT(mIPCOpen == false);
     mIPCOpen = true;
     AddRef();
   }
   void ReleaseIPDLReference() {
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -34,17 +34,16 @@
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsISupportsImpl.h"            // for Layer::Release, etc
 #include "nsLayoutUtils.h"              // for nsLayoutUtils
 #include "nsMathUtils.h"                // for NS_round
 #include "nsPoint.h"                    // for nsPoint
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl, etc
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 #include "GeckoProfiler.h"
-#include "mozilla/layers/TextureHost.h"
 
 typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
 
 using mozilla::layout::RenderFrameParent;
 
 namespace mozilla {
 namespace layers {
 
@@ -596,22 +595,10 @@ LayerTransactionParent::AllocPCompositab
 
 bool
 LayerTransactionParent::DeallocPCompositableParent(PCompositableParent* actor)
 {
   delete actor;
   return true;
 }
 
-PTextureParent*
-LayerTransactionParent::AllocPTextureParent()
-{
-  return TextureHost::CreateIPDLActor(this);
-}
-
-bool
-LayerTransactionParent::DeallocPTextureParent(PTextureParent* actor)
-{
-  return TextureHost::DestroyIPDLActor(actor);
-}
-
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -101,19 +101,16 @@ protected:
   DeallocPGrallocBufferParent(PGrallocBufferParent* actor) MOZ_OVERRIDE;
 
   virtual PLayerParent* AllocPLayerParent() MOZ_OVERRIDE;
   virtual bool DeallocPLayerParent(PLayerParent* actor) MOZ_OVERRIDE;
 
   virtual PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo) MOZ_OVERRIDE;
   virtual bool DeallocPCompositableParent(PCompositableParent* actor) MOZ_OVERRIDE;
 
-  virtual PTextureParent* AllocPTextureParent() MOZ_OVERRIDE;
-  virtual bool DeallocPTextureParent(PTextureParent* actor) MOZ_OVERRIDE;
-
   void Attach(ShadowLayerParent* aLayerParent,
               CompositableParent* aCompositable,
               bool aIsAsyncVideo);
 
   void AddIPDLReference() {
     MOZ_ASSERT(mIPCOpen == false);
     mIPCOpen = true;
     AddRef();
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -6,17 +6,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include LayersSurfaces;
 include protocol PCompositable;
 include protocol PCompositor;
 include protocol PGrallocBuffer;
 include protocol PLayer;
 include protocol PRenderFrame;
-include protocol PTexture;
 
 include "gfxipc/ShadowLayerUtils.h";
 include "mozilla/GfxMessageUtils.h";
 include "ImageLayers.h";
 
 using mozilla::GraphicsFilterType from "mozilla/GfxMessageUtils.h";
 using struct gfxRGBA from "gfxColor.h";
 using struct gfxPoint3D from "gfxPoint3D.h";
@@ -297,48 +296,71 @@ struct OpPaintTextureIncremental {
 };
 
 struct OpUpdatePictureRect {
   PCompositable compositable;
   nsIntRect picture;
 };
 
 /**
+ * Provides the compositor side with enough information to create a
+ * TextureHost.
+ */
+struct OpAddTexture {
+  PCompositable compositable;
+  uint64_t textureID;
+  SurfaceDescriptor data;
+  uint32_t textureFlags;
+};
+
+/**
+ * Tells the compositor-side to remove the corresponding TextureHost and
+ * deallocate its data.
+ */
+struct OpRemoveTexture {
+  PCompositable compositable;
+  uint64_t textureID;
+  uint32_t flags;
+};
+
+/**
  * Tells the compositor-side which texture to use (for example, as front buffer
  * if there is several textures for double buffering)
  */
 struct OpUseTexture {
   PCompositable compositable;
-  PTexture texture;
+  uint64_t textureID;
 };
 
 union MaybeRegion {
   nsIntRegion;
   null_t;
 };
 
 struct OpUpdateTexture {
   PCompositable compositable;
-  PTexture texture;
+  uint64_t textureID;
   MaybeRegion region;
 };
 
 union CompositableOperation {
   OpUpdatePictureRect;
 
   OpCreatedTexture;
   OpCreatedIncrementalTexture;
   OpDestroyThebesBuffer;
 
   OpPaintTexture;
   OpPaintTextureRegion;
   OpPaintTextureIncremental;
 
   OpPaintTiledLayerBuffer;
 
+  OpAddTexture;
+  OpRemoveTexture;
   OpUpdateTexture;
   OpUseTexture;
 };
 
 // A unit of a changeset; a set of these comprise a changeset
 union Edit {
   OpCreateThebesLayer;
   OpCreateContainerLayer;
@@ -372,17 +394,24 @@ struct OpContentBufferSwap {
 };
 
 struct OpTextureSwap {
   PCompositable compositable;
   uint32_t textureId;
   SurfaceDescriptor image;
 };
 
+struct ReplyTextureRemoved {
+  PCompositable compositable;
+  uint64_t textureId;
+};
+
 // Unit of a "changeset reply".  This is a weird abstraction, probably
 // only to be used for buffer swapping.
 union EditReply {
   OpContentBufferSwap;
   OpTextureSwap;
+
+  ReplyTextureRemoved;
 };
 
 } // namespace
 } // namespace
--- a/gfx/layers/ipc/PImageBridge.ipdl
+++ b/gfx/layers/ipc/PImageBridge.ipdl
@@ -2,17 +2,16 @@
  * 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 LayersSurfaces;
 include LayersMessages;
 include protocol PGrallocBuffer;
 include protocol PCompositable;
-include protocol PTexture;
 include ProtocolTypes;
 
 include "mozilla/GfxMessageUtils.h";
 
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 
 namespace mozilla {
 namespace layers {
@@ -21,17 +20,16 @@ namespace layers {
  * The PImageBridge protocol is used to allow isolated threads or processes to push
  * frames directly to the compositor thread/process without relying on the main thread
  * which might be too busy dealing with content script.
  */
 intr protocol PImageBridge
 {
   manages PCompositable;
   manages PGrallocBuffer;
-  manages PTexture;
 
 parent:
 
   sync Update(CompositableOperation[] ops) returns (EditReply[] reply);
   async UpdateNoSwap(CompositableOperation[] ops);
 
   // Allocates a gralloc buffer that may not suitable to use with
   // gfxImageSurface but allows hardware decoder to write to the
@@ -46,15 +44,14 @@ parent:
   // counterpart so as to not race with the upcomming __delete__ message.
   // In the child side, the __delete__ messages are not sent right after Stop,
   // they are scheduled in the ImageBridgeChild's message queue in order to ensure
   // that all the messages from the parent side have been received and processed
   // before sending __delete__.
   sync Stop();
 
   sync PCompositable(TextureInfo aInfo) returns (uint64_t id);
-  async PTexture();
 };
 
 
 } // namespace
 } // namespace
 
--- a/gfx/layers/ipc/PLayerTransaction.ipdl
+++ b/gfx/layers/ipc/PLayerTransaction.ipdl
@@ -7,17 +7,16 @@
 
 include LayersSurfaces;
 include LayersMessages;
 include protocol PCompositable;
 include protocol PCompositor;
 include protocol PGrallocBuffer;
 include protocol PLayer;
 include protocol PRenderFrame;
-include protocol PTexture;
 
 include "mozilla/GfxMessageUtils.h";
 
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 
 /**
  * The layers protocol is spoken between thread contexts that manage
  * layer (sub)trees.  The protocol comprises atomically publishing
@@ -29,17 +28,16 @@ using struct mozilla::layers::TextureInf
 namespace mozilla {
 namespace layers {
 
 sync protocol PLayerTransaction {
   manager PRenderFrame or PCompositor;
   manages PLayer;
   manages PCompositable;
   manages PGrallocBuffer;
-  manages PTexture;
 
 parent:
   /**
    * Only the parent side has privileges to allocate the buffer.
    * Allocation may fail (pmem is a scarce resource), and if so null_t
    * is returned.
    *
    * |format| is an Android PixelFormat (see PixelFormat.h)
@@ -63,17 +61,16 @@ parent:
    *   USAGE_HW_RENDER | USAGE_HW_TEXTURE
    *     - used for GL rendering to a buffer which the compositor
    *       treats as a texture
    */
   sync PGrallocBuffer(gfxIntSize size, uint32_t format, uint32_t usage)
     returns (MaybeMagicGrallocBufferHandle handle);
   async PLayer();
   async PCompositable(TextureInfo aTextureInfo);
-  async PTexture();
 
   // The isFirstPaint flag can be used to indicate that this is the first update
   // for a particular document.
   sync Update(Edit[] cset, TargetConfig targetConfig, bool isFirstPaint)
     returns (EditReply[] reply);
 
   sync GetOpacity(PLayer layer) returns (float opacity);
   sync GetTransform(PLayer layer) returns (gfx3DMatrix transform);
deleted file mode 100644
--- a/gfx/layers/ipc/PTexture.ipdl
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- */
-/* 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 LayersSurfaces;
-include protocol PLayerTransaction;
-include protocol PImageBridge;
-include protocol PGrallocBuffer;
-include "mozilla/GfxMessageUtils.h";
-
-using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
-
-namespace mozilla {
-namespace layers {
-
-/**
- * PTexture is the IPDL glue between a TextureClient and a TextureHost.
- */
-sync protocol PTexture {
-    manager PImageBridge or PLayerTransaction;
-
-child:
-    async __delete__();
-
-parent:
-    /**
-     * Set the shared data and create the TextureHost on the parent side.
-     */
-    async Init(SurfaceDescriptor aSharedData, uint32_t aTextureFlags);
-
-    /**
-     * Asynchronously tell the Compositor side to remove the texture.
-     */
-    async RemoveTexture();
-
-    /**
-     * Synchronously tell the compositor side to remove the texture.
-     */
-    sync RemoveTextureSync();
-};
-
-} // layers
-} // mozilla
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
@@ -8,17 +8,16 @@
 #include "mozilla/DebugOnly.h"
 
 #include "mozilla/layers/PGrallocBufferChild.h"
 #include "mozilla/layers/PGrallocBufferParent.h"
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/CompositorTypes.h"
-#include "mozilla/layers/TextureHost.h"
 #include "mozilla/unused.h"
 #include "nsXULAppAPI.h"
 
 #include "ShadowLayerUtilsGralloc.h"
 
 #include "nsIMemoryReporter.h"
 
 #include "gfxImageSurface.h"
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.h
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.h
@@ -10,28 +10,30 @@
 
 #include <unistd.h>
 #include <ui/GraphicBuffer.h>
 
 #include "ipc/IPCMessageUtils.h"
 #include "mozilla/layers/PGrallocBufferChild.h"
 #include "mozilla/layers/PGrallocBufferParent.h"
 
+// used only for hacky fix in gecko 23 for bug 862324
+// see bug 865908 about fixing this.
+#include "TextureHost.h"
+
 #define MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
 #define MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
 
 class gfxASurface;
 
 namespace mozilla {
 namespace layers {
 
 class MaybeMagicGrallocBufferHandle;
 class SurfaceDescriptorGralloc;
-class TextureHost;
-class DeprecatedTextureHost;
 
 /**
  * This class exists to share the underlying GraphicBuffer resources
  * from one thread context to another.  This requires going through
  * slow paths in the kernel so can be somewhat expensive.
  *
  * This is not just platform-specific, but also
  * gralloc-implementation-specific.
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -402,46 +402,73 @@ ShadowLayerForwarder::UpdateTextureIncre
 
 void
 ShadowLayerForwarder::UpdatePictureRect(CompositableClient* aCompositable,
                                         const nsIntRect& aRect)
 {
   mTxn->AddNoSwapPaint(OpUpdatePictureRect(nullptr, aCompositable->GetIPDLActor(), aRect));
 }
 
+bool
+ShadowLayerForwarder::AddTexture(CompositableClient* aCompositable,
+                                 TextureClient* aTexture)
+{
+  SurfaceDescriptor descriptor;
+  if (!aTexture->ToSurfaceDescriptor(descriptor)) {
+    NS_WARNING("Failed to serialize a TextureClient");
+    return false;
+  }
+  CheckSurfaceDescriptor(&descriptor);
+  MOZ_ASSERT(aCompositable);
+  MOZ_ASSERT(aCompositable->GetIPDLActor());
+  MOZ_ASSERT(aTexture->GetFlags() != 0);
+  mTxn->AddEdit(OpAddTexture(nullptr, aCompositable->GetIPDLActor(),
+                             aTexture->GetID(),
+                             descriptor,
+                             aTexture->GetFlags()));
+  return true;
+}
+
+void
+ShadowLayerForwarder::RemoveTexture(CompositableClient* aCompositable,
+                                    uint64_t aTexture,
+                                    TextureFlags aFlags)
+{
+  mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
+                                aTexture,
+                                aFlags));
+  if (aFlags & TEXTURE_DEALLOCATE_CLIENT) {
+    mTxn->MarkSyncTransaction();
+  }
+}
+
 void
 ShadowLayerForwarder::UpdatedTexture(CompositableClient* aCompositable,
                                      TextureClient* aTexture,
                                      nsIntRegion* aRegion)
 {
   MaybeRegion region = aRegion ? MaybeRegion(*aRegion)
                                : MaybeRegion(null_t());
   if (aTexture->GetFlags() & TEXTURE_IMMEDIATE_UPLOAD) {
     mTxn->AddPaint(OpUpdateTexture(nullptr, aCompositable->GetIPDLActor(),
-                                   nullptr, aTexture->GetIPDLActor(),
+                                   aTexture->GetID(),
                                    region));
   } else {
     mTxn->AddNoSwapPaint(OpUpdateTexture(nullptr, aCompositable->GetIPDLActor(),
-                                         nullptr, aTexture->GetIPDLActor(),
+                                         aTexture->GetID(),
                                          region));
   }
 }
 
 void
 ShadowLayerForwarder::UseTexture(CompositableClient* aCompositable,
                                  TextureClient* aTexture)
 {
   mTxn->AddEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(),
-                             nullptr, aTexture->GetIPDLActor()));
-}
-
-void
-ShadowLayerForwarder::RemoveTexture(TextureClient* aTexture)
-{
-  aTexture->ForceRemove();
+                             aTexture->GetID()));
 }
 
 bool
 ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies, bool* aSent)
 {
   *aSent = false;
 
   PROFILER_LABEL("ShadowLayerForwarder", "EndTranscation");
@@ -957,23 +984,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));
 }
 
-PTextureChild*
-ShadowLayerForwarder::CreateEmptyTextureChild()
-{
-  return mShadowManager->SendPTextureConstructor();
-}
-
-
 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
@@ -144,18 +144,16 @@ public:
   virtual ~ShadowLayerForwarder();
 
   /**
    * Setup the IPDL actor for aCompositable to be part of layers
    * transactions.
    */
   void Connect(CompositableClient* aCompositable);
 
-  virtual PTextureChild* CreateEmptyTextureChild() MOZ_OVERRIDE;
-
   virtual void CreatedSingleBuffer(CompositableClient* aCompositable,
                                    const SurfaceDescriptor& aDescriptor,
                                    const TextureInfo& aTextureInfo,
                                    const SurfaceDescriptor* aDescriptorOnWhite = nullptr) MOZ_OVERRIDE;
   virtual void CreatedIncrementalBuffer(CompositableClient* aCompositable,
                                         const TextureInfo& aTextureInfo,
                                         const nsIntRect& aBufferRect) MOZ_OVERRIDE;
   virtual void CreatedDoubleBuffer(CompositableClient* aCompositable,
@@ -274,18 +272,16 @@ public:
   /**
    * Communicate to the compositor that the texture identified by aLayer
    * and aIdentifier has been updated to aImage.
    */
   virtual void UpdateTexture(CompositableClient* aCompositable,
                              TextureIdentifier aTextureId,
                              SurfaceDescriptor* aDescriptor) MOZ_OVERRIDE;
 
-  virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE;
-
   /**
    * Same as above, but performs an asynchronous layer transaction
    */
   virtual void UpdateTextureNoSwap(CompositableClient* aCompositable,
                                    TextureIdentifier aTextureId,
                                    SurfaceDescriptor* aDescriptor) MOZ_OVERRIDE;
 
   /**
@@ -305,16 +301,29 @@ public:
 
   /**
    * Communicate the picture rect of an image to the compositor
    */
   void UpdatePictureRect(CompositableClient* aCompositable,
                          const nsIntRect& aRect);
 
   /**
+   * See CompositableForwarder::AddTexture
+   */
+  virtual bool AddTexture(CompositableClient* aCompositable,
+                          TextureClient* aClient) MOZ_OVERRIDE;
+
+  /**
+   * See CompositableForwarder::RemoveTexture
+   */
+  virtual void RemoveTexture(CompositableClient* aCompositable,
+                             uint64_t aTextureID,
+                             TextureFlags aFlags) MOZ_OVERRIDE;
+
+  /**
    * See CompositableForwarder::UpdatedTexture
    */
   virtual void UpdatedTexture(CompositableClient* aCompositable,
                               TextureClient* aTexture,
                               nsIntRegion* aRegion) MOZ_OVERRIDE;
 
   /**
    * See CompositableForwarder::UseTexture
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -93,17 +93,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
             'd3d11/CompositorD3D11.cpp',
         ]
 
 EXPORTS.gfxipc += [
     'ipc/ShadowLayerUtils.h',
 ]
 
 EXPORTS.mozilla.layers += [
-    'AtomicRefCountedWithFinalize.h',
     'basic/BasicCompositor.h',
     'basic/MacIOSurfaceTextureHostBasic.h',
     'basic/TextureHostBasic.h',
     'client/CanvasClient.h',
     'client/CompositableClient.h',
     'client/ContentClient.h',
     'client/ImageClient.h',
     'client/TextureClient.h',
@@ -286,17 +285,16 @@ IPDL_SOURCES = [
     'ipc/LayersMessages.ipdlh',
     'ipc/LayersSurfaces.ipdlh',
     'ipc/PCompositable.ipdl',
     'ipc/PCompositor.ipdl',
     'ipc/PGrallocBuffer.ipdl',
     'ipc/PImageBridge.ipdl',
     'ipc/PLayer.ipdl',
     'ipc/PLayerTransaction.ipdl',
-    'ipc/PTexture.ipdl',
 ]
 
 MSVC_ENABLE_PGO = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'thebes'
 
--- a/gfx/layers/opengl/GrallocTextureHost.cpp
+++ b/gfx/layers/opengl/GrallocTextureHost.cpp
@@ -90,17 +90,16 @@ TextureTargetForAndroidPixelFormat(andro
 
 GrallocTextureSourceOGL::GrallocTextureSourceOGL(CompositorOGL* aCompositor,
                                                  android::GraphicBuffer* aGraphicBuffer,
                                                  gfx::SurfaceFormat aFormat)
   : mCompositor(aCompositor)
   , mGraphicBuffer(aGraphicBuffer)
   , mEGLImage(0)
   , mFormat(aFormat)
-  , mNeedsReset(true)
 {
   MOZ_ASSERT(mGraphicBuffer.get());
 }
 
 GrallocTextureSourceOGL::~GrallocTextureSourceOGL()
 {
   DeallocateDeviceData();
   mCompositor = nullptr;
@@ -165,24 +164,16 @@ GrallocTextureSourceOGL::GetFormat() con
     return gfx::FORMAT_R8G8B8A8;
   }
   return mFormat;
 }
 
 void
 GrallocTextureSourceOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
 {
-  if (mCompositableBackendData != aBackendData) {
-    mNeedsReset = true;
-  }
-
-  if (!mNeedsReset) {
-    return;
-  }
-
   mCompositableBackendData = aBackendData;
 
   if (!mCompositor) {
     return;
   }
 
   // delete old EGLImage
   DeallocateDeviceData();
@@ -191,17 +182,16 @@ GrallocTextureSourceOGL::SetCompositable
   GLuint tex = GetGLTexture();
   GLuint textureTarget = GetTextureTarget();
 
   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
   gl()->fBindTexture(textureTarget, tex);
   // create new EGLImage
   mEGLImage = gl()->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
   gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
-  mNeedsReset = false;
 }
 
 gfx::IntSize
 GrallocTextureSourceOGL::GetSize() const
 {
   if (!IsValid()) {
     NS_WARNING("Trying to access the size of an invalid GrallocTextureSourceOGL");
     return gfx::IntSize(0, 0);
@@ -215,19 +205,20 @@ GrallocTextureSourceOGL::DeallocateDevic
   if (mEGLImage) {
     MOZ_ASSERT(gl());
     gl()->MakeCurrent();
     gl()->DestroyEGLImage(mEGLImage);
     mEGLImage = 0;
   }
 }
 
-GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
+GrallocTextureHostOGL::GrallocTextureHostOGL(uint64_t aID,
+                                             TextureFlags aFlags,
                                              const NewSurfaceDescriptorGralloc& aDescriptor)
-  : TextureHost(aFlags)
+  : TextureHost(aID, aFlags)
 {
   mGrallocActor =
     static_cast<GrallocBufferActor*>(aDescriptor.bufferParent());
 
   android::GraphicBuffer* graphicBuffer = mGrallocActor->GetGraphicBuffer();
 
   mSize = aDescriptor.size();
   gfx::SurfaceFormat format =
@@ -278,24 +269,16 @@ GrallocTextureHostOGL::DeallocateSharedD
 {
   if (mTextureSource) {
     mTextureSource->ForgetBuffer();
   }
   PGrallocBufferParent::Send__delete__(mGrallocActor);
 }
 
 void
-GrallocTextureHostOGL::ForgetSharedData()
-{
-  if (mTextureSource) {
-    mTextureSource->ForgetBuffer();
-  }
-}
-
-void
 GrallocTextureHostOGL::DeallocateDeviceData()
 {
   mTextureSource->DeallocateDeviceData();
 }
 
 LayerRenderState
 GrallocTextureHostOGL::GetRenderState()
 {
--- a/gfx/layers/opengl/GrallocTextureHost.h
+++ b/gfx/layers/opengl/GrallocTextureHost.h
@@ -64,40 +64,38 @@ public:
 
   GLuint GetGLTexture();
 
 protected:
   CompositorOGL* mCompositor;
   android::sp<android::GraphicBuffer> mGraphicBuffer;
   EGLImage mEGLImage;
   gfx::SurfaceFormat mFormat;
-  bool mNeedsReset;
 };
 
 class GrallocTextureHostOGL : public TextureHost
 {
   friend class GrallocBufferActor;
 public:
-  GrallocTextureHostOGL(TextureFlags aFlags,
+  GrallocTextureHostOGL(uint64_t aID,
+                        TextureFlags aFlags,
                         const NewSurfaceDescriptorGralloc& aDescriptor);
 
   virtual ~GrallocTextureHostOGL();
 
   virtual void Updated(const nsIntRegion* aRegion) MOZ_OVERRIDE {}
 
   virtual bool Lock() MOZ_OVERRIDE;
 
   virtual void Unlock() MOZ_OVERRIDE;
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
   virtual void DeallocateSharedData() MOZ_OVERRIDE;
 
-  virtual void ForgetSharedData() MOZ_OVERRIDE;
-
   virtual void DeallocateDeviceData() MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const;
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
 
   virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
 
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -29,19 +29,20 @@ MacIOSurfaceTextureSourceOGL::GetSize() 
 }
 
 gfx::SurfaceFormat
 MacIOSurfaceTextureSourceOGL::GetFormat() const
 {
   return mSurface->HasAlpha() ? gfx::FORMAT_R8G8B8A8 : gfx::FORMAT_B8G8R8X8;
 }
 
-MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(TextureFlags aFlags,
+MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(uint64_t aID,
+                                                       TextureFlags aFlags,
                                                        const SurfaceDescriptorMacIOSurface& aDescriptor)
-  : TextureHost(aFlags)
+  : TextureHost(aID, aFlags)
 {
   mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
                                          aDescriptor.scaleFactor(),
                                          aDescriptor.hasAlpha());
 }
 
 bool
 MacIOSurfaceTextureHostOGL::Lock()
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
@@ -60,17 +60,18 @@ protected:
 /**
  * A TextureHost for shared MacIOSurface
  *
  * Most of the logic actually happens in MacIOSurfaceTextureSourceOGL.
  */
 class MacIOSurfaceTextureHostOGL : public TextureHost
 {
 public:
-  MacIOSurfaceTextureHostOGL(TextureFlags aFlags,
+  MacIOSurfaceTextureHostOGL(uint64_t aID,
+                             TextureFlags aFlags,
                              const SurfaceDescriptorMacIOSurface& aDescriptor);
 
   // SharedTextureHostOGL doesn't own any GL texture
   virtual void DeallocateDeviceData() MOZ_OVERRIDE {}
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
   virtual bool Lock() MOZ_OVERRIDE;
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -82,50 +82,51 @@ CreateDeprecatedTextureHostOGL(SurfaceDe
   NS_ASSERTION(result, "Result should have been created.");
 
   result->SetFlags(aTextureFlags);
   return result.forget();
 }
 
 
 TemporaryRef<TextureHost>
-CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
+CreateTextureHostOGL(uint64_t aID,
+                     const SurfaceDescriptor& aDesc,
                      ISurfaceAllocator* aDeallocator,
                      TextureFlags aFlags)
 {
   RefPtr<TextureHost> result;
   switch (aDesc.type()) {
     case SurfaceDescriptor::TSurfaceDescriptorShmem:
     case SurfaceDescriptor::TSurfaceDescriptorMemory: {
-      result = CreateBackendIndependentTextureHost(aDesc,
+      result = CreateBackendIndependentTextureHost(aID, aDesc,
                                                    aDeallocator, aFlags);
       break;
     }
     case SurfaceDescriptor::TSharedTextureDescriptor: {
       const SharedTextureDescriptor& desc = aDesc.get_SharedTextureDescriptor();
-      result = new SharedTextureHostOGL(aFlags,
+      result = new SharedTextureHostOGL(aID, aFlags,
                                         desc.shareType(),
                                         desc.handle(),
                                         gfx::ToIntSize(desc.size()),
                                         desc.inverted());
       break;
     }
 #ifdef XP_MACOSX
     case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
       const SurfaceDescriptorMacIOSurface& desc =
         aDesc.get_SurfaceDescriptorMacIOSurface();
-      result = new MacIOSurfaceTextureHostOGL(aFlags, desc);
+      result = new MacIOSurfaceTextureHostOGL(aID, aFlags, desc);
       break;
     }
 #endif
 #ifdef MOZ_WIDGET_GONK
     case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: {
       const NewSurfaceDescriptorGralloc& desc =
         aDesc.get_NewSurfaceDescriptorGralloc();
-      result = new GrallocTextureHostOGL(aFlags, desc);
+      result = new GrallocTextureHostOGL(aID, aFlags, desc);
       break;
     }
 #endif
     default: return nullptr;
   }
   return result.forget();
 }
 
@@ -370,22 +371,23 @@ SharedTextureSourceOGL::GetTextureTransf
   if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) {
     NS_WARNING("Could not get shared handle details");
     return gfx3DMatrix();
   }
 
   return handleDetails.mTextureTransform;
 }
 
-SharedTextureHostOGL::SharedTextureHostOGL(TextureFlags aFlags,
+SharedTextureHostOGL::SharedTextureHostOGL(uint64_t aID,
+                                           TextureFlags aFlags,
                                            gl::SharedTextureShareType aShareType,
                                            gl::SharedTextureHandle aSharedHandle,
                                            gfx::IntSize aSize,
                                            bool inverted)
-  : TextureHost(aFlags)
+  : TextureHost(aID, aFlags)
   , mSize(aSize)
   , mCompositor(nullptr)
   , mSharedHandle(aSharedHandle)
   , mShareType(aShareType)
 {
 }
 
 SharedTextureHostOGL::~SharedTextureHostOGL()
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -293,17 +293,18 @@ protected:
 /**
  * A TextureHost for shared GL Textures
  *
  * Most of the logic actually happens in SharedTextureSourceOGL.
  */
 class SharedTextureHostOGL : public TextureHost
 {
 public:
-  SharedTextureHostOGL(TextureFlags aFlags,
+  SharedTextureHostOGL(uint64_t aID,
+                       TextureFlags aFlags,
                        gl::SharedTextureShareType aShareType,
                        gl::SharedTextureHandle aSharedhandle,
                        gfx::IntSize aSize,
                        bool inverted);
 
   virtual ~SharedTextureHostOGL();
 
   // SharedTextureHostOGL doesn't own any GL texture
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -114,39 +114,45 @@ void TestTextureClientSurface(TextureCli
   nsRefPtr<gfxASurface> aSurface = client->GetAsSurface();
   nsRefPtr<gfxImageSurface> clientSurface = aSurface->GetAsImageSurface();
 
   ASSERT_TRUE(texture->Lock(OPEN_READ_ONLY));
   AssertSurfacesEqual(surface, clientSurface);
   texture->Unlock();
 
   // client serialization
+  texture->SetID(1);
   SurfaceDescriptor descriptor;
   ASSERT_TRUE(texture->ToSurfaceDescriptor(descriptor));
 
   ASSERT_NE(descriptor.type(), SurfaceDescriptor::Tnull_t);
 
   // host deserialization
-  RefPtr<TextureHost> host = CreateBackendIndependentTextureHost(descriptor, nullptr,
+  RefPtr<TextureHost> host = CreateBackendIndependentTextureHost(texture->GetID(),
+                                                                 descriptor, nullptr,
                                                                  texture->GetFlags());
 
   ASSERT_TRUE(host.get() != nullptr);
   ASSERT_EQ(host->GetFlags(), texture->GetFlags());
+  ASSERT_EQ(host->GetID(), texture->GetID());
 
   // host read
   ASSERT_TRUE(host->Lock());
   RefPtr<mozilla::gfx::DataSourceSurface> hostDataSurface = host->GetAsSurface();
   host->Unlock();
 
   nsRefPtr<gfxImageSurface> hostSurface =
     new gfxImageSurface(hostDataSurface->GetData(),
                         ThebesIntSize(hostDataSurface->GetSize()),
                         hostDataSurface->Stride(),
                         SurfaceFormatToImageFormat(hostDataSurface->GetFormat()));
   AssertSurfacesEqual(surface, hostSurface.get());
+
+  // host deallocation
+  host->DeallocateSharedData();
 }
 
 // Same as above, for YCbCr surfaces
 void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
 
   // client allocation
   ASSERT_TRUE(client->AsTextureClientYCbCr() != nullptr);
   TextureClientYCbCr* texture = client->AsTextureClientYCbCr();
@@ -157,29 +163,32 @@ void TestTextureClientYCbCr(TextureClien
 
   // client painting
   texture->UpdateYCbCr(ycbcrData);
 
   ASSERT_TRUE(client->Lock(OPEN_READ_ONLY));
   client->Unlock();
 
   // client serialization
+  client->SetID(1);
   SurfaceDescriptor descriptor;
   ASSERT_TRUE(client->ToSurfaceDescriptor(descriptor));
 
   ASSERT_NE(descriptor.type(), SurfaceDescriptor::Tnull_t);
 
   // host deserialization
-  RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(descriptor, nullptr,
+  RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(client->GetID(),
+                                                                        descriptor, nullptr,
                                                                         client->GetFlags());
 
   RefPtr<BufferTextureHost> host = static_cast<BufferTextureHost*>(textureHost.get());
 
   ASSERT_TRUE(host.get() != nullptr);
   ASSERT_EQ(host->GetFlags(), client->GetFlags());
+  ASSERT_EQ(host->GetID(), client->GetID());
 
   // This will work iff the compositor is not BasicCompositor
   ASSERT_EQ(host->GetFormat(), mozilla::gfx::FORMAT_YUV);
 
   // host read
   ASSERT_TRUE(host->Lock());
 
   ASSERT_TRUE(host->GetFormat() == mozilla::gfx::FORMAT_YUV);
@@ -199,16 +208,19 @@ void TestTextureClientYCbCr(TextureClien
   data.mCbSkip = 0;
   data.mCrSkip = 0;
   data.mPicSize = data.mYSize;
   data.mPicX = 0;
   data.mPicY = 0;
 
   AssertYCbCrSurfacesEqual(&ycbcrData, &data);
   host->Unlock();
+
+  // host deallocation
+  host->DeallocateSharedData();
 }
 
 TEST(Layers, TextureSerialization) {
   // the test is run on all the following image formats
   gfxImageFormat formats[3] = {
     gfxImageFormatARGB32,
     gfxImageFormatRGB24,
     gfxImageFormatA8,
@@ -217,17 +229,17 @@ TEST(Layers, TextureSerialization) {
   for (int f = 0; f < 3; ++f) {
     RefPtr<gfxImageSurface> surface = new gfxImageSurface(gfxIntSize(400,300), formats[f]);
     SetupSurface(surface.get());
     AssertSurfacesEqual(surface, surface);
 
     RefPtr<TextureClient> client
       = new MemoryTextureClient(nullptr,
                                 mozilla::gfx::ImageFormatToSurfaceFormat(surface->Format()),
-                                TEXTURE_DEALLOCATE_CLIENT);
+                                TEXTURE_FLAGS_DEFAULT);
 
     TestTextureClientSurface(client, surface);
 
     // XXX - Test more texture client types.
   }
 }
 
 TEST(Layers, TextureYCbCrSerialization) {
@@ -253,14 +265,14 @@ TEST(Layers, TextureYCbCrSerialization) 
   clientData.mCrSkip = 0;
   clientData.mCrSkip = 0;
   clientData.mPicX = 0;
   clientData.mPicX = 0;
 
   RefPtr<TextureClient> client
     = new MemoryTextureClient(nullptr,
                               mozilla::gfx::FORMAT_YUV,
-                              TEXTURE_DEALLOCATE_CLIENT);
+                              TEXTURE_FLAGS_DEFAULT);
 
   TestTextureClientYCbCr(client, clientData);
 
   // XXX - Test more texture client types.
 }