Backed out 12 changesets (bug 1200595) for b2g mochitest crashes in SharedBufferManagerParent CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Tue, 24 Nov 2015 10:07:02 -0800
changeset 273992 9783264529d356ebc52cec33ef4be2b389c7b32d
parent 273991 dd05d41ce5aef1a1eedcb591f98a5599cc1c8cca
child 273993 d9243e369c22ae1df321491a15eeb931ee43f1f5
child 274066 9689a552174cec7353f698ee3ebe9c9cc60e8ac2
push id29715
push userkwierso@gmail.com
push dateTue, 24 Nov 2015 21:54:25 +0000
treeherdermozilla-central@d9243e369c22 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1200595
milestone45.0a1
backs outcf8cf1a039dd370d157b2afaa1fed719f1e34069
65da564f952c211fde3a7512251b3d98e3ed8bb4
7663208f1582394ddbe3a60dee2898f0272533e0
fc1fbb97c8eb3d999933cf3290e43928d02f61eb
3ad5a4c457fe8c5941d09a77d7d96e2e783387ed
add3fe9afc0c1790763f2cd4a3d641b809b21c15
68aba6b395887666406fbaa77a6eccb08ff5ed34
ab326c34f1cfc90f1d678f86b1761e875d60a636
ed34bc528a1b7ab01d2b36dddf60c58b00c16246
0dc93424546c50a7b74b2ae78d0cb4b3919ea58c
8cc12f12f3d1916c87d14871e86b1c5ad17ead43
bb84403701b7f86e22c75ebe6980e12424d07eca
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 12 changesets (bug 1200595) for b2g mochitest crashes in SharedBufferManagerParent CLOSED TREE Backed out changeset cf8cf1a039dd (bug 1200595) Backed out changeset 65da564f952c (bug 1200595) Backed out changeset 7663208f1582 (bug 1200595) Backed out changeset fc1fbb97c8eb (bug 1200595) Backed out changeset 3ad5a4c457fe (bug 1200595) Backed out changeset add3fe9afc0c (bug 1200595) Backed out changeset 68aba6b39588 (bug 1200595) Backed out changeset ab326c34f1cf (bug 1200595) Backed out changeset ed34bc528a1b (bug 1200595) Backed out changeset 0dc93424546c (bug 1200595) Backed out changeset 8cc12f12f3d1 (bug 1200595) Backed out changeset bb84403701b7 (bug 1200595)
dom/media/omx/OmxDecoder.cpp
dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
dom/media/webrtc/MediaEngineGonkVideoSource.cpp
gfx/gl/SharedSurface.cpp
gfx/gl/SharedSurfaceGralloc.cpp
gfx/gl/SharedSurfaceGralloc.h
gfx/layers/AsyncCanvasRenderer.cpp
gfx/layers/BufferTexture.cpp
gfx/layers/BufferTexture.h
gfx/layers/CompositorTypes.h
gfx/layers/D3D11ShareHandleImage.cpp
gfx/layers/D3D11ShareHandleImage.h
gfx/layers/D3D9SurfaceImage.cpp
gfx/layers/D3D9SurfaceImage.h
gfx/layers/GrallocImages.cpp
gfx/layers/GrallocImages.h
gfx/layers/IMFYCbCrImage.cpp
gfx/layers/ImageDataSerializer.h
gfx/layers/LayersLogging.cpp
gfx/layers/MacIOSurfaceImage.cpp
gfx/layers/TextureDIB.cpp
gfx/layers/TextureDIB.h
gfx/layers/YCbCrImageDataSerializer.cpp
gfx/layers/basic/GrallocTextureHostBasic.cpp
gfx/layers/basic/TextureClientX11.cpp
gfx/layers/basic/TextureClientX11.h
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CompositableClient.cpp
gfx/layers/client/CompositableClient.h
gfx/layers/client/ImageClient.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/client/TextureClientPool.cpp
gfx/layers/client/TextureClientSharedSurface.cpp
gfx/layers/client/TextureClientSharedSurface.h
gfx/layers/client/TiledContentClient.cpp
gfx/layers/d3d11/TextureD3D11.cpp
gfx/layers/d3d11/TextureD3D11.h
gfx/layers/d3d9/TextureD3D9.cpp
gfx/layers/d3d9/TextureD3D9.h
gfx/layers/ipc/CompositableForwarder.h
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeChild.h
gfx/layers/ipc/LayerTransactionChild.cpp
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
gfx/layers/ipc/SharedPlanarYCbCrImage.h
gfx/layers/ipc/SharedRGBImage.cpp
gfx/layers/ipc/SharedRGBImage.h
gfx/layers/moz.build
gfx/layers/opengl/GrallocTextureClient.cpp
gfx/layers/opengl/GrallocTextureClient.h
gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp
gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h
gfx/layers/opengl/TextureClientOGL.cpp
gfx/layers/opengl/TextureClientOGL.h
gfx/tests/gtest/TestTextures.cpp
widget/gonk/nativewindow/GonkBufferQueueJB.cpp
widget/gonk/nativewindow/GonkBufferQueueKK.cpp
widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp
widget/gonk/nativewindow/GonkNativeWindowICS.cpp
--- a/dom/media/omx/OmxDecoder.cpp
+++ b/dom/media/omx/OmxDecoder.cpp
@@ -349,20 +349,20 @@ OmxDecoder::ReleaseMediaResources() {
     MOZ_ASSERT(mPendingRecycleTexutreClients.empty());
     // Release all pending recycle TextureClients, if they are not recycled yet.
     // This should not happen. See Bug 1042308.
     if (!mPendingRecycleTexutreClients.empty()) {
       printf_stderr("OmxDecoder::ReleaseMediaResources -- TextureClients are not recycled yet\n");
       for (std::set<TextureClient*>::iterator it=mPendingRecycleTexutreClients.begin();
            it!=mPendingRecycleTexutreClients.end(); it++)
       {
-        GrallocTextureData* client = static_cast<GrallocTextureData*>((*it)->GetInternalData());
-        (*it)->ClearRecycleCallback();
+        GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(*it);
+        client->ClearRecycleCallback();
         if (client->GetMediaBuffer()) {
-          mPendingVideoBuffers.push(BufferItem(client->GetMediaBuffer(), (*it)->GetAndResetReleaseFenceHandle()));
+          mPendingVideoBuffers.push(BufferItem(client->GetMediaBuffer(), client->GetAndResetReleaseFenceHandle()));
         }
       }
       mPendingRecycleTexutreClients.clear();
     }
   }
 
   {
     // Free all pending video buffers.
@@ -648,17 +648,18 @@ OmxDecoder::ReadVideo(VideoFrame *aFrame
     if ((mVideoBuffer->graphicBuffer().get())) {
       textureClient = mNativeWindow->getTextureClientFromBuffer(mVideoBuffer->graphicBuffer().get());
     }
 
     if (textureClient) {
       // Manually increment reference count to keep MediaBuffer alive
       // during TextureClient is in use.
       mVideoBuffer->add_ref();
-      static_cast<GrallocTextureData*>(textureClient->GetInternalData())->SetMediaBuffer(mVideoBuffer);
+      GrallocTextureClientOGL* grallocClient = static_cast<GrallocTextureClientOGL*>(textureClient.get());
+      grallocClient->SetMediaBuffer(mVideoBuffer);
       // Set recycle callback for TextureClient
       textureClient->SetRecycleCallback(OmxDecoder::RecycleCallback, this);
       {
         Mutex::Autolock autoLock(mPendingVideoBuffersLock);
         // Store pending recycle TextureClient.
         MOZ_ASSERT(mPendingRecycleTexutreClients.find(textureClient) == mPendingRecycleTexutreClients.end());
         mPendingRecycleTexutreClients.insert(textureClient);
       }
@@ -911,19 +912,19 @@ OmxDecoder::RecycleCallbackImp(TextureCl
   aClient->ClearRecycleCallback();
   {
     Mutex::Autolock autoLock(mPendingVideoBuffersLock);
     if (mPendingRecycleTexutreClients.find(aClient) == mPendingRecycleTexutreClients.end()) {
       printf_stderr("OmxDecoder::RecycleCallbackImp -- TextureClient is not pending recycle\n");
       return;
     }
     mPendingRecycleTexutreClients.erase(aClient);
-    GrallocTextureData* grallocData = static_cast<GrallocTextureData*>(aClient->GetInternalData());
-    if (grallocData->GetMediaBuffer()) {
-      mPendingVideoBuffers.push(BufferItem(grallocData->GetMediaBuffer(), aClient->GetAndResetReleaseFenceHandle()));
+    GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(aClient);
+    if (client->GetMediaBuffer()) {
+      mPendingVideoBuffers.push(BufferItem(client->GetMediaBuffer(), client->GetAndResetReleaseFenceHandle()));
     }
   }
   sp<AMessage> notify =
             new AMessage(kNotifyPostReleaseVideoBuffer, mReflector->id());
   // post AMessage to OmxDecoder via ALooper.
   notify->post();
 }
 
--- a/dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
+++ b/dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
@@ -369,24 +369,24 @@ GonkVideoDecoderManager::CreateVideoData
       GVDM_LOG("Copy buffer allocation failed!");
       return nullptr;
     }
     // Update size to match buffer's.
     aPicture.width = size.width;
     aPicture.height = size.height;
 
     sp<GraphicBuffer> destBuffer =
-      static_cast<GrallocTextureData*>(textureClient->GetInternalData())->GetGraphicBuffer();
-     
+      static_cast<GrallocTextureClientOGL*>(textureClient.get())->GetGraphicBuffer();
+
     CopyGraphicBuffer(srcBuffer, destBuffer, aPicture);
   } else {
     textureClient = mNativeWindow->getTextureClientFromBuffer(srcBuffer.get());
     textureClient->SetRecycleCallback(GonkVideoDecoderManager::RecycleCallback, this);
-
-    static_cast<GrallocTextureData*>(textureClient->GetInternalData())->SetMediaBuffer(aSource);
+    GrallocTextureClientOGL* grallocClient = static_cast<GrallocTextureClientOGL*>(textureClient.get());
+    grallocClient->SetMediaBuffer(aSource);
   }
 
   RefPtr<VideoData> data = VideoData::Create(mInfo.mVideo,
                                              mImageContainer,
                                              0, // Filled later by caller.
                                              0, // Filled later by caller.
                                              1, // No way to pass sample duration from muxer to
                                                 // OMX codec, so we hardcode the duration here.
@@ -678,17 +678,17 @@ GonkVideoDecoderManager::GetColorConvert
 }
 
 /* static */
 void
 GonkVideoDecoderManager::RecycleCallback(TextureClient* aClient, void* aClosure)
 {
   MOZ_ASSERT(aClient && !aClient->IsDead());
   GonkVideoDecoderManager* videoManager = static_cast<GonkVideoDecoderManager*>(aClosure);
-  GrallocTextureData* client = static_cast<GrallocTextureData*>(aClient->GetInternalData());
+  GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(aClient);
   aClient->ClearRecycleCallback();
   FenceHandle handle = aClient->GetAndResetReleaseFenceHandle();
   videoManager->PostReleaseVideoBuffer(client->GetMediaBuffer(), handle);
 }
 
 void GonkVideoDecoderManager::PostReleaseVideoBuffer(
                                 android::MediaBuffer *aBuffer,
                                 FenceHandle aReleaseFence)
--- a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp
@@ -758,18 +758,19 @@ MediaEngineGonkVideoSource::RotateImage(
   MOZ_ASSERT(mTextureClientAllocator);
   RefPtr<layers::TextureClient> textureClient
     = mTextureClientAllocator->CreateOrRecycle(gfx::SurfaceFormat::YUV,
                                                gfx::IntSize(dstWidth, dstHeight),
                                                layers::BackendSelector::Content,
                                                layers::TextureFlags::DEFAULT,
                                                layers::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
   if (textureClient) {
-    android::sp<android::GraphicBuffer> destBuffer =
-      static_cast<layers::GrallocTextureData*>(textureClient->GetInternalData())->GetGraphicBuffer();
+    RefPtr<layers::GrallocTextureClientOGL> grallocTextureClient = textureClient->AsGrallocTextureClientOGL();
+
+    android::sp<android::GraphicBuffer> destBuffer = grallocTextureClient->GetGraphicBuffer();
 
     void* destMem = nullptr;
     destBuffer->lock(android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, &destMem);
     uint8_t* dstPtr = static_cast<uint8_t*>(destMem);
 
     int32_t yStride = destBuffer->getStride();
     // Align to 16 bytes boundary
     int32_t uvStride = ((yStride / 2) + 15) & ~0x0F;
--- a/gfx/gl/SharedSurface.cpp
+++ b/gfx/gl/SharedSurface.cpp
@@ -350,17 +350,17 @@ SurfaceFactory::NewTexClient(const gfx::
         StopRecycling(cur);
     }
 
     UniquePtr<SharedSurface> surf = Move(CreateShared(size));
     if (!surf)
         return nullptr;
 
     RefPtr<layers::SharedSurfaceTextureClient> ret;
-    ret = layers::SharedSurfaceTextureClient::Create(Move(surf), this, mAllocator, mFlags);
+    ret = new layers::SharedSurfaceTextureClient(mAllocator, mFlags, Move(surf), this);
 
     StartRecycling(ret);
 
     return ret.forget();
 }
 
 void
 SurfaceFactory::StartRecycling(layers::SharedSurfaceTextureClient* tc)
@@ -386,17 +386,17 @@ SurfaceFactory::StopRecycling(layers::Sh
 
 /*static*/ void
 SurfaceFactory::RecycleCallback(layers::TextureClient* rawTC, void* rawFactory)
 {
     RefPtr<layers::SharedSurfaceTextureClient> tc;
     tc = static_cast<layers::SharedSurfaceTextureClient*>(rawTC);
     SurfaceFactory* factory = static_cast<SurfaceFactory*>(rawFactory);
 
-    if (tc->Surf()->mCanRecycle) {
+    if (tc->mSurf->mCanRecycle) {
         if (factory->Recycle(tc))
             return;
     }
 
     // Did not recover the tex client. End the (re)cycle!
     factory->StopRecycling(tc);
 }
 
--- a/gfx/gl/SharedSurfaceGralloc.cpp
+++ b/gfx/gl/SharedSurfaceGralloc.cpp
@@ -58,27 +58,27 @@ SharedSurface_Gralloc::Create(GLContext*
     DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n");
 
     if (!HasExtensions(egl, prodGL))
         return Move(ret);
 
     gfxContentType type = hasAlpha ? gfxContentType::COLOR_ALPHA
                                    : gfxContentType::COLOR;
 
-    GrallocTextureData* texData = GrallocTextureData::CreateForGLRendering(
-        size, gfxPlatform::GetPlatform()->Optimal2DFormatForContent(type), allocator
-    );
+    typedef GrallocTextureClientOGL ptrT;
+    RefPtr<ptrT> grallocTC = new ptrT(allocator,
+                                      gfxPlatform::GetPlatform()->Optimal2DFormatForContent(type),
+                                      gfx::BackendType::NONE, // we don't need to use it with a DrawTarget
+                                      flags);
 
-    if (!texData) {
+    if (!grallocTC->AllocateForGLRendering(size)) {
         return Move(ret);
     }
 
-    RefPtr<TextureClient> grallocTC = new TextureClient(texData, flags, allocator);
-
-    sp<GraphicBuffer> buffer = texData->GetGraphicBuffer();
+    sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer();
 
     EGLDisplay display = egl->Display();
     EGLClientBuffer clientBuffer = buffer->getNativeBuffer();
     EGLint attrs[] = {
         LOCAL_EGL_NONE, LOCAL_EGL_NONE
     };
     EGLImage image = egl->fCreateImage(display,
                                        EGL_NO_CONTEXT,
@@ -114,17 +114,17 @@ SharedSurface_Gralloc::Create(GLContext*
 }
 
 
 SharedSurface_Gralloc::SharedSurface_Gralloc(GLContext* prodGL,
                                              const gfx::IntSize& size,
                                              bool hasAlpha,
                                              GLLibraryEGL* egl,
                                              layers::ISurfaceAllocator* allocator,
-                                             layers::TextureClient* textureClient,
+                                             layers::GrallocTextureClientOGL* textureClient,
                                              GLuint prodTex)
     : SharedSurface(SharedSurfaceType::Gralloc,
                     AttachmentType::GLTexture,
                     prodGL,
                     size,
                     hasAlpha,
                     true)
     , mEGL(egl)
@@ -274,26 +274,25 @@ void
 SharedSurface_Gralloc::WaitForBufferOwnership()
 {
     mTextureClient->WaitForBufferOwnership();
 }
 
 bool
 SharedSurface_Gralloc::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
 {
+    mTextureClient->MarkShared();
     return mTextureClient->ToSurfaceDescriptor(*out_descriptor);
 }
 
 bool
 SharedSurface_Gralloc::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
 {
     MOZ_ASSERT(out_surface);
-    sp<GraphicBuffer> buffer = static_cast<GrallocTextureData*>(
-        mTextureClient->GetInternalData()
-    )->GetGraphicBuffer();
+    sp<GraphicBuffer> buffer = mTextureClient->GetGraphicBuffer();
 
     const uint8_t* grallocData = nullptr;
     auto result = buffer->lock(
         GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
         const_cast<void**>(reinterpret_cast<const void**>(&grallocData))
     );
 
     if (result == BAD_VALUE) {
--- a/gfx/gl/SharedSurfaceGralloc.h
+++ b/gfx/gl/SharedSurfaceGralloc.h
@@ -8,17 +8,17 @@
 
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayersSurfaces.h"
 #include "SharedSurface.h"
 
 namespace mozilla {
 namespace layers {
 class ISurfaceAllocator;
-class TextureClient;
+class GrallocTextureClientOGL;
 }
 
 namespace gl {
 class GLContext;
 class GLLibraryEGL;
 
 class SharedSurface_Gralloc
     : public SharedSurface
@@ -36,25 +36,25 @@ public:
 
         return (SharedSurface_Gralloc*)surf;
     }
 
 protected:
     GLLibraryEGL* const mEGL;
     EGLSync mSync;
     RefPtr<layers::ISurfaceAllocator> mAllocator;
-    RefPtr<layers::TextureClient> mTextureClient;
+    RefPtr<layers::GrallocTextureClientOGL> mTextureClient;
     const GLuint mProdTex;
 
     SharedSurface_Gralloc(GLContext* prodGL,
                           const gfx::IntSize& size,
                           bool hasAlpha,
                           GLLibraryEGL* egl,
                           layers::ISurfaceAllocator* allocator,
-                          layers::TextureClient* textureClient,
+                          layers::GrallocTextureClientOGL* textureClient,
                           GLuint prodTex);
 
     static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
 
 public:
     virtual ~SharedSurface_Gralloc();
 
     virtual void Fence() override;
@@ -65,17 +65,17 @@ public:
 
     virtual void LockProdImpl() override {}
     virtual void UnlockProdImpl() override {}
 
     virtual GLuint ProdTexture() override {
         return mProdTex;
     }
 
-    layers::TextureClient* GetTextureClient() {
+    layers::GrallocTextureClientOGL* GetTextureClient() {
         return mTextureClient;
     }
 
     virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
 
     virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) override;
 };
 
--- a/gfx/layers/AsyncCanvasRenderer.cpp
+++ b/gfx/layers/AsyncCanvasRenderer.cpp
@@ -6,17 +6,16 @@
 
 #include "AsyncCanvasRenderer.h"
 
 #include "gfxUtils.h"
 #include "GLContext.h"
 #include "GLReadTexImageHelper.h"
 #include "GLScreenBuffer.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
-#include "mozilla/layers/BufferTexture.h"
 #include "mozilla/layers/CanvasClient.h"
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/TextureClientSharedSurface.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsIRunnable.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
@@ -143,48 +142,44 @@ AsyncCanvasRenderer::GetActiveThread()
   nsCOMPtr<nsIThread> result = mActiveThread;
   return result.forget();
 }
 
 void
 AsyncCanvasRenderer::CopyFromTextureClient(TextureClient* aTextureClient)
 {
   MutexAutoLock lock(mMutex);
-  TextureClientAutoLock texLock(aTextureClient, layers::OpenMode::OPEN_READ);
-  if (!texLock.Succeeded()) {
+  RefPtr<BufferTextureClient> buffer = static_cast<BufferTextureClient*>(aTextureClient);
+  if (!buffer->Lock(layers::OpenMode::OPEN_READ)) {
     return;
   }
 
   const gfx::IntSize& size = aTextureClient->GetSize();
   // This buffer would be used later for content rendering. So we choose
   // B8G8R8A8 format here.
   const gfx::SurfaceFormat format = gfx::SurfaceFormat::B8G8R8A8;
   // Avoid to create buffer every time.
   if (!mSurfaceForBasic ||
       size != mSurfaceForBasic->GetSize() ||
       format != mSurfaceForBasic->GetFormat())
   {
     uint32_t stride = gfx::GetAlignedStride<8>(size.width * BytesPerPixel(format));
     mSurfaceForBasic = gfx::Factory::CreateDataSourceSurfaceWithStride(size, format, stride);
   }
 
-  MappedTextureData mapped;
-  if (!aTextureClient->BorrowMappedData(mapped)) {
+  const uint8_t* lockedBytes = buffer->GetLockedData();
+  gfx::DataSourceSurface::ScopedMap map(mSurfaceForBasic,
+                                        gfx::DataSourceSurface::MapType::WRITE);
+  if (!map.IsMapped()) {
+    buffer->Unlock();
     return;
   }
 
-  const uint8_t* lockedBytes = mapped.data;
-  gfx::DataSourceSurface::ScopedMap map(mSurfaceForBasic,
-                                        gfx::DataSourceSurface::MapType::WRITE);
-  if (!map.IsMapped()) {
-    return;
-  }
-
-  MOZ_ASSERT(map.GetStride() == mapped.stride);
   memcpy(map.GetData(), lockedBytes, map.GetStride() * mSurfaceForBasic->GetSize().height);
+  buffer->Unlock();
 
   if (mSurfaceForBasic->GetFormat() == gfx::SurfaceFormat::R8G8B8A8 ||
       mSurfaceForBasic->GetFormat() == gfx::SurfaceFormat::R8G8B8X8) {
     gl::SwapRAndBComponents(mSurfaceForBasic);
   }
 }
 
 already_AddRefed<gfx::DataSourceSurface>
deleted file mode 100644
--- a/gfx/layers/BufferTexture.cpp
+++ /dev/null
@@ -1,449 +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/. */
-
-#include "BufferTexture.h"
-#include "mozilla/layers/ImageDataSerializer.h"
-#include "mozilla/layers/ISurfaceAllocator.h"
-#include "mozilla/gfx/Logging.h"
-#include "mozilla/gfx/2D.h"
-#include "mozilla/fallible.h"
-
-namespace mozilla {
-namespace layers {
-
-class MemoryTextureData : public BufferTextureData
-{
-public:
-  static MemoryTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                   gfx::BackendType aMoz2DBackend,TextureFlags aFlags,
-                                   TextureAllocationFlags aAllocFlags,
-                                   ISurfaceAllocator* aAllocator);
-
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags = TextureFlags::DEFAULT,
-                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
-
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
-
-  virtual void Deallocate(ISurfaceAllocator*) override;
-
-  MemoryTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                    gfx::BackendType aMoz2DBackend,
-                    uint8_t* aBuffer, size_t aBufferSize)
-  : BufferTextureData(aSize, aFormat, aMoz2DBackend)
-  , mBuffer(aBuffer)
-  , mBufferSize(aBufferSize)
-  {
-    MOZ_ASSERT(aBuffer);
-    MOZ_ASSERT(aBufferSize);
-  }
-
-  virtual uint8_t* GetBuffer() override { return mBuffer; }
-
-  virtual size_t GetBufferSize() override { return mBufferSize; }
-
-protected:
-  uint8_t* mBuffer;
-  size_t mBufferSize;
-};
-
-class ShmemTextureData : public BufferTextureData
-{
-public:
-  static ShmemTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                  gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
-                                  TextureAllocationFlags aAllocFlags,
-                                  ISurfaceAllocator* aAllocator);
-
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags = TextureFlags::DEFAULT,
-                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
-
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
-
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
-
-  ShmemTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                   gfx::BackendType aMoz2DBackend, mozilla::ipc::Shmem aShmem)
-  : BufferTextureData(aSize, aFormat, aMoz2DBackend)
-  , mShmem(aShmem)
-  {
-    MOZ_ASSERT(mShmem.Size<uint8_t>());
-  }
-
-  virtual uint8_t* GetBuffer() override { return mShmem.get<uint8_t>(); }
-
-  virtual size_t GetBufferSize() override { return mShmem.Size<uint8_t>(); }
-
-protected:
-  mozilla::ipc::Shmem mShmem;
-};
-
-BufferTextureData*
-BufferTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                          gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
-                          TextureAllocationFlags aAllocFlags,
-                          ISurfaceAllocator* aAllocator)
-{
-  if (!aAllocator || aAllocator->IsSameProcess()) {
-    return MemoryTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags, aAllocFlags, aAllocator);
-  } else {
-    return ShmemTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags, aAllocFlags, aAllocator);
-  }
-}
-
-BufferTextureData*
-BufferTextureData::CreateWithBufferSize(ISurfaceAllocator* aAllocator,
-                                        gfx::SurfaceFormat aFormat,
-                                        size_t aSize,
-                                        TextureFlags aTextureFlags)
-{
-  if (aSize == 0) {
-    return nullptr;
-  }
-
-  BufferTextureData* data;
-  if (!aAllocator || aAllocator->IsSameProcess()) {
-    uint8_t* buffer = new (fallible) uint8_t[aSize];
-    if (!buffer) {
-      return nullptr;
-    }
-
-    data = new MemoryTextureData(gfx::IntSize(), aFormat, gfx::BackendType::NONE, buffer, aSize);
-  } else {
-    ipc::Shmem shm;
-    if (!aAllocator->AllocUnsafeShmem(aSize, OptimalShmemType(), &shm)) {
-      return nullptr;
-    }
-
-    data = new ShmemTextureData(gfx::IntSize(), aFormat, gfx::BackendType::NONE, shm);
-  }
-
-  // Initialize the metadata with something, even if it will have to be rewritten
-  // afterwards since we don't know the dimensions of the texture at this point.
-  if (aFormat == gfx::SurfaceFormat::YUV) {
-    YCbCrImageDataSerializer serializer(data->GetBuffer(), data->GetBufferSize());
-    serializer.InitializeBufferInfo(gfx::IntSize(0,0), gfx::IntSize(0,0), StereoMode::MONO);
-  } else {
-    ImageDataSerializer serializer(data->GetBuffer(), data->GetBufferSize());
-    serializer.InitializeBufferInfo(gfx::IntSize(0, 0), aFormat);
-  }
-
-  return data;
-}
-
-BufferTextureData*
-BufferTextureData::CreateForYCbCr(ISurfaceAllocator* aAllocator,
-                                  gfx::IntSize aYSize,
-                                  gfx::IntSize aCbCrSize,
-                                  StereoMode aStereoMode,
-                                  TextureFlags aTextureFlags)
-{
-  size_t bufSize = YCbCrImageDataSerializer::ComputeMinBufferSize(aYSize, aCbCrSize);
-  BufferTextureData* texture = CreateWithBufferSize(aAllocator, gfx::SurfaceFormat::YUV,
-                                                    bufSize, aTextureFlags);
-  if (!texture) {
-    return nullptr;
-  }
-
-  YCbCrImageDataSerializer serializer(texture->GetBuffer(), texture->GetBufferSize());
-  serializer.InitializeBufferInfo(aYSize, aCbCrSize, aStereoMode);
-  texture->mSize = aYSize;
-
-  return texture;
-}
-
-bool
-BufferTextureData::SupportsMoz2D() const
-{
-  switch (mFormat) {
-    case gfx::SurfaceFormat::YUV:
-    case gfx::SurfaceFormat::NV12:
-    case gfx::SurfaceFormat::UNKNOWN:
-      return false;
-    default:
-      return true;
-  }
-}
-
-already_AddRefed<gfx::DrawTarget>
-BufferTextureData::BorrowDrawTarget()
-{
-  if (mDrawTarget) {
-    mDrawTarget->SetTransform(gfx::Matrix());
-    RefPtr<gfx::DrawTarget> dt = mDrawTarget;
-    return dt.forget();
-  }
-
-  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
-  if (!serializer.IsValid()) {
-    return nullptr;
-  }
-
-  mDrawTarget = serializer.GetAsDrawTarget(mMoz2DBackend);
-  if (mDrawTarget) {
-    RefPtr<gfx::DrawTarget> dt = mDrawTarget;
-    return dt.forget();
-  }
-
-  // TODO - should we warn? should we really fallback to cairo? perhaps
-  // at least update mMoz2DBackend...
-  mDrawTarget = serializer.GetAsDrawTarget(gfx::BackendType::CAIRO);
-  if (!mDrawTarget) {
-    gfxCriticalNote << "BorrowDrawTarget failure, original backend " << (int)mMoz2DBackend;
-  }
-
-  RefPtr<gfx::DrawTarget> dt = mDrawTarget;
-  return dt.forget();
-}
-
-bool
-BufferTextureData::BorrowMappedData(MappedTextureData& aData)
-{
-  if (mFormat == gfx::SurfaceFormat::YUV) {
-    return false;
-  }
-
-  ImageDataDeserializer view(GetBuffer(), GetBufferSize());
-  if (!view.IsValid()) {
-    return false;
-  }
-
-  aData.data = view.GetData();
-  aData.size = view.GetSize();
-  aData.stride = view.GetStride();
-  aData.format = mFormat;
-
-  return true;
-}
-
-bool
-BufferTextureData::BorrowMappedYCbCrData(MappedYCbCrTextureData& aMap)
-{
-  if (mFormat != gfx::SurfaceFormat::YUV) {
-    return false;
-  }
-
-  YCbCrImageDataDeserializer view(GetBuffer(), GetBufferSize());
-  if (!view.IsValid()) {
-    return false;
-  }
-
-  aMap.stereoMode = view.GetStereoMode();
-  aMap.metadata = GetBuffer();
-
-  aMap.y.data = view.GetYData();
-  aMap.y.size = view.GetYSize();
-  aMap.y.stride = view.GetYStride();
-  aMap.y.skip = 0;
-
-  aMap.cb.data = view.GetCbData();
-  aMap.cb.size = view.GetCbCrSize();
-  aMap.cb.stride = view.GetCbCrStride();
-  aMap.cb.skip = 0;
-
-  aMap.cr.data = view.GetCrData();
-  aMap.cr.size = view.GetCbCrSize();
-  aMap.cr.stride = view.GetCbCrStride();
-  aMap.cr.skip = 0;
-
-  return true;
-}
-
-bool
-BufferTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
-{
-  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
-
-  RefPtr<gfx::DataSourceSurface> surface = serializer.GetAsSurface();
-
-  if (!surface) {
-    gfxCriticalError() << "Failed to get serializer as surface!";
-    return false;
-  }
-
-  RefPtr<gfx::DataSourceSurface> srcSurf = aSurface->GetDataSurface();
-
-  if (!srcSurf) {
-    gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
-    return false;
-  }
-
-  if (surface->GetSize() != srcSurf->GetSize() || surface->GetFormat() != srcSurf->GetFormat()) {
-    gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format! This: " << surface->GetSize() << " " << surface->GetFormat() << " Other: " << aSurface->GetSize() << " " << aSurface->GetFormat();
-    return false;
-  }
-
-  gfx::DataSourceSurface::MappedSurface sourceMap;
-  gfx::DataSourceSurface::MappedSurface destMap;
-  if (!srcSurf->Map(gfx::DataSourceSurface::READ, &sourceMap)) {
-    gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
-    return false;
-  }
-
-  if (!surface->Map(gfx::DataSourceSurface::WRITE, &destMap)) {
-    srcSurf->Unmap();
-    gfxCriticalError() << "Failed to map destination surface for UpdateFromSurface.";
-    return false;
-  }
-
-
-  for (int y = 0; y < srcSurf->GetSize().height; y++) {
-    memcpy(destMap.mData + destMap.mStride * y,
-           sourceMap.mData + sourceMap.mStride * y,
-           srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
-  }
-
-  srcSurf->Unmap();
-  surface->Unmap();
-
-  return true;
-}
-
-bool
-MemoryTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
-{
-  MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
-  if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
-    return false;
-  }
-
-  aOutDescriptor = SurfaceDescriptorMemory(reinterpret_cast<uintptr_t>(mBuffer),
-                                           GetFormat());
-  return true;
-}
-
-static bool InitBuffer(uint8_t* buf, size_t bufSize,
-                       gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                       TextureAllocationFlags aAllocFlags)
-{
-  if (!buf) {
-    gfxDebug() << "BufferTextureData: Failed to allocate " << bufSize << " bytes";
-    return false;
-  }
-
-  if (aAllocFlags & ALLOC_CLEAR_BUFFER) {
-    memset(buf, 0, bufSize);
-  }
-  if (aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE) {
-    memset(buf, 0xFF, bufSize);
-  }
-
-  ImageDataSerializer serializer(buf, bufSize);
-  serializer.InitializeBufferInfo(aSize, aFormat);
-  return true;
-}
-
-MemoryTextureData*
-MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                          gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
-                          TextureAllocationFlags aAllocFlags,
-                          ISurfaceAllocator*)
-{
-  if (aSize.width <= 0 || aSize.height <= 0) {
-    gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
-    return nullptr;
-  }
-
-  uint32_t bufSize = ImageDataSerializer::ComputeMinBufferSize(aSize, aFormat);
-  if (!bufSize) {
-    return nullptr;
-  }
-
-  uint8_t* buf = new (fallible) uint8_t[bufSize];
-
-  if (InitBuffer(buf, bufSize, aSize, aFormat, aAllocFlags)) {
-    GfxMemoryImageReporter::DidAlloc(buf);
-    return new MemoryTextureData(aSize, aFormat, aMoz2DBackend, buf, bufSize);
-  }
-
-  return nullptr;
-}
-
-void
-MemoryTextureData::Deallocate(ISurfaceAllocator*)
-{
-  MOZ_ASSERT(mBuffer);
-  GfxMemoryImageReporter::WillFree(mBuffer);
-  delete [] mBuffer;
-  mBuffer = nullptr;
-}
-
-TextureData*
-MemoryTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
-                                 TextureFlags aFlags,
-                                 TextureAllocationFlags aAllocFlags) const
-{
-  return MemoryTextureData::Create(mSize, mFormat, mMoz2DBackend,
-                                   aFlags, aAllocFlags, aAllocator);
-}
-
-bool
-ShmemTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
-{
-  MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
-  if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
-    return false;
-  }
-
-  aOutDescriptor = SurfaceDescriptorShmem(mShmem, GetFormat());
-
-  return true;
-}
-
-ShmemTextureData*
-ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                         gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
-                         TextureAllocationFlags aAllocFlags,
-                         ISurfaceAllocator* aAllocator)
-{
-  MOZ_ASSERT(aAllocator);
-  if (!aAllocator) {
-    return nullptr;
-  }
-
-  if (aSize.width <= 0 || aSize.height <= 0) {
-    gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
-    return nullptr;
-  }
-
-  uint32_t bufSize = ImageDataSerializer::ComputeMinBufferSize(aSize, aFormat);
-  if (!bufSize) {
-    return nullptr;
-  }
-
-  mozilla::ipc::Shmem shm;
-  if (!aAllocator->AllocUnsafeShmem(bufSize, OptimalShmemType(), &shm)) {
-    return nullptr;
-  }
-
-  uint8_t* buf = shm.get<uint8_t>();
-
-  if (InitBuffer(buf, bufSize, aSize, aFormat, aAllocFlags)) {
-    return new ShmemTextureData(aSize, aFormat, aMoz2DBackend, shm);
-  }
-
-  return nullptr;
-}
-
-TextureData*
-ShmemTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
-                                TextureFlags aFlags,
-                                TextureAllocationFlags aAllocFlags) const
-{
-  return ShmemTextureData::Create(mSize, mFormat, mMoz2DBackend,
-                                  aFlags, aAllocFlags, aAllocator);
-}
-
-void
-ShmemTextureData::Deallocate(ISurfaceAllocator* aAllocator)
-{
-  aAllocator->DeallocShmem(mShmem);
-}
-
-} // namespace
-} // namespace
deleted file mode 100644
--- a/gfx/layers/BufferTexture.h
+++ /dev/null
@@ -1,81 +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_LAYERS_BUFFERETEXTURE
-#define MOZILLA_LAYERS_BUFFERETEXTURE
-
-#include "mozilla/layers/ImageDataSerializer.h"
-#include "mozilla/layers/YCbCrImageDataSerializer.h"
-#include "mozilla/layers/TextureClient.h"
-#include "mozilla/ipc/SharedMemory.h"
-#include "mozilla/gfx/Types.h"
-#include "mozilla/gfx/2D.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-namespace layers {
-
-class BufferTextureData : public TextureData
-{
-public:
-  static BufferTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                   gfx::BackendType aMoz2DBackend,TextureFlags aFlags,
-                                   TextureAllocationFlags aAllocFlags,
-                                   ISurfaceAllocator* aAllocator);
-
-  static BufferTextureData* CreateWithBufferSize(ISurfaceAllocator* aAllocator,
-                                                 gfx::SurfaceFormat aFormat,
-                                                 size_t aSize,
-                                                 TextureFlags aTextureFlags);
-
-  static BufferTextureData* CreateForYCbCr(ISurfaceAllocator* aAllocator,
-                                           gfx::IntSize aYSize,
-                                           gfx::IntSize aCbCrSize,
-                                           StereoMode aStereoMode,
-                                           TextureFlags aTextureFlags);
-
-  virtual bool Lock(OpenMode aMode, FenceHandle*) override { return true; }
-
-  virtual void Unlock() override {}
-
-  virtual gfx::IntSize GetSize() const override { return mSize; }
-
-  virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
-
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
-
-  virtual bool CanExposeMappedData() const override { return true; }
-
-  virtual bool BorrowMappedData(MappedTextureData& aMap) override;
-
-  virtual bool BorrowMappedYCbCrData(MappedYCbCrTextureData& aMap) override;
-
-  virtual bool SupportsMoz2D() const override;
-
-  virtual bool HasInternalBuffer() const override { return true; }
-
-  // use TextureClient's default implementation
-  virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
-
-protected:
-  virtual uint8_t* GetBuffer() = 0;
-  virtual size_t GetBufferSize() = 0;
-
-  BufferTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, gfx::BackendType aMoz2DBackend)
-  : mSize(aSize)
-  , mFormat(aFormat)
-  , mMoz2DBackend(aMoz2DBackend)
-  {}
-
-  RefPtr<gfx::DrawTarget> mDrawTarget;
-  gfx::IntSize mSize;
-  gfx::SurfaceFormat mFormat;
-  gfx::BackendType mMoz2DBackend;
-};
-
-} // namespace
-} // namespace
-
-#endif
--- a/gfx/layers/CompositorTypes.h
+++ b/gfx/layers/CompositorTypes.h
@@ -46,31 +46,29 @@ enum class TextureFlags : uint32_t {
   NON_PREMULTIPLIED  = 1 << 4,
   // The texture should be recycled when no longer in used
   RECYCLE            = 1 << 5,
   // If DEALLOCATE_CLIENT is set, the shared data is deallocated on the
   // client side and requires some extra synchronizaion to ensure race-free
   // deallocation.
   // The default behaviour is to deallocate on the host side.
   DEALLOCATE_CLIENT  = 1 << 6,
-  DEALLOCATE_SYNC    = 1 << 6, // XXX - make it a separate flag.
-  DEALLOCATE_MAIN_THREAD = 1 << 8,
   // After being shared ith the compositor side, an immutable texture is never
   // modified, it can only be read. It is safe to not Lock/Unlock immutable
   // textures.
-  IMMUTABLE          = 1 << 9,
+  IMMUTABLE          = 1 << 7,
   // The contents of the texture must be uploaded or copied immediately
   // during the transaction, because the producer may want to write
   // to it again.
-  IMMEDIATE_UPLOAD   = 1 << 10,
+  IMMEDIATE_UPLOAD   = 1 << 8,
   // The texture is part of a component-alpha pair
-  COMPONENT_ALPHA    = 1 << 11,
+  COMPONENT_ALPHA    = 1 << 9,
 
   // OR union of all valid bits
-  ALL_BITS           = (1 << 12) - 1,
+  ALL_BITS           = (1 << 10) - 1,
   // the default flags
   DEFAULT = NO_FLAGS
 };
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(TextureFlags)
 
 static inline bool
 TextureRequiresLocking(TextureFlags aFlags)
 {
--- a/gfx/layers/D3D11ShareHandleImage.cpp
+++ b/gfx/layers/D3D11ShareHandleImage.cpp
@@ -124,38 +124,45 @@ D3D11ShareHandleImage::GetAsSourceSurfac
   context->Unmap(softTexture, 0);
   surface->Unmap();
 
   return surface.forget();
 }
 
 ID3D11Texture2D*
 D3D11ShareHandleImage::GetTexture() const {
-  return static_cast<D3D11TextureData*>(mTextureClient->GetInternalData())->GetD3D11Texture();
+  return mTextureClient->GetD3D11Texture();
 }
 
 already_AddRefed<TextureClient>
 D3D11RecycleAllocator::Allocate(gfx::SurfaceFormat aFormat,
                                 gfx::IntSize aSize,
                                 BackendSelector aSelector,
                                 TextureFlags aTextureFlags,
                                 TextureAllocationFlags aAllocFlags)
 {
-  return CreateD3D11TextureClientWithDevice(aSize, aFormat,
-                                            aTextureFlags, aAllocFlags,
-                                            mDevice, mSurfaceAllocator);
+  return TextureClientD3D11::Create(mSurfaceAllocator,
+                                    aFormat,
+                                    TextureFlags::DEFAULT,
+                                    mDevice,
+                                    aSize);
 }
 
-already_AddRefed<TextureClient>
+already_AddRefed<TextureClientD3D11>
 D3D11RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
                                              const gfx::IntSize& aSize)
 {
   RefPtr<TextureClient> textureClient =
     CreateOrRecycle(aFormat,
                     aSize,
                     BackendSelector::Content,
                     layers::TextureFlags::DEFAULT);
-  return textureClient.forget();
+  if (!textureClient) {
+    return nullptr;
+  }
+
+  RefPtr<TextureClientD3D11> textureD3D11 = static_cast<TextureClientD3D11*>(textureClient.get());
+  return textureD3D11.forget();
 }
 
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/D3D11ShareHandleImage.h
+++ b/gfx/layers/D3D11ShareHandleImage.h
@@ -21,17 +21,17 @@ class D3D11RecycleAllocator : public Tex
 {
 public:
   explicit D3D11RecycleAllocator(CompositableForwarder* aAllocator,
                                  ID3D11Device* aDevice)
     : TextureClientRecycleAllocator(aAllocator)
     , mDevice(aDevice)
   {}
 
-  already_AddRefed<TextureClient>
+  already_AddRefed<TextureClientD3D11>
   CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
                         const gfx::IntSize& aSize);
 
 protected:
   virtual already_AddRefed<TextureClient>
   Allocate(gfx::SurfaceFormat aFormat,
            gfx::IntSize aSize,
            BackendSelector aSelector,
@@ -58,15 +58,15 @@ public:
   virtual TextureClient* GetTextureClient(CompositableClient* aClient) override;
   virtual gfx::IntRect GetPictureRect() override { return mPictureRect; }
 
   ID3D11Texture2D* GetTexture() const;
 
 private:
   gfx::IntSize mSize;
   gfx::IntRect mPictureRect;
-  RefPtr<TextureClient> mTextureClient;
+  RefPtr<TextureClientD3D11> mTextureClient;
 };
 
 } // namepace layers
 } // namespace mozilla
 
 #endif // GFX_D3DSURFACEIMAGE_H
--- a/gfx/layers/D3D9SurfaceImage.cpp
+++ b/gfx/layers/D3D9SurfaceImage.cpp
@@ -51,25 +51,24 @@ D3D9SurfaceImage::AllocateAndCopy(D3D9Re
                                          D3DDEVTYPE_HAL,
                                          desc.Format,
                                          D3DFMT_X8R8G8B8);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   // DXVA surfaces aren't created sharable, so we need to copy the surface
   // to a sharable texture to that it's accessible to the layer manager's
   // device.
-  RefPtr<TextureClient> textureClient =
+  RefPtr<SharedTextureClientD3D9> textureClient =
     aAllocator->CreateOrRecycleClient(gfx::SurfaceFormat::B8G8R8X8, aRegion.Size());
   if (!textureClient) {
     return E_FAIL;
   }
 
   // Copy the image onto the texture, preforming YUV -> RGB conversion if necessary.
-  RefPtr<IDirect3DSurface9> textureSurface = static_cast<DXGID3D9TextureData*>(
-    textureClient->GetInternalData())->GetD3D9Surface();
+  RefPtr<IDirect3DSurface9> textureSurface = textureClient->GetD3D9Surface();
   if (!textureSurface) {
     return E_FAIL;
   }
 
   RECT src = { aRegion.x, aRegion.y, aRegion.x+aRegion.width, aRegion.y+aRegion.height };
   hr = device->StretchRect(surface, &src, textureSurface, nullptr, D3DTEXF_NONE);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
@@ -117,17 +116,17 @@ D3D9SurfaceImage::EnsureSynchronized()
     break;
   }
   mQuery = nullptr;
 }
 
 const D3DSURFACE_DESC&
 D3D9SurfaceImage::GetDesc() const
 {
-  return static_cast<DXGID3D9TextureData*>(mTextureClient->GetInternalData())->GetDesc();
+  return mTextureClient->GetDesc();
 }
 
 gfx::IntSize
 D3D9SurfaceImage::GetSize()
 {
   return mSize;
 }
 
@@ -138,38 +137,35 @@ D3D9SurfaceImage::GetTextureClient(Compo
   MOZ_ASSERT(mTextureClient->GetAllocator() == aClient->GetForwarder());
   EnsureSynchronized();
   return mTextureClient;
 }
 
 already_AddRefed<gfx::SourceSurface>
 D3D9SurfaceImage::GetAsSourceSurface()
 {
-  if (!mTextureClient) {
-    return nullptr;
-  }
+  NS_ENSURE_TRUE(mTextureClient, nullptr);
 
   HRESULT hr;
   RefPtr<gfx::DataSourceSurface> surface = gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8);
   if (NS_WARN_IF(!surface)) {
     return nullptr;
   }
 
   // Ensure that the texture is ready to be used.
   EnsureSynchronized();
 
-  DXGID3D9TextureData* texData = static_cast<DXGID3D9TextureData*>(mTextureClient->GetInternalData());
   // Readback the texture from GPU memory into system memory, so that
   // we can copy it into the Cairo image. This is expensive.
-  RefPtr<IDirect3DSurface9> textureSurface = texData->GetD3D9Surface();
+  RefPtr<IDirect3DSurface9> textureSurface = mTextureClient->GetD3D9Surface();
   if (!textureSurface) {
     return nullptr;
   }
 
-  RefPtr<IDirect3DDevice9> device = texData->GetD3D9Device();
+  RefPtr<IDirect3DDevice9> device = mTextureClient->GetD3D9Device();
   if (!device) {
     return nullptr;
   }
 
   RefPtr<IDirect3DSurface9> systemMemorySurface;
   hr = device->CreateOffscreenPlainSurface(mSize.width,
                                            mSize.height,
                                            D3DFMT_X8R8G8B8,
@@ -207,26 +203,34 @@ D3D9SurfaceImage::GetAsSourceSurface()
 
 already_AddRefed<TextureClient>
 D3D9RecycleAllocator::Allocate(gfx::SurfaceFormat aFormat,
                                gfx::IntSize aSize,
                                BackendSelector aSelector,
                                TextureFlags aTextureFlags,
                                TextureAllocationFlags aAllocFlags)
 {
-  TextureData* data = DXGID3D9TextureData::Create(aSize, aFormat, aTextureFlags, mDevice);
-  if (!data) {
+  return SharedTextureClientD3D9::Create(mSurfaceAllocator,
+                                         aFormat,
+                                         aTextureFlags,
+                                         mDevice,
+                                         aSize);
+}
+
+already_AddRefed<SharedTextureClientD3D9>
+D3D9RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
+                                            const gfx::IntSize& aSize)
+{
+  RefPtr<TextureClient> textureClient =
+    CreateOrRecycle(aFormat,
+                    aSize,
+                    BackendSelector::Content,
+                    layers::TextureFlags::DEFAULT);
+  if (!textureClient) {
     return nullptr;
   }
 
-  return MakeAndAddRef<TextureClient>(data, aTextureFlags, mSurfaceAllocator);
-}
-
-already_AddRefed<TextureClient>
-D3D9RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
-                                            const gfx::IntSize& aSize)
-{
-  return CreateOrRecycle(aFormat, aSize, BackendSelector::Content,
-                         TextureFlags::DEFAULT);
+  RefPtr<SharedTextureClientD3D9> textureD3D9 = static_cast<SharedTextureClientD3D9*>(textureClient.get());
+  return textureD3D9.forget();
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/D3D9SurfaceImage.h
+++ b/gfx/layers/D3D9SurfaceImage.h
@@ -10,28 +10,28 @@
 #include "ImageContainer.h"
 #include "nsAutoPtr.h"
 #include "d3d9.h"
 #include "mozilla/layers/TextureClientRecycleAllocator.h"
 
 namespace mozilla {
 namespace layers {
 
-class TextureClient;
+class SharedTextureClientD3D9;
 
 class D3D9RecycleAllocator : public TextureClientRecycleAllocator
 {
 public:
   explicit D3D9RecycleAllocator(CompositableForwarder* aAllocator,
                                 IDirect3DDevice9* aDevice)
     : TextureClientRecycleAllocator(aAllocator)
     , mDevice(aDevice)
   {}
 
-  already_AddRefed<TextureClient>
+  already_AddRefed<SharedTextureClientD3D9>
   CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
                         const gfx::IntSize& aSize);
 
 protected:
   virtual already_AddRefed<TextureClient>
   Allocate(gfx::SurfaceFormat aFormat,
            gfx::IntSize aSize,
            BackendSelector aSelector,
@@ -68,17 +68,17 @@ public:
 private:
 
   // Blocks the calling thread until the copy operation started in SetData()
   // is complete, whereupon the texture is safe to use.
   void EnsureSynchronized();
 
   gfx::IntSize mSize;
   RefPtr<IDirect3DQuery9> mQuery;
-  RefPtr<TextureClient> mTextureClient;
+  RefPtr<SharedTextureClientD3D9> mTextureClient;
   bool mValid;
   bool mIsFirstFrame;
 };
 
 } // namepace layers
 } // namespace mozilla
 
 #endif // GFX_D3DSURFACEIMAGE_H
--- a/gfx/layers/GrallocImages.cpp
+++ b/gfx/layers/GrallocImages.cpp
@@ -68,31 +68,35 @@ GrallocImage::SetData(const Data& aData)
   mData = aData;
   mSize = aData.mPicSize;
 
   if (gfxPlatform::GetPlatform()->IsInGonkEmulator()) {
     // Emulator does not support HAL_PIXEL_FORMAT_YV12.
     return false;
   }
 
-  ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
-  GrallocTextureData* texData = GrallocTextureData::Create(mData.mYSize, HAL_PIXEL_FORMAT_YV12,
-                                                           gfx::BackendType::NONE,
-                                                           GraphicBuffer::USAGE_SW_READ_OFTEN |
-                                                             GraphicBuffer::USAGE_SW_WRITE_OFTEN |
-                                                             GraphicBuffer::USAGE_HW_TEXTURE,
-                                                           allocator
-  );
-
-  if (!texData) {
+  RefPtr<GrallocTextureClientOGL> textureClient =
+       new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
+                                   gfx::SurfaceFormat::UNKNOWN,
+                                   gfx::BackendType::NONE);
+  // GrallocImages are all YUV and don't support alpha.
+  textureClient->SetIsOpaque(true);
+  bool result =
+    textureClient->AllocateGralloc(mData.mYSize,
+                                   HAL_PIXEL_FORMAT_YV12,
+                                   GraphicBuffer::USAGE_SW_READ_OFTEN |
+                                   GraphicBuffer::USAGE_SW_WRITE_OFTEN |
+                                   GraphicBuffer::USAGE_HW_TEXTURE);
+  sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
+  if (!result || !graphicBuffer.get()) {
+    mTextureClient = nullptr;
     return false;
   }
 
-  mTextureClient = new TextureClient(texData, TextureFlags::DEFAULT, allocator);
-  sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
+  mTextureClient = textureClient;
 
   void* vaddr;
   if (graphicBuffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
                           &vaddr) != OK) {
     return false;
   }
 
   uint8_t* yChannel = static_cast<uint8_t*>(vaddr);
@@ -141,17 +145,18 @@ GrallocImage::SetData(const Data& aData)
   mData.mCrChannel    = nullptr;
   mData.mCbChannel    = nullptr;
   return true;
 }
 
 void
 GrallocImage::SetData(TextureClient* aGraphicBuffer, const gfx::IntSize& aSize)
 {
-  mTextureClient = aGraphicBuffer;
+  MOZ_ASSERT(aGraphicBuffer->AsGrallocTextureClientOGL());
+  mTextureClient = aGraphicBuffer->AsGrallocTextureClientOGL();
   mSize = aSize;
 }
 
 /**
  * Converts YVU420 semi planar frames to RGB565, possibly taking different
  * stride values.
  * Needed because the Android ColorConverter class assumes that the Y and UV
  * channels have equal stride.
@@ -433,40 +438,42 @@ GetDataSourceSurfaceFrom(android::sp<and
 
 already_AddRefed<gfx::SourceSurface>
 GrallocImage::GetAsSourceSurface()
 {
   if (!mTextureClient) {
     return nullptr;
   }
 
-  android::sp<GraphicBuffer> graphicBuffer = GetGraphicBuffer();
+  android::sp<GraphicBuffer> graphicBuffer =
+    mTextureClient->GetGraphicBuffer();
 
   RefPtr<gfx::DataSourceSurface> surface =
     GetDataSourceSurfaceFrom(graphicBuffer, mSize, mData);
 
   return surface.forget();
 }
 
 android::sp<android::GraphicBuffer>
 GrallocImage::GetGraphicBuffer() const
 {
   if (!mTextureClient) {
     return nullptr;
   }
-  return static_cast<GrallocTextureData*>(mTextureClient->GetInternalData())->GetGraphicBuffer();
+  return mTextureClient->GetGraphicBuffer();
 }
 
 void*
 GrallocImage::GetNativeBuffer()
 {
   if (!mTextureClient) {
     return nullptr;
   }
-  android::sp<android::GraphicBuffer> graphicBuffer = GetGraphicBuffer();
+  android::sp<android::GraphicBuffer> graphicBuffer =
+    mTextureClient->GetGraphicBuffer();
   if (!graphicBuffer.get()) {
     return nullptr;
   }
   return graphicBuffer->getNativeBuffer();
 }
 
 TextureClient*
 GrallocImage::GetTextureClient(CompositableClient* aClient)
--- a/gfx/layers/GrallocImages.h
+++ b/gfx/layers/GrallocImages.h
@@ -15,17 +15,17 @@
 #include "mozilla/layers/FenceUtils.h"
 #include "mozilla/layers/LayersSurfaces.h"
 
 #include <ui/GraphicBuffer.h>
 
 namespace mozilla {
 namespace layers {
 
-class TextureClient;
+class GrallocTextureClientOGL;
 
 already_AddRefed<gfx::DataSourceSurface>
 GetDataSourceSurfaceFrom(android::sp<android::GraphicBuffer>& aGraphicBuffer,
                          gfx::IntSize aSize,
                          const layers::PlanarYCbCrData& aYcbcrData);
 
 /**
  * The YUV format supported by Android HAL
@@ -119,17 +119,17 @@ public:
         break;
       }
     }
 
     return omxFormat;
   }
 
 private:
-  RefPtr<TextureClient> mTextureClient;
+  RefPtr<GrallocTextureClientOGL> mTextureClient;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
 
 #endif /* GRALLOCIMAGES_H */
--- a/gfx/layers/IMFYCbCrImage.cpp
+++ b/gfx/layers/IMFYCbCrImage.cpp
@@ -199,25 +199,27 @@ IMFYCbCrImage::GetD3D9TextureClient(Comp
     }
     break;
   }
 
   if (!valid) {
     return nullptr;
   }
 
-  mTextureClient = TextureClient::CreateWithData(
-    DXGIYCbCrTextureData::Create(aClient->GetForwarder(),
-                                 TextureFlags::DEFAULT,
-                                 textureY, textureCb, textureCr,
-                                 shareHandleY, shareHandleCb, shareHandleCr,
-                                 GetSize(), mData.mYSize, mData.mCbCrSize),
-    TextureFlags::DEFAULT,
-    aClient->GetForwarder()
-  );
+  mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(),
+                                                  TextureFlags::DEFAULT,
+                                                  textureY,
+                                                  textureCb,
+                                                  textureCr,
+                                                  shareHandleY,
+                                                  shareHandleCb,
+                                                  shareHandleCr,
+                                                  GetSize(),
+                                                  mData.mYSize,
+                                                  mData.mCbCrSize);
 
   return mTextureClient;
 }
 
 TextureClient*
 IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
 {
   LayersBackend backend = aClient->GetForwarder()->GetCompositorBackendType();
@@ -266,22 +268,22 @@ IMFYCbCrImage::GetTextureClient(Composit
     ctx->UpdateSubresource(textureY, 0, nullptr, mData.mYChannel,
                            mData.mYStride, mData.mYStride * mData.mYSize.height);
     ctx->UpdateSubresource(textureCb, 0, nullptr, mData.mCbChannel,
                            mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height);
     ctx->UpdateSubresource(textureCr, 0, nullptr, mData.mCrChannel,
                            mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height);
   }
 
-  mTextureClient = TextureClient::CreateWithData(
-    DXGIYCbCrTextureData::Create(aClient->GetForwarder(),
-                                 TextureFlags::DEFAULT,
-                                 textureY, textureCb, textureCr,
-                                 GetSize(), mData.mYSize, mData.mCbCrSize),
-    TextureFlags::DEFAULT,
-    aClient->GetForwarder()
-  );
+  mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(),
+                                                  TextureFlags::DEFAULT,
+                                                  textureY,
+                                                  textureCb,
+                                                  textureCr,
+                                                  GetSize(),
+                                                  mData.mYSize,
+                                                  mData.mCbCrSize);
 
   return mTextureClient;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ImageDataSerializer.h
+++ b/gfx/layers/ImageDataSerializer.h
@@ -34,18 +34,16 @@ public:
   gfx::IntSize GetSize() const;
   gfx::SurfaceFormat GetFormat() const;
   already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
   already_AddRefed<gfx::DrawTarget> GetAsDrawTarget(gfx::BackendType aBackend);
 
   static uint32_t ComputeMinBufferSize(gfx::IntSize aSize,
                                        gfx::SurfaceFormat aFormat);
 
-  size_t GetBufferSize() const { return mDataSize; }
-
 protected:
 
   ImageDataSerializerBase(uint8_t* aData, size_t aDataSize)
     : mData(aData)
     , mDataSize(aDataSize)
     , mIsValid(false)
   {}
 
--- a/gfx/layers/LayersLogging.cpp
+++ b/gfx/layers/LayersLogging.cpp
@@ -8,17 +8,16 @@
 #include "LayersLogging.h"
 #include <stdint.h>                     // for uint8_t
 #include "ImageTypes.h"                 // for ImageFormat
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4, Matrix
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "nsDebug.h"                    // for NS_ERROR
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsRect.h"                     // for mozilla::gfx::IntRect
-#include "base/basictypes.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 void
 AppendToString(std::stringstream& aStream, const void* p,
--- a/gfx/layers/MacIOSurfaceImage.cpp
+++ b/gfx/layers/MacIOSurfaceImage.cpp
@@ -13,21 +13,19 @@
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 TextureClient*
 MacIOSurfaceImage::GetTextureClient(CompositableClient* aClient)
 {
   if (!mTextureClient) {
-    mTextureClient = TextureClient::CreateWithData(
-      MacIOSurfaceTextureData::Create(mSurface),
-      TextureFlags::DEFAULT,
-      aClient->GetForwarder()
-    );
+    mTextureClient = MacIOSurfaceTextureClientOGL::Create(aClient->GetForwarder(),
+                                                          TextureFlags::DEFAULT,
+                                                          mSurface);
   }
   return mTextureClient;
 }
 
 already_AddRefed<SourceSurface>
 MacIOSurfaceImage::GetAsSourceSurface()
 {
   RefPtr<DataSourceSurface> dataSurface;
--- a/gfx/layers/TextureDIB.cpp
+++ b/gfx/layers/TextureDIB.cpp
@@ -9,299 +9,271 @@
 #include "mozilla/ipc/ProtocolUtils.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
-/**
-  * Can only be drawn into through Cairo.
-  * The coresponding TextureHost depends on the compositor
-  */
-class MemoryDIBTextureData : public DIBTextureData
+bool
+TextureClientDIB::Lock(OpenMode)
 {
-public:
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
-
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags = TextureFlags::DEFAULT,
-                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
+  MOZ_ASSERT(!mIsLocked);
+  if (!IsValid()) {
+    return false;
+  }
+  mIsLocked = true;
+  return true;
+}
 
-  static
-  DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
+void
+TextureClientDIB::Unlock()
+{
+  MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
+  if (mDrawTarget) {
+    if (mReadbackSink) {
+      RefPtr<SourceSurface> snapshot = mDrawTarget->Snapshot();
+      RefPtr<DataSourceSurface> dataSurf = snapshot->GetDataSurface();
+      mReadbackSink->ProcessReadback(dataSurf);
+    }
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override
-  {
-    mSurface = nullptr;
-  }
-
-  MemoryDIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                       gfxWindowsSurface* aSurface)
-  : DIBTextureData(aSize, aFormat, aSurface)
-  {
-    MOZ_COUNT_CTOR(MemoryDIBTextureData);
+    mDrawTarget->Flush();
+    mDrawTarget = nullptr;
   }
 
-  virtual ~MemoryDIBTextureData()
-  {
-    MOZ_COUNT_DTOR(MemoryDIBTextureData);
-  }
-};
-
-/**
-  * Can only be drawn into through Cairo.
-  * The coresponding TextureHost depends on the compositor
-  */
-class ShmemDIBTextureData : public DIBTextureData
-{
-public:
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
+  mIsLocked = false;
+}
 
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags = TextureFlags::DEFAULT,
-                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
-
-  static
-  DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                         ISurfaceAllocator* aAllocator);
+gfx::DrawTarget*
+TextureClientDIB::BorrowDrawTarget()
+{
+  MOZ_ASSERT(mIsLocked && IsAllocated());
 
-  void DeallocateData()
-  {
-    if (mSurface) {
-      ::DeleteObject(mBitmap);
-      ::DeleteDC(mDC);
-      ::CloseHandle(mFileMapping);
-      mBitmap = NULL;
-      mDC = NULL;
-      mFileMapping = NULL;
-      mSurface = nullptr;
-    }
+  if (!mDrawTarget) {
+    mDrawTarget =
+      gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface, mSize);
   }
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override
-  {
-    DeallocateData();
-  }
-
-  ShmemDIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                      gfxWindowsSurface* aSurface,
-                      HANDLE aFileMapping, HANDLE aHostHandle,
-                      HDC aDC, HBITMAP aBitmap)
-  : DIBTextureData(aSize, aFormat, aSurface)
-  , mFileMapping(aFileMapping)
-  , mHostHandle(aHostHandle)
-  , mDC(aDC)
-  , mBitmap(aBitmap)
-  {
-    MOZ_COUNT_CTOR(ShmemDIBTextureData);
+  if (!mDrawTarget) {
+    gfxCriticalNote << "DIB failed draw target surface " << mSize << ", " << (int)mIsLocked << ", " << IsAllocated();
   }
 
-  virtual ~ShmemDIBTextureData() 
-  {
-    MOZ_COUNT_DTOR(ShmemDIBTextureData);
-  }
-
-  HANDLE mFileMapping;
-  HANDLE mHostHandle;
-  HDC mDC;
-  HBITMAP mBitmap;
-};
-
-already_AddRefed<gfx::DrawTarget>
-DIBTextureData::BorrowDrawTarget()
-{
-  return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface, mSize);
+  return mDrawTarget;
 }
 
-bool
-DIBTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
+void
+TextureClientDIB::UpdateFromSurface(gfx::SourceSurface* aSurface)
 {
+  MOZ_ASSERT(mIsLocked && IsAllocated());
+
   RefPtr<gfxImageSurface> imgSurf = mSurface->GetAsImageSurface();
 
   RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
 
   if (!srcSurf) {
     gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
-    return false;
+    return;
   }
 
   DataSourceSurface::MappedSurface sourceMap;
   srcSurf->Map(DataSourceSurface::READ, &sourceMap);
 
   for (int y = 0; y < srcSurf->GetSize().height; y++) {
     memcpy(imgSurf->Data() + imgSurf->Stride() * y,
            sourceMap.mData + sourceMap.mStride * y,
            srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
   }
 
   srcSurf->Unmap();
-  return true;
+}
+
+TextureClientMemoryDIB::TextureClientMemoryDIB(ISurfaceAllocator* aAllocator,
+                                   gfx::SurfaceFormat aFormat,
+                                   TextureFlags aFlags)
+  : TextureClientDIB(aAllocator, aFormat, aFlags)
+{
+  MOZ_COUNT_CTOR(TextureClientMemoryDIB);
 }
 
-DIBTextureData*
-DIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                       ISurfaceAllocator* aAllocator)
+TextureClientMemoryDIB::~TextureClientMemoryDIB()
 {
-  if (!aAllocator) {
-    return nullptr;
-  }
-  if (aFormat == gfx::SurfaceFormat::UNKNOWN) {
+  MOZ_COUNT_DTOR(TextureClientMemoryDIB);
+}
+
+already_AddRefed<TextureClient>
+TextureClientMemoryDIB::CreateSimilar(TextureFlags aFlags,
+                                      TextureAllocationFlags aAllocFlags) const
+{
+  RefPtr<TextureClient> tex = new TextureClientMemoryDIB(mAllocator, mFormat,
+                                                         mFlags | aFlags);
+
+  if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
     return nullptr;
   }
-  if (aAllocator->IsSameProcess()) {
-    return MemoryDIBTextureData::Create(aSize, aFormat);
-  } else {
-    return ShmemDIBTextureData::Create(aSize, aFormat, aAllocator);
-  }
-}
 
-TextureData*
-MemoryDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
-                                    TextureFlags aFlags,
-                                    TextureAllocationFlags aAllocFlags) const
-{
-  if (!aAllocator) {
-    return nullptr;
-  }
-  return MemoryDIBTextureData::Create(mSize, mFormat);
+  return tex.forget();
 }
 
 bool
-MemoryDIBTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+TextureClientMemoryDIB::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
+  MOZ_ASSERT(IsValid());
+  if (!IsAllocated()) {
+    return false;
+  }
+
   MOZ_ASSERT(mSurface);
   // The host will release this ref when it receives the surface descriptor.
   // We AddRef in case we die before the host receives the pointer.
   aOutDescriptor = SurfaceDescriptorDIB(reinterpret_cast<uintptr_t>(mSurface.get()));
   mSurface->AddRef();
   return true;
 }
 
-DIBTextureData*
-MemoryDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat)
+bool
+TextureClientMemoryDIB::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
 {
-  RefPtr<gfxWindowsSurface> surface
-    = new gfxWindowsSurface(aSize, SurfaceFormatToImageFormat(aFormat));
-  if (!surface || surface->CairoStatus()) {
-    NS_WARNING("Could not create DIB surface");
+  MOZ_ASSERT(!IsAllocated());
+  mSize = aSize;
+
+  mSurface = new gfxWindowsSurface(aSize, SurfaceFormatToImageFormat(mFormat));
+  if (!mSurface || mSurface->CairoStatus())
+  {
+    NS_WARNING("Could not create surface");
+    mSurface = nullptr;
+    return false;
+  }
+
+  return true;
+}
+
+TextureClientShmemDIB::TextureClientShmemDIB(ISurfaceAllocator* aAllocator,
+                                             gfx::SurfaceFormat aFormat,
+                                             TextureFlags aFlags)
+  : TextureClientDIB(aAllocator, aFormat, aFlags)
+  , mFileMapping(NULL)
+  , mHostHandle(NULL)
+  , mDC(NULL)
+  , mBitmap(NULL)
+{
+  MOZ_COUNT_CTOR(TextureClientShmemDIB);
+}
+
+TextureClientShmemDIB::~TextureClientShmemDIB()
+{
+  MOZ_COUNT_DTOR(TextureClientShmemDIB);
+
+  ::DeleteObject(mBitmap);
+  ::DeleteDC(mDC);
+  ::CloseHandle(mFileMapping);
+}
+
+already_AddRefed<TextureClient>
+TextureClientShmemDIB::CreateSimilar(TextureFlags aFlags,
+                                     TextureAllocationFlags aAllocFlags) const
+{
+  RefPtr<TextureClient> tex = new TextureClientShmemDIB(mAllocator, mFormat,
+                                                        mFlags | aFlags);
+
+  if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
     return nullptr;
   }
 
-  return new MemoryDIBTextureData(aSize, aFormat, surface);
-}
-
-TextureData*
-ShmemDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
-                                   TextureFlags aFlags,
-                                   TextureAllocationFlags aAllocFlags) const
-{
-  if (!aAllocator) {
-    return nullptr;
-  }
-  return ShmemDIBTextureData::Create(mSize, mFormat, aAllocator);
+  return tex.forget();
 }
 
 bool
-ShmemDIBTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+TextureClientShmemDIB::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
-  if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
+  MOZ_ASSERT(IsValid());
+  MOZ_ASSERT(mAllocator->ParentPid() != base::ProcessId());
+  if (!IsAllocated() || GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
     return false;
   }
 
   ::GdiFlush();
   aOutDescriptor = SurfaceDescriptorFileMapping((WindowsHandle)mHostHandle, mFormat, mSize);
   return true;
 }
 
-DIBTextureData*
-ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                            ISurfaceAllocator* aAllocator)
+bool
+TextureClientShmemDIB::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
 {
-  MOZ_ASSERT(aAllocator->ParentPid() != base::ProcessId());
+  MOZ_ASSERT(!IsAllocated());
+  MOZ_ASSERT(mAllocator->ParentPid() != base::ProcessId());
 
-  DWORD mapSize = aSize.width * aSize.height * BytesPerPixel(aFormat);
-  HANDLE fileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, mapSize, NULL);
+  mSize = aSize;
 
-  if (!fileMapping) {
+  DWORD mapSize = mSize.width * mSize.height * BytesPerPixel(mFormat);
+  mFileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, mapSize, NULL);
+
+  if (!mFileMapping) {
     gfxCriticalError() << "Failed to create memory file mapping for " << mapSize << " bytes.";
-    return nullptr;
+    return false;
   }
 
-  uint8_t* data = (uint8_t*)::MapViewOfFile(fileMapping, FILE_MAP_WRITE | FILE_MAP_READ,
-                                            0, 0, aSize.width * aSize.height
-                                                  * BytesPerPixel(aFormat));
+  uint8_t* data = (uint8_t*)::MapViewOfFile(mFileMapping, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, mSize.width * mSize.height * BytesPerPixel(mFormat));
 
-  memset(data, 0x80, aSize.width * aSize.height * BytesPerPixel(aFormat));
+  memset(data, 0x80, mSize.width * mSize.height * BytesPerPixel(mFormat));
 
-  ::UnmapViewOfFile(fileMapping);
+  ::UnmapViewOfFile(mFileMapping);
 
   BITMAPV4HEADER header;
   memset(&header, 0, sizeof(BITMAPV4HEADER));
   header.bV4Size          = sizeof(BITMAPV4HEADER);
-  header.bV4Width         = aSize.width;
-  header.bV4Height        = -LONG(aSize.height); // top-to-buttom DIB
+  header.bV4Width         = mSize.width;
+  header.bV4Height        = -LONG(mSize.height); // top-to-buttom DIB
   header.bV4Planes        = 1;
   header.bV4BitCount      = 32;
   header.bV4V4Compression = BI_BITFIELDS;
   header.bV4RedMask       = 0x00FF0000;
   header.bV4GreenMask     = 0x0000FF00;
   header.bV4BlueMask      = 0x000000FF;
 
-  HDC dc = ::CreateCompatibleDC(::GetDC(NULL));
+  mDC = ::CreateCompatibleDC(::GetDC(NULL));
 
-  if (!dc) {
-    ::CloseHandle(fileMapping);
+  if (!mDC) {
+    ::CloseHandle(mFileMapping);
     gfxCriticalError() << "Failed to create DC for bitmap.";
-    return nullptr;
+    return false;
   }
 
   void* bits;
-  HBITMAP bitmap = ::CreateDIBSection(dc, (BITMAPINFO*)&header,
-                                      DIB_RGB_COLORS, &bits,
-                                      fileMapping, 0);
+  mBitmap = ::CreateDIBSection(mDC, (BITMAPINFO*)&header, DIB_RGB_COLORS, &bits, mFileMapping, 0);
 
-  if (!bitmap) {
-    gfxCriticalError() << "Failed to create DIB section for a bitmap of size "
-                       << aSize;
-    ::CloseHandle(fileMapping);
-    ::DeleteDC(dc);
-    return nullptr;
+  if (!mBitmap) {
+    gfxCriticalError() << "Failed to create DIB section for a bitmap of size " << mSize;
+    ::CloseHandle(mFileMapping);
+    ::DeleteDC(mDC);
+    return false;
   }
 
-  ::SelectObject(dc, bitmap);
+  ::SelectObject(mDC, mBitmap);
 
-  RefPtr<gfxWindowsSurface> surface = new gfxWindowsSurface(dc, 0);
-  if (surface->CairoStatus())
+  mSurface = new gfxWindowsSurface(mDC, 0);
+  if (mSurface->CairoStatus())
   {
-    ::DeleteObject(bitmap);
-    ::DeleteDC(dc);
-    ::CloseHandle(fileMapping);
-    gfxCriticalError() << "Could not create surface, status: "
-                       << surface->CairoStatus();
-    return nullptr;
+    ::DeleteObject(mBitmap);
+    ::DeleteDC(mDC);
+    ::CloseHandle(mFileMapping);
+    gfxCriticalError() << "Could not create surface, status: " << mSurface->CairoStatus();
+    mSurface = nullptr;
+    return false;
   }
 
-  HANDLE hostHandle = NULL;
-
-  if (!ipc::DuplicateHandle(fileMapping, aAllocator->ParentPid(),
-                            &hostHandle, 0, DUPLICATE_SAME_ACCESS)) {
+  if (!ipc::DuplicateHandle(mFileMapping, mAllocator->ParentPid(), &mHostHandle, 0, DUPLICATE_SAME_ACCESS)) {
     gfxCriticalError() << "Failed to duplicate handle to parent process for surface.";
-    ::DeleteObject(bitmap);
-    ::DeleteDC(dc);
-    ::CloseHandle(fileMapping);
-    return nullptr;
+    ::DeleteObject(mBitmap);
+    ::DeleteDC(mDC);
+    ::CloseHandle(mFileMapping);
+    return false;
   }
 
-  return new ShmemDIBTextureData(aSize, aFormat, surface,
-                                 fileMapping, hostHandle,
-                                 dc, bitmap);
+  return true;
 }
 
 
 bool
 TextureHostDirectUpload::Lock()
 {
   MOZ_ASSERT(!mIsLocked);
   mIsLocked = true;
--- a/gfx/layers/TextureDIB.h
+++ b/gfx/layers/TextureDIB.h
@@ -10,52 +10,111 @@
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/GfxMessageUtils.h"
 #include "gfxWindowsPlatform.h"
 
 namespace mozilla {
 namespace layers {
 
-class DIBTextureData : public TextureData
+class TextureClientDIB : public TextureClient
 {
 public:
-  virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
+  virtual bool IsAllocated() const override { return !!mSurface; }
+
+  virtual bool Lock(OpenMode aOpenMode) override;
 
-  virtual void Unlock() override {}
+  virtual void Unlock() override;
+
+  virtual bool IsLocked() const override{ return mIsLocked; }
 
   virtual gfx::IntSize GetSize() const override { return mSize; }
 
   virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
 
-  virtual bool SupportsMoz2D() const override { return true; }
+  virtual bool CanExposeDrawTarget() const override { return true; }
 
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
+  virtual gfx::DrawTarget* BorrowDrawTarget() override;
 
-  virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
+  virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
   virtual bool HasInternalBuffer() const override { return true; }
 
-  static
-  DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                         ISurfaceAllocator* aAllocator);
+protected:
+  TextureClientDIB(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat, TextureFlags aFlags)
+    : TextureClient(aAllocator, aFlags)
+    , mFormat(aFormat)
+    , mIsLocked(false)
+  { }
+
+  RefPtr<gfxWindowsSurface> mSurface;
+  RefPtr<gfx::DrawTarget> mDrawTarget;
+  gfx::IntSize mSize;
+  gfx::SurfaceFormat mFormat;
+  bool mIsLocked;
+};
+
+/**
+  * Can only be drawn into through Cairo.
+  * Prefer CairoTextureClient when possible.
+  * The coresponding TextureHost depends on the compositor
+  */
+class TextureClientMemoryDIB : public TextureClientDIB
+{
+public:
+  TextureClientMemoryDIB(ISurfaceAllocator* aAllocator,
+                         gfx::SurfaceFormat aFormat,
+                         TextureFlags aFlags);
+
+  virtual ~TextureClientMemoryDIB();
+
+  // TextureClient
+
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
+
+  virtual bool AllocateForSurface(gfx::IntSize aSize,
+    TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
+
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
+                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
+
+
+};
+
+/**
+  * Can only be drawn into through Cairo.
+  * Prefer CairoTextureClient when possible.
+  * The coresponding TextureHost depends on the compositor
+  */
+class TextureClientShmemDIB : public TextureClientDIB
+{
+public:
+  TextureClientShmemDIB(ISurfaceAllocator* aAllocator,
+                        gfx::SurfaceFormat aFormat,
+                        TextureFlags aFlags);
+
+  virtual ~TextureClientShmemDIB();
+
+  // TextureClient
+
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
+
+  virtual bool AllocateForSurface(gfx::IntSize aSize,
+    TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
+
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
+                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
 protected:
-  DIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                 gfxWindowsSurface* aSurface)
-  : mSurface(aSurface)
-  , mSize(aSize)
-  , mFormat(aFormat)
-  {
-    MOZ_ASSERT(aSurface);
-  }
-
-  RefPtr<gfxWindowsSurface> mSurface;
-  gfx::IntSize mSize;
-  gfx::SurfaceFormat mFormat;
+  HANDLE mFileMapping;
+  HANDLE mHostHandle;
+  HDC mDC;
+  HBITMAP mBitmap;
 };
 
 /**
   * This is meant for a texture host which does a direct upload from
   * Updated to a Compositor specific DataTextureSource and therefor doesn't
   * need any specific Lock/Unlock magic.
   */
 class TextureHostDirectUpload : public TextureHost
--- a/gfx/layers/YCbCrImageDataSerializer.cpp
+++ b/gfx/layers/YCbCrImageDataSerializer.cpp
@@ -70,17 +70,17 @@ void YCbCrImageDataDeserializerBase::Val
   if (!info) {
     return;
   }
   size_t requiredSize = ComputeMinBufferSize(
                           IntSize(info->mYWidth, info->mYHeight),
                           info->mYStride,
                           IntSize(info->mCbCrWidth, info->mCbCrHeight),
                           info->mCbCrStride);
-  mIsValid = requiredSize <= mDataSize;
+  mIsValid = requiredSize && requiredSize <= mDataSize;
 
 }
 
 uint8_t* YCbCrImageDataDeserializerBase::GetYData()
 {
   YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return reinterpret_cast<uint8_t*>(info) + info->mYOffset;
 }
@@ -142,25 +142,24 @@ static size_t ComputeOffset(uint32_t aHe
 // Minimum required shmem size in bytes
 size_t
 YCbCrImageDataDeserializerBase::ComputeMinBufferSize(const gfx::IntSize& aYSize,
                                                      uint32_t aYStride,
                                                      const gfx::IntSize& aCbCrSize,
                                                      uint32_t aCbCrStride)
 {
   MOZ_ASSERT(aYSize.height >= 0 && aYSize.width >= 0);
-  if (aYSize.height < 0 || aYSize.width < 0 || aCbCrSize.height < 0 || aCbCrSize.width < 0) {
+  if (aYSize.height <= 0 || aYSize.width <= 0 || aCbCrSize.height <= 0 || aCbCrSize.width <= 0) {
     gfxDebug() << "Non-positive YCbCr buffer size request " << aYSize.height << "x" << aYSize.width << ", " << aCbCrSize.height << "x" << aCbCrSize.width;
     return 0;
   }
 
-  if (aYSize != IntSize() &&
-      (!gfx::Factory::AllowedSurfaceSize(aYSize) ||
-       aCbCrSize.width > aYSize.width ||
-       aCbCrSize.height > aYSize.height)) {
+  if (!gfx::Factory::AllowedSurfaceSize(aYSize) ||
+      aCbCrSize.width > aYSize.width ||
+      aCbCrSize.height > aYSize.height) {
     return 0;
   }
 
   return ComputeOffset(aYSize.height, aYStride)
          + 2 * ComputeOffset(aCbCrSize.height, aCbCrStride)
          + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
 }
 
--- a/gfx/layers/basic/GrallocTextureHostBasic.cpp
+++ b/gfx/layers/basic/GrallocTextureHostBasic.cpp
@@ -9,17 +9,17 @@
 
 #if ANDROID_VERSION >= 17
 #include <ui/Fence.h>
 #endif
 
 namespace mozilla {
 namespace layers {
 
-static gfx::SurfaceFormat
+static SurfaceFormat
 HalFormatToSurfaceFormat(int aHalFormat, TextureFlags aFlags)
 {
   bool swapRB = bool(aFlags & TextureFlags::RB_SWAPPED);
   switch (aHalFormat) {
   case android::PIXEL_FORMAT_BGRA_8888:
     return swapRB ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::B8G8R8A8;
   case android::PIXEL_FORMAT_RGBA_8888:
     return swapRB ? gfx::SurfaceFormat::B8G8R8A8 : gfx::SurfaceFormat::R8G8B8A8;
@@ -40,17 +40,17 @@ HalFormatToSurfaceFormat(int aHalFormat,
       return gfx::SurfaceFormat::R5G6B5_UINT16;
   default:
     if (aHalFormat >= 0x100 && aHalFormat <= 0x1FF) {
       // Reserved range for HAL specific formats.
       // Needs convert to RGB565
       return gfx::SurfaceFormat::R5G6B5_UINT16;
     } else {
       MOZ_CRASH("Unhandled HAL pixel format");
-      return gfx::SurfaceFormat::UNKNOWN; // not reached
+      return SurfaceFormat::UNKNOWN; // not reached
     }
   }
 }
 
 static bool
 NeedsConvertFromYUVtoRGB565(int aHalFormat)
 {
   switch (aHalFormat) {
@@ -129,17 +129,17 @@ GrallocTextureHostBasic::Lock()
     uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN;
     int32_t rv = graphicBuffer->lock(usage,
                                      reinterpret_cast<void**>(&mMappedBuffer));
     if (rv) {
       mMappedBuffer = nullptr;
       NS_WARNING("Couldn't lock graphic buffer");
       return false;
     }
-    surf = gfx::Factory::CreateWrappingDataSourceSurface(
+    surf = Factory::CreateWrappingDataSourceSurface(
              mMappedBuffer,
              graphicBuffer->getStride() * gfx::BytesPerPixel(mFormat),
              mCropSize,
              mFormat);
   }
   mTextureSource = mCompositor->CreateDataTextureSource(mFlags);
   mTextureSource->Update(surf, nullptr);
   return true;
@@ -212,17 +212,17 @@ GrallocTextureHostBasic::WaitAcquireFenc
     NS_ERROR("failed to wait fence complete");
   }
 #endif
 }
 
 void
 GrallocTextureHostBasic::SetCropRect(nsIntRect aCropRect)
 {
-  MOZ_ASSERT(aCropRect.TopLeft() == gfx::IntPoint(0, 0));
+  MOZ_ASSERT(aCropRect.TopLeft() == IntPoint(0, 0));
   MOZ_ASSERT(!aCropRect.IsEmpty());
   MOZ_ASSERT(aCropRect.width <= mSize.width);
   MOZ_ASSERT(aCropRect.height <= mSize.height);
 
   gfx::IntSize cropSize(aCropRect.width, aCropRect.height);
   if (mCropSize == cropSize) {
     return;
   }
--- a/gfx/layers/basic/TextureClientX11.cpp
+++ b/gfx/layers/basic/TextureClientX11.cpp
@@ -12,134 +12,158 @@
 #include "gfxXlibSurface.h"
 #include "gfx2DGlue.h"
 
 #include "mozilla/X11Util.h"
 #include <X11/Xlib.h>
 
 using namespace mozilla;
 using namespace mozilla::gfx;
+using namespace mozilla::layers;
 
-namespace mozilla {
-namespace layers {
+TextureClientX11::TextureClientX11(ISurfaceAllocator* aAllocator,
+                                   SurfaceFormat aFormat,
+                                   TextureFlags aFlags)
+  : TextureClient(aAllocator, aFlags),
+    mFormat(aFormat),
+    mLocked(false)
+{
+  MOZ_COUNT_CTOR(TextureClientX11);
+}
 
-X11TextureData::X11TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                               bool aClientDeallocation, bool aIsCrossProcess,
-                               gfxXlibSurface* aSurface)
-: mSize(aSize)
-, mFormat(aFormat)
-, mSurface(aSurface)
-, mClientDeallocation(aClientDeallocation)
-, mIsCrossProcess(aIsCrossProcess)
+TextureClientX11::~TextureClientX11()
+{
+  MOZ_COUNT_DTOR(TextureClientX11);
+}
+
+already_AddRefed<TextureClient>
+TextureClientX11::CreateSimilar(TextureFlags aFlags,
+                                TextureAllocationFlags aAllocFlags) const
 {
-  MOZ_ASSERT(mSurface);
+  RefPtr<TextureClient> tex = new TextureClientX11(mAllocator, mFormat, mFlags);
+
+  // mSize is guaranteed to be non-negative
+  MOZ_ASSERT(mSize.width >= 0 && mSize.height >= 0);
+  if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
+    return nullptr;
+  }
+
+  return tex.forget();
 }
 
 bool
-X11TextureData::Lock(OpenMode aMode, FenceHandle*)
+TextureClientX11::IsAllocated() const
 {
-  return true;
+  return !!mSurface;
+}
+
+bool
+TextureClientX11::Lock(OpenMode aMode)
+{
+  MOZ_ASSERT(!mLocked, "The TextureClient is already Locked!");
+  mLocked = IsValid() && IsAllocated();
+  return mLocked;
 }
 
 void
-X11TextureData::Unlock()
+TextureClientX11::Unlock()
 {
-  if (mSurface && mIsCrossProcess) {
+  MOZ_ASSERT(mLocked, "The TextureClient is already Unlocked!");
+  mLocked = false;
+
+  if (mDrawTarget) {
+    // see the comment on TextureClient::BorrowDrawTarget.
+    // This DrawTarget is internal to the TextureClient and is only exposed to the
+    // outside world between Lock() and Unlock(). This assertion checks that no outside
+    // reference remains by the time Unlock() is called.
+    MOZ_ASSERT(mDrawTarget->refCount() == 1);
+
+    mDrawTarget->Flush();
+    mDrawTarget = nullptr;
+  }
+
+  if (mSurface && !mAllocator->IsSameProcess()) {
     FinishX(DefaultXDisplay());
   }
 }
 
-
 bool
-X11TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+TextureClientX11::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
-  MOZ_ASSERT(mSurface);
+  MOZ_ASSERT(IsValid());
   if (!mSurface) {
     return false;
   }
 
-  if (!mClientDeallocation) {
+  if (!(mFlags & TextureFlags::DEALLOCATE_CLIENT)) {
     // Pass to the host the responsibility of freeing the pixmap. ReleasePixmap means
     // the underlying pixmap will not be deallocated in mSurface's destructor.
     // ToSurfaceDescriptor is at most called once per TextureClient.
     mSurface->ReleasePixmap();
   }
 
   aOutDescriptor = SurfaceDescriptorX11(mSurface);
   return true;
 }
 
-already_AddRefed<gfx::DrawTarget>
-X11TextureData::BorrowDrawTarget()
+bool
+TextureClientX11::AllocateForSurface(IntSize aSize, TextureAllocationFlags aTextureFlags)
 {
-  MOZ_ASSERT(mSurface);
-  if (!mSurface) {
-    return nullptr;
-  }
-
-  IntSize size = mSurface->GetSize();
-  RefPtr<gfx::DrawTarget> dt = Factory::CreateDrawTargetForCairoSurface(mSurface->CairoSurface(), size);
-
-  return dt.forget();
-}
-
-bool
-X11TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
-{
-  RefPtr<DrawTarget> dt = BorrowDrawTarget();
-
-  if (!dt) {
-    return false;
-  }
+  MOZ_ASSERT(IsValid());
+  MOZ_ASSERT(!IsAllocated());
+  //MOZ_ASSERT(mFormat != gfx::FORMAT_YUV, "This TextureClient cannot use YCbCr data");
 
-  dt->CopySurface(aSurface, IntRect(IntPoint(), aSurface->GetSize()), IntPoint());
-
-  return true;
-}
-
-void
-X11TextureData::Deallocate(ISurfaceAllocator*)
-{
-  mSurface = nullptr;
-}
-
-TextureData*
-X11TextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
-                              TextureFlags aFlags,
-                              TextureAllocationFlags aAllocFlags) const
-{
-  return X11TextureData::Create(mSize, mFormat, aFlags, aAllocator);
-}
-
-X11TextureData*
-X11TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                       TextureFlags aFlags, ISurfaceAllocator* aAllocator)
-{
   MOZ_ASSERT(aSize.width >= 0 && aSize.height >= 0);
   if (aSize.width <= 0 || aSize.height <= 0 ||
       aSize.width > XLIB_IMAGE_SIDE_SIZE_LIMIT ||
       aSize.height > XLIB_IMAGE_SIDE_SIZE_LIMIT) {
     gfxDebug() << "Asking for X11 surface of invalid size " << aSize.width << "x" << aSize.height;
-    return nullptr;
+    return false;
   }
-  gfxImageFormat imageFormat = SurfaceFormatToImageFormat(aFormat);
+  gfxImageFormat imageFormat = SurfaceFormatToImageFormat(mFormat);
   RefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, imageFormat);
   if (!surface || surface->GetType() != gfxSurfaceType::Xlib) {
     NS_ERROR("creating Xlib surface failed!");
+    return false;
+  }
+
+  mSize = aSize;
+  mSurface = static_cast<gfxXlibSurface*>(surface.get());
+
+  if (!mAllocator->IsSameProcess()) {
+    FinishX(DefaultXDisplay());
+  }
+
+  return true;
+}
+
+DrawTarget*
+TextureClientX11::BorrowDrawTarget()
+{
+  MOZ_ASSERT(IsValid());
+  MOZ_ASSERT(mLocked);
+
+  if (!mSurface) {
     return nullptr;
   }
 
-  gfxXlibSurface* xlibSurface = static_cast<gfxXlibSurface*>(surface.get());
-
-  bool crossProcess = !aAllocator->IsSameProcess();
-  X11TextureData* texture = new X11TextureData(aSize, aFormat,
-                                               !!(aFlags & TextureFlags::DEALLOCATE_CLIENT),
-                                               crossProcess,
-                                               xlibSurface);
-  if (crossProcess) {
-    FinishX(DefaultXDisplay());
+  if (!mDrawTarget) {
+    IntSize size = mSurface->GetSize();
+    mDrawTarget = Factory::CreateDrawTargetForCairoSurface(mSurface->CairoSurface(), size);
   }
 
-  return texture;
+  return mDrawTarget;
 }
 
-} // namespace
-} // namespace
+void
+TextureClientX11::UpdateFromSurface(gfx::SourceSurface* aSurface)
+{
+  MOZ_ASSERT(CanExposeDrawTarget());
+
+  DrawTarget* dt = BorrowDrawTarget();
+
+  if (!dt) {
+    gfxCriticalError() << "Failed to borrow drawtarget for TextureClientX11::UpdateFromSurface";
+    return;
+  }
+
+  dt->CopySurface(aSurface, IntRect(IntPoint(), aSurface->GetSize()), IntPoint());
+}
\ No newline at end of file
--- a/gfx/layers/basic/TextureClientX11.h
+++ b/gfx/layers/basic/TextureClientX11.h
@@ -8,55 +8,60 @@
 
 #include "mozilla/layers/TextureClient.h"
 #include "ISurfaceAllocator.h" // For IsSurfaceDescriptorValid
 #include "mozilla/layers/ShadowLayerUtilsX11.h"
 
 namespace mozilla {
 namespace layers {
 
-class X11TextureData : public TextureData
+/**
+ * A TextureClient implementation based on Xlib.
+ */
+class TextureClientX11 : public TextureClient
 {
-public:
-  static X11TextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                TextureFlags aFlags, ISurfaceAllocator* aAllocator);
+ public:
+  TextureClientX11(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat format, TextureFlags aFlags = TextureFlags::DEFAULT);
+
+  ~TextureClientX11();
+
+  // TextureClient
 
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
+  virtual bool IsAllocated() const override;
+
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
 
-  virtual bool Lock(OpenMode aMode, FenceHandle*) override;
+  virtual gfx::IntSize GetSize() const override { return mSize; }
+
+  virtual bool Lock(OpenMode aMode) override;
 
   virtual void Unlock() override;
 
-  virtual gfx::IntSize GetSize() const override { return mSize; }
+  virtual bool IsLocked() const override { return mLocked; }
+
+  virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags flags) override;
+
+  virtual bool CanExposeDrawTarget() const override { return true; }
+
+  virtual gfx::DrawTarget* BorrowDrawTarget() override;
+
+  virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
   virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
 
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
-
-  virtual bool SupportsMoz2D() const override { return true; }
-
   virtual bool HasInternalBuffer() const override { return false; }
 
-  virtual void Deallocate(ISurfaceAllocator*) override;
-
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags = TextureFlags::DEFAULT,
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
-  virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
-
-protected:
-  X11TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                 bool aClientDeallocation, bool aIsCrossProcess,
-                 gfxXlibSurface* aSurface);
-
+ private:
+  gfx::SurfaceFormat mFormat;
   gfx::IntSize mSize;
-  gfx::SurfaceFormat mFormat;
   RefPtr<gfxXlibSurface> mSurface;
-  bool mClientDeallocation;
-  bool mIsCrossProcess;
+  RefPtr<gfx::DrawTarget> mDrawTarget;
+  bool mLocked;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -8,17 +8,16 @@
 #include "ClientCanvasLayer.h"          // for ClientCanvasLayer
 #include "GLContext.h"                  // for GLContext
 #include "GLScreenBuffer.h"             // for GLScreenBuffer
 #include "ScopedGLHelpers.h"
 #include "gfx2DGlue.h"                  // for ImageFormatToSurfaceFormat
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "GLReadTexImageHelper.h"
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
-#include "mozilla/layers/BufferTexture.h"
 #include "mozilla/layers/AsyncCanvasRenderer.h"
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/CompositorChild.h" // for CompositorChild
 #include "mozilla/layers/GrallocTextureClient.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/layers/TextureClient.h"  // for TextureClient, etc
 #include "mozilla/layers/TextureClientOGL.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
@@ -196,31 +195,31 @@ public:
     , mSize(size)
     , mBackendType(backendType)
     , mBaseTexFlags(baseTexFlags)
     , mLayersBackend(layersBackend)
   {
   }
 
 protected:
-  already_AddRefed<TextureClient> Create(gfx::SurfaceFormat format) {
+  already_AddRefed<BufferTextureClient> Create(gfx::SurfaceFormat format) {
     return TextureClient::CreateForRawBufferAccess(mAllocator, format,
                                                    mSize, mBackendType,
                                                    mBaseTexFlags);
   }
 
 public:
-  already_AddRefed<TextureClient> CreateB8G8R8AX8() {
+  already_AddRefed<BufferTextureClient> CreateB8G8R8AX8() {
     gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
                                           : gfx::SurfaceFormat::B8G8R8X8;
     return Create(format);
   }
 
-  already_AddRefed<TextureClient> CreateR8G8B8AX8() {
-    RefPtr<TextureClient> ret;
+  already_AddRefed<BufferTextureClient> CreateR8G8B8AX8() {
+    RefPtr<BufferTextureClient> ret;
 
     bool areRGBAFormatsBroken = mLayersBackend == LayersBackend::LAYERS_BASIC;
     if (!areRGBAFormatsBroken) {
       gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
                                             : gfx::SurfaceFormat::R8G8B8X8;
       ret = Create(format);
     }
 
@@ -238,17 +237,17 @@ public:
 static already_AddRefed<TextureClient>
 TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
                       TextureFlags baseFlags, LayersBackend layersBackend)
 {
   auto backendType = gfx::BackendType::CAIRO;
   TexClientFactory factory(allocator, src->mHasAlpha, src->mSize, backendType,
                            baseFlags, layersBackend);
 
-  RefPtr<TextureClient> texClient;
+  RefPtr<BufferTextureClient> texClient;
 
   {
     gl::ScopedReadbackFB autoReadback(src);
 
     // We have a source FB, now we need a format.
     GLenum destFormat = LOCAL_GL_BGRA;
     GLenum destType = LOCAL_GL_UNSIGNED_BYTE;
     GLenum readFormat;
@@ -284,41 +283,39 @@ TexClientFromReadback(SharedSurface* src
     if (!texClient)
         return nullptr;
 
     // With a texClient, we can lock for writing.
     TextureClientAutoLock autoLock(texClient, OpenMode::OPEN_WRITE);
     DebugOnly<bool> succeeded = autoLock.Succeeded();
     MOZ_ASSERT(succeeded, "texture should have locked");
 
-    MappedTextureData mapped;
-    texClient->BorrowMappedData(mapped);
+    uint8_t* lockedBytes = texClient->GetLockedData();
 
-    // ReadPixels from the current FB into mapped.data.
+    // ReadPixels from the current FB into lockedBits.
     auto width = src->mSize.width;
     auto height = src->mSize.height;
 
     {
       ScopedPackAlignment autoAlign(gl, 4);
 
-      MOZ_ASSERT(mapped.stride/4 == mapped.size.width);
-      gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, mapped.data);
+      gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, lockedBytes);
     }
 
     // RB_SWAPPED doesn't work with D3D11. (bug 1051010)
     // RB_SWAPPED doesn't work with Basic. (bug ???????)
     // RB_SWAPPED doesn't work with D3D9. (bug ???????)
     bool layersNeedsManualSwap = layersBackend == LayersBackend::LAYERS_BASIC ||
                                  layersBackend == LayersBackend::LAYERS_D3D9 ||
                                  layersBackend == LayersBackend::LAYERS_D3D11;
     if (texClient->HasFlags(TextureFlags::RB_SWAPPED) &&
         layersNeedsManualSwap)
     {
       size_t pixels = width * height;
-      uint8_t* itr = mapped.data;
+      uint8_t* itr = lockedBytes;
       for (size_t i = 0; i < pixels; i++) {
         SwapRB_R8G8B8A8(itr);
         itr += 4;
       }
 
       texClient->RemoveFlags(TextureFlags::RB_SWAPPED);
     }
   }
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -193,17 +193,17 @@ uint64_t
 CompositableClient::GetAsyncID() const
 {
   if (mCompositableChild) {
     return mCompositableChild->mAsyncID;
   }
   return 0; // zero is always an invalid async ID
 }
 
-already_AddRefed<TextureClient>
+already_AddRefed<BufferTextureClient>
 CompositableClient::CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
                                               gfx::IntSize aSize,
                                               gfx::BackendType aMoz2DBackend,
                                               TextureFlags aTextureFlags)
 {
   return TextureClient::CreateForRawBufferAccess(GetForwarder(),
                                                  aFormat, aSize, aMoz2DBackend,
                                                  aTextureFlags | mTextureFlags);
@@ -220,17 +220,17 @@ CompositableClient::CreateTextureClientF
                                          aFormat, aSize, aSelector,
                                          aTextureFlags | mTextureFlags,
                                          aAllocFlags);
 }
 
 bool
 CompositableClient::AddTextureClient(TextureClient* aClient)
 {
-  if(!aClient) {
+  if(!aClient || !aClient->IsAllocated()) {
     return false;
   }
   aClient->SetAddedToCompositableClient();
   return aClient->InitIPDLActor(mForwarder);
 }
 
 void
 CompositableClient::ClearCachedResources()
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -18,16 +18,17 @@
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
 #include "mozilla/layers/TextureClientRecycleAllocator.h" // for TextureClientRecycleAllocator
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 
 namespace mozilla {
 namespace layers {
 
 class CompositableClient;
+class BufferTextureClient;
 class ImageBridgeChild;
 class ImageContainer;
 class CompositableForwarder;
 class CompositableChild;
 class PCompositableChild;
 
 /**
  * Handle RemoveTextureFromCompositableAsync() transaction.
@@ -130,17 +131,17 @@ public:
                     const char* aPrefix="",
                     bool aDumpHtml=false,
                     TextureDumpMode aCompress=TextureDumpMode::Compress) {};
 
   virtual TextureInfo GetTextureInfo() const = 0;
 
   LayersBackend GetCompositorBackendType() const;
 
-  already_AddRefed<TextureClient>
+  already_AddRefed<BufferTextureClient>
   CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
                             gfx::IntSize aSize,
                             gfx::BackendType aMoz2dBackend = gfx::BackendType::NONE,
                             TextureFlags aFlags = TextureFlags::DEFAULT);
 
   already_AddRefed<TextureClient>
   CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat,
                                 gfx::IntSize aSize,
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -187,36 +187,37 @@ ImageClientSingle::UpdateImage(ImageCont
           return false;
         }
 
         TextureClientAutoLock autoLock(texture, OpenMode::OPEN_WRITE_ONLY);
         if (!autoLock.Succeeded()) {
           return false;
         }
 
-        bool status = UpdateYCbCrTextureClient(texture, *data);
+        bool status = texture->AsTextureClientYCbCr()->UpdateYCbCr(*data);
         MOZ_ASSERT(status);
         if (!status) {
           return false;
         }
       } else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE ||
                  image->GetFormat() == ImageFormat::EGLIMAGE) {
         gfx::IntSize size = image->GetSize();
 
         if (image->GetFormat() == ImageFormat::EGLIMAGE) {
           EGLImageImage* typedImage = image->AsEGLImageImage();
-          texture = EGLImageTextureData::CreateTextureClient(
-            typedImage, size, GetForwarder(), mTextureFlags);
+          texture = new EGLImageTextureClient(GetForwarder(),
+                                              mTextureFlags,
+                                              typedImage,
+                                              size);
 #ifdef MOZ_WIDGET_ANDROID
         } else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
           SurfaceTextureImage* typedImage = image->AsSurfaceTextureImage();
-          texture = AndroidSurfaceTextureData::CreateTextureClient(
-            typedImage->GetSurfaceTexture(), size, typedImage->GetOriginPos(),
-            GetForwarder(), mTextureFlags
-          );
+          texture = new SurfaceTextureClient(GetForwarder(), mTextureFlags,
+                                             typedImage->GetSurfaceTexture(), size,
+                                             typedImage->GetOriginPos());
 #endif
         } else {
           MOZ_ASSERT(false, "Bad ImageFormat.");
         }
       } else {
         RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface();
         MOZ_ASSERT(surface);
         texture = CreateTextureClientForDrawing(surface->GetFormat(), image->GetSize(),
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -21,17 +21,16 @@
 #include "mozilla/gfx/Logging.h"        // for gfxDebug
 #include "mozilla/layers/TextureClientOGL.h"
 #include "mozilla/layers/PTextureChild.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h" // for CreateDataSourceSurfaceByCloning
 #include "nsPrintfCString.h"            // for nsPrintfCString
 #include "LayersLogging.h"              // for AppendToString
 #include "gfxUtils.h"                   // for gfxUtils::GetAsLZ4Base64Str
 #include "IPDLActor.h"
-#include "BufferTexture.h"
 
 #ifdef XP_WIN
 #include "mozilla/layers/TextureD3D9.h"
 #include "mozilla/layers/TextureD3D11.h"
 #include "mozilla/layers/TextureDIB.h"
 #include "gfxWindowsPlatform.h"
 #include "gfx2DGlue.h"
 #endif
@@ -62,60 +61,62 @@
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::ipc;
 using namespace mozilla::gl;
 using namespace mozilla::gfx;
 
-struct TextureDeallocParams
+struct ReleaseKeepAlive : public nsRunnable
 {
-  TextureData* data;
-  RefPtr<TextureChild> actor;
-  RefPtr<ISurfaceAllocator> allocator;
-  bool clientDeallocation;
-  bool syncDeallocation;
+  NS_IMETHOD Run()
+  {
+    mKeep = nullptr;
+    return NS_OK;
+  }
+
+  UniquePtr<KeepAlive> mKeep;
 };
 
-void DeallocateTextureClient(TextureDeallocParams params);
-
 /**
  * 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 final : public ChildActor<PTextureChild>
 {
   ~TextureChild()
   {
-    // We should have deallocated mTextureData in ActorDestroy
-    MOZ_ASSERT(!mTextureData);
+    if (mKeep && mMainThreadOnly && !NS_IsMainThread()) {
+      RefPtr<ReleaseKeepAlive> release = new ReleaseKeepAlive();
+      release->mKeep = Move(mKeep);
+      NS_DispatchToMainThread(release);
+    }
   }
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureChild)
 
   TextureChild()
   : mForwarder(nullptr)
   , mMonitor("TextureChild")
   , mTextureClient(nullptr)
-  , mTextureData(nullptr)
   , mDestroyed(false)
   , mMainThreadOnly(false)
   , mIPCOpen(false)
-  , mOwnsTextureData(false)
-  {}
+  {
+  }
 
-  bool Recv__delete__() override { return true; }
+  bool Recv__delete__() override;
 
   bool RecvCompositorRecycle() override
   {
     RECYCLE_LOG("[CLIENT] Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
     mWaitForRecycle = nullptr;
     return true;
   }
 
@@ -161,375 +162,39 @@ private:
   }
 
   RefPtr<CompositableForwarder> mForwarder;
   RefPtr<TextureClient> mWaitForRecycle;
 
   // Monitor protecting mTextureClient.
   Monitor mMonitor;
   TextureClient* mTextureClient;
-  TextureData* mTextureData;
+  UniquePtr<KeepAlive> mKeep;
   Atomic<bool> mDestroyed;
   bool mMainThreadOnly;
   bool mIPCOpen;
-  bool mOwnsTextureData;
 
   friend class TextureClient;
-  friend void DeallocateTextureClient(TextureDeallocParams params);
 };
 
-
-static void DestroyTextureData(TextureData* aTextureData, ISurfaceAllocator* aAllocator,
-                               bool aDeallocate, bool aMainThreadOnly)
+bool
+TextureChild::Recv__delete__()
 {
-  MOZ_ASSERT(aTextureData);
-  if (!aTextureData) {
-    return;
-  }
-
-  if (aMainThreadOnly && !NS_IsMainThread()) {
-    RefPtr<ISurfaceAllocator> allocatorRef = aAllocator;
-    NS_DispatchToMainThread(NS_NewRunnableFunction([aTextureData, allocatorRef, aDeallocate]() -> void {
-      DestroyTextureData(aTextureData, allocatorRef, aDeallocate, true);
-    }));
-    return;
-  }
-
-  if (aDeallocate) {
-    aTextureData->Deallocate(aAllocator);
-  } else {
-    aTextureData->Forget(aAllocator);
-  }
-  delete aTextureData;
+  return true;
 }
 
 void
 TextureChild::ActorDestroy(ActorDestroyReason why)
 {
-  mWaitForRecycle = nullptr;
-
-  if (mTextureData) {
-    DestroyTextureData(mTextureData, GetAllocator(), mOwnsTextureData, mMainThreadOnly);
-    mTextureData = nullptr;
-  }
-}
-
-void DeallocateTextureClientSyncProxy(TextureDeallocParams params,
-                                        ReentrantMonitor* aBarrier, bool* aDone)
-{
-  DeallocateTextureClient(params);
-  ReentrantMonitorAutoEnter autoMon(*aBarrier);
-  *aDone = true;
-  aBarrier->NotifyAll();
-}
-
-/// The logic for synchronizing a TextureClient's deallocation goes here.
-///
-/// This funciton takes care of dispatching work to the right thread using
-/// a synchronous proxy if needed, and handles client/host deallocation.
-void
-DeallocateTextureClient(TextureDeallocParams params)
-{
-  TextureChild* actor = params.actor;
-  MessageLoop* ipdlMsgLoop = nullptr;
-
-  if (params.allocator) {
-    ipdlMsgLoop = params.allocator->GetMessageLoop();
-    if (!ipdlMsgLoop) {
-      // An allocator with no message loop means we are too late in the shutdown
-      // sequence.
-      gfxCriticalError() << "Texture deallocated too late during shutdown";
-      return;
-    }
-  }
-
-  // First make sure that the work is happening on the IPDL thread.
-  if (ipdlMsgLoop && MessageLoop::current() != ipdlMsgLoop) {
-    if (params.syncDeallocation) {
-      bool done = false;
-      ReentrantMonitor barrier("DeallocateTextureClient");
-      ReentrantMonitorAutoEnter autoMon(barrier);
-      ipdlMsgLoop->PostTask(FROM_HERE,
-        NewRunnableFunction(DeallocateTextureClientSyncProxy,
-                            params, &barrier, &done));
-      while (!done) {
-        barrier.Wait();
-      }
-    } else {
-      ipdlMsgLoop->PostTask(FROM_HERE,
-        NewRunnableFunction(DeallocateTextureClient, params));
-    }
-    // The work has been forwarded to the IPDL thread, we are done.
-    return;
-  }
-
-  // Below this line, we are either in the IPDL thread or ther is no IPDL
-  // thread anymore.
-
-  if (!ipdlMsgLoop) {
-    // If we don't have a message loop we can't know for sure that we are in
-    // the IPDL thread and use the ISurfaceAllocator.
-    // This should ideally not happen outside of gtest, but some shutdown raciness
-    // could put us in this situation.
-    params.allocator = nullptr;
-  }
-
-  if (!actor) {
-    // We don't have an IPDL actor, probably because we destroyed the TextureClient
-    // before sharing it with the compositor. It means the data cannot be owned by
-    // the TextureHost since we never created the TextureHost.
-    DestroyTextureData(params.data, params.allocator,
-                       true,    // client-side deallocation
-                       false);  // main-thread deallocation
-    return;
-  }
-
-  if (!actor->IPCOpen()) {
-    // The actor is already deallocated which probably means there was a shutdown
-    // race causing this function to be called concurrently which is bad!
-    gfxCriticalError() << "Racy texture deallocation";
-    return;
-  }
-
-  if (params.syncDeallocation) {
-    MOZ_PERFORMANCE_WARNING("gfx",
-      "TextureClient/Host pair requires synchronous deallocation");
-    actor->DestroySynchronously();
-    DestroyTextureData(params.data, params.allocator, params.clientDeallocation,
-                       actor->mMainThreadOnly);
-  } else {
-    actor->mTextureData = params.data;
-    actor->mOwnsTextureData = params.clientDeallocation;
-    actor->Destroy();
-    // DestroyTextureData will be called by TextureChild::ActorDestroy
-  }
-}
-
-void TextureClient::Destroy(bool aForceSync)
-{
-  MOZ_ASSERT(!IsLocked());
-
-  RefPtr<TextureChild> actor = mActor;
-  mActor = nullptr;
-
-  if (actor && !actor->mDestroyed.compareExchange(false, true)) {
-    actor = nullptr;
-  }
-
-  TextureData* data = mData;
-  if (!mWorkaroundAnnoyingSharedSurfaceLifetimeIssues) {
-    mData = nullptr;
-  }
-
-  if (data || actor) {
-    TextureDeallocParams params;
-    params.actor = actor;
-    params.allocator = mAllocator;
-    params.clientDeallocation = !!(mFlags & TextureFlags::DEALLOCATE_CLIENT);
-    if (mWorkaroundAnnoyingSharedSurfaceLifetimeIssues) {
-      params.data = nullptr;
-    } else {
-      params.data = data;
-    }
-    // At the moment we always deallocate synchronously when deallocating on the
-    // client side, but having asynchronous deallocate in some of the cases will
-    // be a worthwhile optimization.
-    params.syncDeallocation = !!(mFlags & TextureFlags::DEALLOCATE_CLIENT) || aForceSync;
-    DeallocateTextureClient(params);
-  }
-}
-
-bool
-TextureClient::Lock(OpenMode aMode)
-{
-  MOZ_ASSERT(IsValid());
-  MOZ_ASSERT(!mIsLocked);
-  if (mIsLocked) {
-    return mOpenMode == aMode;
-  }
-
-  if (mRemoveFromCompositableWaiter) {
-    mRemoveFromCompositableWaiter->WaitComplete();
-    mRemoveFromCompositableWaiter = nullptr;
-  }
-
-  mIsLocked = mData->Lock(aMode, mReleaseFenceHandle.IsValid() ? &mReleaseFenceHandle : nullptr);
-  mOpenMode = aMode;
-
-  return mIsLocked;
-}
-
-void
-TextureClient::Unlock()
-{
-  MOZ_ASSERT(IsValid());
-  MOZ_ASSERT(mIsLocked);
-  if (!mIsLocked) {
-    return;
+  if (mTextureClient) {
+    mTextureClient->mActor = nullptr;
+    mTextureClient->mAllocator = nullptr;
   }
-
-  if (mBorrowedDrawTarget) {
-    MOZ_ASSERT(mBorrowedDrawTarget->refCount() <= mExpectedDtRefs);
-    if (mOpenMode & OpenMode::OPEN_WRITE) {
-      mBorrowedDrawTarget->Flush();
-      if (mReadbackSink && !mData->ReadBack(mReadbackSink)) {
-        // Fallback implementation for reading back, because mData does not
-        // have a backend-specific implementation and returned false.
-        RefPtr<SourceSurface> snapshot = mBorrowedDrawTarget->Snapshot();
-        RefPtr<DataSourceSurface> dataSurf = snapshot->GetDataSurface();
-        mReadbackSink->ProcessReadback(dataSurf);
-      }
-    }
-    mBorrowedDrawTarget = nullptr;
-  }
-
-  mData->Unlock();
-  mIsLocked = false;
-  mOpenMode = OpenMode::OPEN_NONE;
-}
-
-bool
-TextureClient::HasInternalBuffer() const
-{
-  MOZ_ASSERT(IsValid());
-  return mData->HasInternalBuffer();
-}
-
-gfx::IntSize
-TextureClient::GetSize() const
-{
-  MOZ_ASSERT(IsValid());
-  return mData->GetSize();
-}
-
-gfx::SurfaceFormat
-TextureClient::GetFormat() const
-{
-  MOZ_ASSERT(IsValid());
-  return mData->GetFormat();
-}
-
-TextureClient::~TextureClient()
-{
-  Destroy(false);
-}
-
-void
-TextureClient::UpdateFromSurface(gfx::SourceSurface* aSurface)
-{
-  MOZ_ASSERT(IsValid());
-  MOZ_ASSERT(mIsLocked);
-  MOZ_ASSERT(aSurface);
-
-  // XXX - It would be better to first try the DrawTarget approach and fallback
-  // to the backend-specific implementation because the latter will usually do
-  // an expensive read-back + cpu-side copy if the texture is on the gpu.
-  // There is a bug with the DrawTarget approach, though specific to reading back
-  // from WebGL (where R and B channel end up inverted) to figure out first.
-  if (mData->UpdateFromSurface(aSurface)) {
-    return;
-  }
-  if (CanExposeDrawTarget() && NS_IsMainThread()) {
-    RefPtr<DrawTarget> dt = BorrowDrawTarget();
-
-    MOZ_ASSERT(dt);
-    if (dt) {
-      dt->CopySurface(aSurface,
-                      gfx::IntRect(gfx::IntPoint(0, 0), aSurface->GetSize()),
-                      gfx::IntPoint(0, 0));
-      return;
-    }
-  }
-  NS_WARNING("TextureClient::UpdateFromSurface failed");
-}
-
-
-already_AddRefed<TextureClient>
-TextureClient::CreateSimilar(TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
-{
-  MOZ_ASSERT(IsValid());
-  TextureData* data = mData->CreateSimilar(mAllocator, aFlags, aAllocFlags);
-  if (!data) {
-    return nullptr;
-  }
-
-  return MakeAndAddRef<TextureClient>(data, aFlags, mAllocator);
-}
-
-gfx::DrawTarget*
-TextureClient::BorrowDrawTarget()
-{
-  MOZ_ASSERT(IsValid());
-  MOZ_ASSERT(mIsLocked);
-  // TODO- We can't really assert that at the moment because there is code that Borrows
-  // the DrawTarget, just to get a snapshot, which is legit in term of OpenMode
-  // but we should have a way to get a SourceSurface directly instead.
-  //MOZ_ASSERT(mOpenMode & OpenMode::OPEN_WRITE);
-
-  if (!mIsLocked) {
-    return nullptr;
-  }
-
-  if (!NS_IsMainThread()) {
-    return nullptr;
-  }
-
-  if (!mBorrowedDrawTarget) {
-    mBorrowedDrawTarget = mData->BorrowDrawTarget();
-#ifdef DEBUG
-    mExpectedDtRefs = mBorrowedDrawTarget ? mBorrowedDrawTarget->refCount() : 0;
-#endif
-  }
-
-  return mBorrowedDrawTarget;
-}
-
-bool
-TextureClient::BorrowMappedData(MappedTextureData& aMap)
-{
-  MOZ_ASSERT(IsValid());
-
-  // TODO - SharedRGBImage just accesses the buffer without properly locking
-  // the texture. It's bad.
-  //MOZ_ASSERT(mIsLocked);
-  //if (!mIsLocked) {
-  //  return nullptr;
-  //}
-
-  return mData->BorrowMappedData(aMap);
-}
-
-bool
-TextureClient::BorrowMappedYCbCrData(MappedYCbCrTextureData& aMap)
-{
-  MOZ_ASSERT(IsValid());
-  return mData->BorrowMappedYCbCrData(aMap);
-}
-
-bool
-TextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
-{
-  MOZ_ASSERT(IsValid());
-  return mData->Serialize(aOutDescriptor);
-}
-
-void
-TextureClient::WaitForBufferOwnership(bool aWaitReleaseFence)
-{
-  if (mRemoveFromCompositableWaiter) {
-    mRemoveFromCompositableWaiter->WaitComplete();
-    mRemoveFromCompositableWaiter = nullptr;
-  }
-
-#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION < 21
-  if (aWaitReleaseFence && mReleaseFenceHandle.IsValid()) {
-    mData->WaitForFence(&mReleaseFenceHandle);
-    mReleaseFenceHandle = FenceHandle();
-  }
-#endif
+  mWaitForRecycle = nullptr;
+  mKeep = nullptr;
 }
 
 // static
 PTextureChild*
 TextureClient::CreateIPDLActor()
 {
   TextureChild* c = new TextureChild();
   c->AddIPDLReference();
@@ -543,63 +208,55 @@ TextureClient::DestroyIPDLActor(PTexture
   static_cast<TextureChild*>(actor)->ReleaseIPDLReference();
   return true;
 }
 
 // static
 TextureClient*
 TextureClient::AsTextureClient(PTextureChild* actor)
 {
-  if (!actor) {
-    return nullptr;
-  }
-  TextureChild* tc = static_cast<TextureChild*>(actor);
-  if (tc->mDestroyed) {
-    return nullptr;
-  }
-
-  return tc->mTextureClient;
+  return actor ? static_cast<TextureChild*>(actor)->mTextureClient : nullptr;
 }
 
 bool
 TextureClient::IsSharedWithCompositor() const {
-  return mActor && mActor->IPCOpen();
+  return mShared && mActor && mActor->IPCOpen();
 }
 
 void
 TextureClient::AddFlags(TextureFlags aFlags)
 {
   MOZ_ASSERT(!IsSharedWithCompositor() ||
              ((GetFlags() & TextureFlags::RECYCLE) && !IsAddedToCompositableClient()));
   mFlags |= aFlags;
-  if (IsValid() && mActor && !mActor->mDestroyed && mActor->IPCOpen()) {
+  if (mValid && mActor && !mActor->mDestroyed && mActor->IPCOpen()) {
     mActor->SendRecycleTexture(mFlags);
   }
 }
 
 void
 TextureClient::RemoveFlags(TextureFlags aFlags)
 {
   MOZ_ASSERT(!IsSharedWithCompositor() ||
              ((GetFlags() & TextureFlags::RECYCLE) && !IsAddedToCompositableClient()));
   mFlags &= ~aFlags;
-  if (IsValid() && mActor && !mActor->mDestroyed && mActor->IPCOpen()) {
+  if (mValid && mActor && !mActor->mDestroyed && mActor->IPCOpen()) {
     mActor->SendRecycleTexture(mFlags);
   }
 }
 
 void
 TextureClient::RecycleTexture(TextureFlags aFlags)
 {
   MOZ_ASSERT(GetFlags() & TextureFlags::RECYCLE);
 
   mAddedToCompositableClient = false;
   if (mFlags != aFlags) {
     mFlags = aFlags;
-    if (IsValid() && mActor && !mActor->mDestroyed && mActor->IPCOpen()) {
+    if (mValid && mActor && !mActor->mDestroyed && mActor->IPCOpen()) {
       mActor->SendRecycleTexture(mFlags);
     }
   }
 }
 
 void
 TextureClient::WaitForCompositorRecycle()
 {
@@ -645,26 +302,69 @@ TextureClient::InitIPDLActor(Compositabl
   if (!ToSurfaceDescriptor(desc)) {
     return false;
   }
 
   mActor = static_cast<TextureChild*>(aForwarder->CreateTexture(desc, aForwarder->GetCompositorBackendType(), GetFlags()));
   MOZ_ASSERT(mActor);
   mActor->mForwarder = aForwarder;
   mActor->mTextureClient = this;
-  mActor->mMainThreadOnly = !!(mFlags & TextureFlags::DEALLOCATE_MAIN_THREAD);
+  mShared = true;
   return mActor->IPCOpen();
 }
 
 PTextureChild*
 TextureClient::GetIPDLActor()
 {
   return mActor;
 }
 
+#ifdef MOZ_WIDGET_GONK
+static bool
+DisableGralloc(SurfaceFormat aFormat, const gfx::IntSize& aSizeHint)
+{
+  if (gfxPrefs::DisableGralloc()) {
+    return true;
+  }
+  if (aFormat == gfx::SurfaceFormat::A8) {
+    return true;
+  }
+
+#if ANDROID_VERSION <= 15
+  // Adreno 200 has a problem of drawing gralloc buffer width less than 64 and
+  // drawing gralloc buffer with a height 9px-16px.
+  // See Bug 983971.
+  if (aSizeHint.width < 64 || aSizeHint.height < 32) {
+    return true;
+  }
+#endif
+
+  return false;
+}
+#endif
+
+static
+already_AddRefed<BufferTextureClient>
+CreateBufferTextureClient(ISurfaceAllocator* aAllocator,
+                          SurfaceFormat aFormat,
+                          TextureFlags aTextureFlags,
+                          gfx::BackendType aMoz2DBackend)
+{
+  if (aAllocator->IsSameProcess()) {
+    RefPtr<BufferTextureClient> result = new MemoryTextureClient(aAllocator, aFormat,
+                                                                 aMoz2DBackend,
+                                                                 aTextureFlags);
+    return result.forget();
+  }
+  RefPtr<BufferTextureClient> result = new ShmemTextureClient(aAllocator, aFormat,
+                                                              aMoz2DBackend,
+                                                              aTextureFlags);
+  return result.forget();
+}
+
 static inline gfx::BackendType
 BackendTypeForBackendSelector(LayersBackend aLayersBackend, BackendSelector aSelector)
 {
   switch (aSelector) {
     case BackendSelector::Canvas:
       return gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
     case BackendSelector::Content:
       return gfxPlatform::GetPlatform()->GetContentBackendFor(aLayersBackend);
@@ -690,183 +390,246 @@ TextureClient::CreateForDrawing(Composit
 
   if (!gfx::Factory::AllowedSurfaceSize(aSize)) {
     return nullptr;
   }
 
   LayersBackend parentBackend = aAllocator->GetCompositorBackendType();
   gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(parentBackend, aSelector);
 
-  TextureData* data = nullptr;
+  RefPtr<TextureClient> texture;
 
-#if defined(XP_WIN)
+#if defined(MOZ_WIDGET_GONK) || defined(XP_WIN)
   int32_t maxTextureSize = aAllocator->GetMaxTextureSize();
 #endif
 
 #ifdef XP_WIN
   if (parentBackend == LayersBackend::LAYERS_D3D11 &&
       (moz2DBackend == gfx::BackendType::DIRECT2D ||
        moz2DBackend == gfx::BackendType::DIRECT2D1_1) &&
       aSize.width <= maxTextureSize &&
       aSize.height <= maxTextureSize)
   {
-    data = DXGITextureData::Create(aSize, aFormat, aAllocFlags);
+    texture = new TextureClientD3D11(aAllocator, aFormat, aTextureFlags);
   }
   if (parentBackend == LayersBackend::LAYERS_D3D9 &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       aAllocator->IsSameProcess() &&
       aSize.width <= maxTextureSize &&
       aSize.height <= maxTextureSize &&
-      NS_IsMainThread() &&
-      gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
-    data = D3D9TextureData::Create(aSize, aFormat, aAllocFlags);
+      NS_IsMainThread()) {
+    if (gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
+      texture = new TextureClientD3D9(aAllocator, aFormat, aTextureFlags);
+    }
   }
 
-  if (!data && aFormat == SurfaceFormat::B8G8R8X8 &&
+  if (!texture && aFormat == SurfaceFormat::B8G8R8X8 &&
       aAllocator->IsSameProcess() &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       NS_IsMainThread()) {
-    data = DIBTextureData::Create(aSize, aFormat, aAllocator);
+    if (aAllocator->IsSameProcess()) {
+      texture = new TextureClientMemoryDIB(aAllocator, aFormat, aTextureFlags);
+    } else {
+      texture = new TextureClientShmemDIB(aAllocator, aFormat, aTextureFlags);
+    }
   }
 #endif
 
 #ifdef MOZ_X11
   gfxSurfaceType type =
     gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType();
 
-  if (!data && parentBackend == LayersBackend::LAYERS_BASIC &&
+  if (parentBackend == LayersBackend::LAYERS_BASIC &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       type == gfxSurfaceType::Xlib)
   {
-    data = X11TextureData::Create(aSize, aFormat, aTextureFlags, aAllocator);
+    texture = new TextureClientX11(aAllocator, aFormat, aTextureFlags);
   }
 #ifdef GL_PROVIDER_GLX
-  if (!data && parentBackend == LayersBackend::LAYERS_OPENGL &&
+  if (parentBackend == LayersBackend::LAYERS_OPENGL &&
       type == gfxSurfaceType::Xlib &&
       aFormat != SurfaceFormat::A8 &&
       gl::sGLXLibrary.UseTextureFromPixmap())
   {
-    data = X11TextureData::Create(aSize, aFormat, aTextureFlags, aAllocator);
+    texture = new TextureClientX11(aAllocator, aFormat, aTextureFlags);
   }
 #endif
 #endif
 
 #ifdef MOZ_WIDGET_GONK
-  if (!data) {
-    data = GrallocTextureData::CreateForDrawing(aSize, aFormat, moz2DBackend,
-                                                aAllocator);
+  if (!DisableGralloc(aFormat, aSize)) {
+    // Don't allow Gralloc texture clients to exceed the maximum texture size.
+    // BufferTextureClients have code to handle tiling the surface client-side.
+    if (aSize.width <= maxTextureSize && aSize.height <= maxTextureSize) {
+      texture = new GrallocTextureClientOGL(aAllocator, aFormat, moz2DBackend,
+                                           aTextureFlags);
+    }
   }
 #endif
 
-  if (data) {
-    return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
+  MOZ_ASSERT(!texture || texture->CanExposeDrawTarget(), "texture cannot expose a DrawTarget?");
+
+  if (texture && texture->AllocateForSurface(aSize, aAllocFlags)) {
+    return texture.forget();
+  }
+
+  if (aAllocFlags & ALLOC_DISALLOW_BUFFERTEXTURECLIENT) {
+    return nullptr;
+  }
+
+  if (texture) {
+    NS_WARNING("Failed to allocate a TextureClient, falling back to BufferTextureClient.");
   }
 
   // Can't do any better than a buffer texture client.
-  return TextureClient::CreateForRawBufferAccess(aAllocator, aFormat, aSize,
-                                                 moz2DBackend, aTextureFlags, aAllocFlags);
+  texture = CreateBufferTextureClient(aAllocator, aFormat, aTextureFlags, moz2DBackend);
+
+  if (!texture->AllocateForSurface(aSize, aAllocFlags)) {
+    return nullptr;
+  }
+
+  return texture.forget();
 }
 
 // static
-already_AddRefed<TextureClient>
+already_AddRefed<BufferTextureClient>
 TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
                                         gfx::SurfaceFormat aFormat,
                                         gfx::IntSize aSize,
                                         gfx::BackendType aMoz2DBackend,
                                         TextureFlags aTextureFlags,
                                         TextureAllocationFlags aAllocFlags)
 {
   MOZ_ASSERT(aAllocator->IPCOpen());
   if (!aAllocator || !aAllocator->IPCOpen()) {
     return nullptr;
   }
 
-  if (aAllocFlags & ALLOC_DISALLOW_BUFFERTEXTURECLIENT) {
-    return nullptr;
-  }
-
   if (!gfx::Factory::AllowedSurfaceSize(aSize)) {
     return nullptr;
   }
 
-  TextureData* texData = BufferTextureData::Create(aSize, aFormat, aMoz2DBackend,
-                                                   aTextureFlags, aAllocFlags,
-                                                   aAllocator);
-  if (!texData) {
-    return nullptr;
+  RefPtr<BufferTextureClient> texture =
+    CreateBufferTextureClient(aAllocator, aFormat,
+                              aTextureFlags, aMoz2DBackend);
+  if (texture) {
+    if (!texture->AllocateForSurface(aSize, aAllocFlags)) {
+      return nullptr;
+    }
   }
-
-  return MakeAndAddRef<TextureClient>(texData, aTextureFlags, aAllocator);
+  return texture.forget();
 }
 
 // static
-already_AddRefed<TextureClient>
+already_AddRefed<BufferTextureClient>
 TextureClient::CreateForYCbCr(ISurfaceAllocator* aAllocator,
                               gfx::IntSize aYSize,
                               gfx::IntSize aCbCrSize,
                               StereoMode aStereoMode,
                               TextureFlags aTextureFlags)
 {
-  // The only reason we allow aAllocator to be null is for gtests
-  MOZ_ASSERT(!aAllocator || aAllocator->IPCOpen());
-  if (aAllocator && !aAllocator->IPCOpen()) {
+  MOZ_ASSERT(aAllocator->IPCOpen());
+  if (!aAllocator || !aAllocator->IPCOpen()) {
     return nullptr;
   }
 
   if (!gfx::Factory::AllowedSurfaceSize(aYSize)) {
     return nullptr;
   }
 
-  TextureData* data = BufferTextureData::CreateForYCbCr(aAllocator, aYSize, aCbCrSize,
-                                                        aStereoMode, aTextureFlags);
-  if (!data) {
+  RefPtr<BufferTextureClient> texture;
+  if (aAllocator->IsSameProcess()) {
+    texture = new MemoryTextureClient(aAllocator, gfx::SurfaceFormat::YUV,
+                                      gfx::BackendType::NONE,
+                                      aTextureFlags);
+  } else {
+    texture = new ShmemTextureClient(aAllocator, gfx::SurfaceFormat::YUV,
+                                     gfx::BackendType::NONE,
+                                     aTextureFlags);
+  }
+
+  if (!texture->AllocateForYCbCr(aYSize, aCbCrSize, aStereoMode)) {
     return nullptr;
   }
 
-  return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
+  return texture.forget();
 }
 
 // static
-already_AddRefed<TextureClient>
+already_AddRefed<BufferTextureClient>
 TextureClient::CreateWithBufferSize(ISurfaceAllocator* aAllocator,
-                                    gfx::SurfaceFormat aFormat,
-                                    size_t aSize,
-                                    TextureFlags aTextureFlags)
+                     gfx::SurfaceFormat aFormat,
+                     size_t aSize,
+                     TextureFlags aTextureFlags)
 {
   MOZ_ASSERT(aAllocator->IPCOpen());
   if (!aAllocator || !aAllocator->IPCOpen()) {
     return nullptr;
   }
 
-  TextureData* data = BufferTextureData::CreateWithBufferSize(aAllocator, aFormat, aSize,
-                                                              aTextureFlags);
-  if (!data) {
+  RefPtr<BufferTextureClient> texture;
+  if (aAllocator->IsSameProcess()) {
+    texture = new MemoryTextureClient(aAllocator, gfx::SurfaceFormat::YUV,
+                                      gfx::BackendType::NONE,
+                                      aTextureFlags);
+  } else {
+    texture = new ShmemTextureClient(aAllocator, gfx::SurfaceFormat::YUV,
+                                     gfx::BackendType::NONE,
+                                     aTextureFlags);
+  }
+
+  if (!texture->Allocate(aSize)) {
     return nullptr;
   }
 
-  return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
+  return texture.forget();
+}
+
+TextureClient::TextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags)
+  : mAllocator(aAllocator)
+  , mFlags(aFlags)
+  , mShared(false)
+  , mValid(true)
+  , mAddedToCompositableClient(false)
+#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
+  , mPoolTracker(nullptr)
+#endif
+{}
+
+TextureClient::~TextureClient()
+{
+  // All the destruction code that may lead to virtual method calls must
+  // be in Finalize() which is called just before the destructor.
 }
 
-TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator)
-: mAllocator(aAllocator)
-, mActor(nullptr)
-, mData(aData)
-, mFlags(aFlags)
-, mOpenMode(OpenMode::OPEN_NONE)
-#ifdef DEBUG
-, mExpectedDtRefs(0)
-#endif
-, mIsLocked(false)
-, mAddedToCompositableClient(false)
-, mWorkaroundAnnoyingSharedSurfaceLifetimeIssues(false)
-#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
-, mPoolTracker(nullptr)
-#endif
+void
+TextureClient::KeepUntilFullDeallocation(UniquePtr<KeepAlive> aKeep, bool aMainThreadOnly)
+{
+  MOZ_ASSERT(mActor);
+  MOZ_ASSERT(!mActor->mKeep);
+  mActor->mKeep = Move(aKeep);
+  mActor->mMainThreadOnly = aMainThreadOnly;
+}
+
+void TextureClient::ForceRemove(bool sync)
 {
-  mFlags |= mData->GetTextureFlags();
+  if (mActor && mActor->mDestroyed) {
+    mActor = nullptr;
+  }
+  if (mValid && mActor) {
+    FinalizeOnIPDLThread();
+    if (mActor->CanSend()) {
+      if (sync || GetFlags() & TextureFlags::DEALLOCATE_CLIENT) {
+        mActor->DestroySynchronously();
+      } else {
+        mActor->Destroy();
+      }
+    }
+  }
+  MarkInvalid();
 }
 
 bool TextureClient::CopyToTextureClient(TextureClient* aTarget,
                                         const gfx::IntRect* aRect,
                                         const gfx::IntPoint* aPoint)
 {
   MOZ_ASSERT(IsLocked());
   MOZ_ASSERT(aTarget->IsLocked());
@@ -890,18 +653,56 @@ bool TextureClient::CopyToTextureClient(
   RefPtr<gfx::SourceSurface> source = sourceTarget->Snapshot();
   destinationTarget->CopySurface(source,
                                  aRect ? *aRect : gfx::IntRect(gfx::IntPoint(0, 0), GetSize()),
                                  aPoint ? *aPoint : gfx::IntPoint(0, 0));
   return true;
 }
 
 void
-TextureClient::SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) {
-  mRemoveFromCompositableWaiter = aWaiter;
+TextureClient::Finalize()
+{
+  MOZ_ASSERT(!IsLocked());
+
+  // Always make a temporary strong reference to the actor before we use it,
+  // in case TextureChild::ActorDestroy might null mActor concurrently.
+  RefPtr<TextureChild> actor = mActor;
+
+  if (actor) {
+    if (actor->mDestroyed) {
+      actor = nullptr;
+      return;
+    }
+    // The actor has a raw pointer to us, actor->mTextureClient.
+    // Null it before RemoveTexture calls to avoid invalid actor->mTextureClient
+    // when calling TextureChild::ActorDestroy()
+    actor->SetTextureClient(nullptr);
+
+    // `actor->mWaitForRecycle` may not be null, as we may be being called from setting
+    // this RefPtr to null! Clearing it here will double-Release() it.
+
+    // this will call ForceRemove in the right thread, using a sync proxy if needed
+    if (actor->GetForwarder()) {
+      actor->GetForwarder()->RemoveTexture(this);
+    }
+  }
+}
+
+bool
+TextureClient::ShouldDeallocateInDestructor() const
+{
+  if (!IsAllocated()) {
+    return false;
+  }
+
+  // If we're meant to be deallocated by the host,
+  // but we haven't been shared yet or
+  // TextureFlags::DEALLOCATE_CLIENT is set, then we should
+  // deallocate on the client instead.
+  return !mShared || (GetFlags() & TextureFlags::DEALLOCATE_CLIENT);
 }
 
 void
 TextureClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
 {
   aStream << aPrefix;
   aStream << nsPrintfCString("TextureClient (0x%p)", this).get();
   AppendToString(aStream, GetSize(), " [size=", "]");
@@ -916,114 +717,363 @@ TextureClient::PrintInfo(std::stringstre
     aStream << "\n" << pfx.get() << "Surface: ";
     RefPtr<gfx::DataSourceSurface> dSurf = GetAsSurface();
     if (dSurf) {
       aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get();
     }
   }
 #endif
 }
+bool
+ShmemTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor)
+{
+  MOZ_ASSERT(IsValid());
+  if (!IsAllocated() || GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
+    return false;
+  }
+
+  aDescriptor = SurfaceDescriptorShmem(mShmem, GetFormat());
+
+  return true;
+}
+
+bool
+ShmemTextureClient::Allocate(uint32_t aSize)
+{
+  MOZ_ASSERT(mValid);
+  if (aSize > 0) {
+    SharedMemory::SharedMemoryType memType = OptimalShmemType();
+    mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem);
+  }
+  return mAllocated;
+}
+
+uint8_t*
+ShmemTextureClient::GetBuffer() const
+{
+  MOZ_ASSERT(IsValid());
+  if (mAllocated) {
+    return mShmem.get<uint8_t>();
+  }
+  return nullptr;
+}
+
+size_t
+ShmemTextureClient::GetBufferSize() const
+{
+  MOZ_ASSERT(IsValid());
+  return mShmem.Size<uint8_t>();
+}
+
+ShmemTextureClient::ShmemTextureClient(ISurfaceAllocator* aAllocator,
+                                       gfx::SurfaceFormat aFormat,
+                                       gfx::BackendType aMoz2DBackend,
+                                       TextureFlags aFlags)
+  : BufferTextureClient(aAllocator, aFormat, aMoz2DBackend, aFlags)
+  , mAllocated(false)
+{
+  MOZ_COUNT_CTOR(ShmemTextureClient);
+}
+
+ShmemTextureClient::~ShmemTextureClient()
+{
+  MOZ_COUNT_DTOR(ShmemTextureClient);
+  if (ShouldDeallocateInDestructor()) {
+    // if the buffer has never been shared we must deallocate it or ir would
+    // leak.
+    GetAllocator()->DeallocShmem(mShmem);
+  }
+}
 
 bool
-UpdateYCbCrTextureClient(TextureClient* aTexture, const PlanarYCbCrData& aData)
+MemoryTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor)
+{
+  MOZ_ASSERT(IsValid());
+  if (!IsAllocated() || GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
+    return false;
+  }
+  aDescriptor = SurfaceDescriptorMemory(reinterpret_cast<uintptr_t>(mBuffer),
+                                        GetFormat());
+  return true;
+}
+
+bool
+MemoryTextureClient::Allocate(uint32_t aSize)
+{
+  MOZ_ASSERT(!mBuffer);
+  mBuffer = new (fallible) uint8_t[aSize];
+  if (!mBuffer) {
+    NS_WARNING("Failed to allocate buffer");
+    return false;
+  }
+  GfxMemoryImageReporter::DidAlloc(mBuffer);
+  mBufSize = aSize;
+  return true;
+}
+
+MemoryTextureClient::MemoryTextureClient(ISurfaceAllocator* aAllocator,
+                                         gfx::SurfaceFormat aFormat,
+                                         gfx::BackendType aMoz2DBackend,
+                                         TextureFlags aFlags)
+  : BufferTextureClient(aAllocator, aFormat, aMoz2DBackend, aFlags)
+  , mBuffer(nullptr)
+  , mBufSize(0)
+{
+  MOZ_COUNT_CTOR(MemoryTextureClient);
+}
+
+MemoryTextureClient::~MemoryTextureClient()
 {
-  MOZ_ASSERT(aTexture);
-  MOZ_ASSERT(aTexture->IsLocked());
-  MOZ_ASSERT(aTexture->GetFormat() == gfx::SurfaceFormat::YUV, "This textureClient can only use YCbCr data");
-  MOZ_ASSERT(!aTexture->IsImmutable());
-  MOZ_ASSERT(aTexture->IsValid());
-  MOZ_ASSERT(aData.mCbSkip == aData.mCrSkip);
+  MOZ_COUNT_DTOR(MemoryTextureClient);
+  if (mBuffer && ShouldDeallocateInDestructor()) {
+    // if the buffer has never been shared we must deallocate it or it would
+    // leak.
+    GfxMemoryImageReporter::WillFree(mBuffer);
+    delete [] mBuffer;
+  }
+}
+
+BufferTextureClient::BufferTextureClient(ISurfaceAllocator* aAllocator,
+                                         gfx::SurfaceFormat aFormat,
+                                         gfx::BackendType aMoz2DBackend,
+                                         TextureFlags aFlags)
+  : TextureClient(aAllocator, aFlags)
+  , mFormat(aFormat)
+  , mBackend(aMoz2DBackend)
+  , mOpenMode(OpenMode::OPEN_NONE)
+  , mLocked(false)
+{}
 
-  MappedYCbCrTextureData mapped;
-  if (!aTexture->BorrowMappedYCbCrData(mapped)) {
-    NS_WARNING("Failed to extract YCbCr info!");
+BufferTextureClient::~BufferTextureClient()
+{}
+
+already_AddRefed<TextureClient>
+BufferTextureClient::CreateSimilar(TextureFlags aFlags,
+                                   TextureAllocationFlags aAllocFlags) const
+{
+  // This may return null
+  RefPtr<BufferTextureClient> newBufferTex = TextureClient::CreateForRawBufferAccess(
+    mAllocator, mFormat, mSize, mBackend, mFlags | aFlags, aAllocFlags
+  );
+
+  return newBufferTex.forget();
+}
+
+bool
+BufferTextureClient::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
+{
+  MOZ_ASSERT(IsValid());
+  MOZ_ASSERT(mFormat != gfx::SurfaceFormat::YUV, "This textureClient cannot use YCbCr data");
+  MOZ_ASSERT(aSize.width > 0 && aSize.height > 0);
+
+  if (aSize.width <= 0 || aSize.height <= 0) {
+    gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
     return false;
   }
 
-  MappedYCbCrTextureData srcData;
-  srcData.y.data = aData.mYChannel;
-  srcData.y.size = aData.mYSize;
-  srcData.y.stride = aData.mYStride;
-  srcData.y.skip = aData.mYSkip;
-  srcData.cb.data = aData.mCbChannel;
-  srcData.cb.size = aData.mCbCrSize;
-  srcData.cb.stride = aData.mCbCrStride;
-  srcData.cb.skip = aData.mCbSkip;
-  srcData.cr.data = aData.mCrChannel;
-  srcData.cr.size = aData.mCbCrSize;
-  srcData.cr.stride = aData.mCbCrStride;
-  srcData.cr.skip = aData.mCrSkip;
-  srcData.metadata = nullptr;
+  uint32_t bufSize = ImageDataSerializer::ComputeMinBufferSize(aSize, mFormat);
+  if (!bufSize || !Allocate(bufSize)) {
+    return false;
+  }
+
+  if (aFlags & ALLOC_CLEAR_BUFFER) {
+    memset(GetBuffer(), 0, bufSize);
+  }
+  if (aFlags & ALLOC_CLEAR_BUFFER_WHITE) {
+    memset(GetBuffer(), 0xFF, bufSize);
+  }
+
+  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
+  serializer.InitializeBufferInfo(aSize, mFormat);
+  mSize = aSize;
+  return true;
+}
+
+gfx::DrawTarget*
+BufferTextureClient::BorrowDrawTarget()
+{
+  MOZ_ASSERT(IsValid());
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mLocked, "BorrowDrawTarget should be called on locked textures only");
+  if (!mLocked) {
+    return nullptr;
+  }
+
+  if (mDrawTarget) {
+    mDrawTarget->SetTransform(Matrix());
+    return mDrawTarget;
+  }
+
+  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
+  if (!serializer.IsValid()) {
+    gfxCriticalNote << "Invalid serializer " << IsValid() << ", " << IsLocked() << ", " << GetBufferSize();
+    return nullptr;
+  }
+
+  mDrawTarget = serializer.GetAsDrawTarget(mBackend);
+  if (mDrawTarget) {
+    return mDrawTarget;
+  }
+
+  mDrawTarget = serializer.GetAsDrawTarget(BackendType::CAIRO);
+  if (!mDrawTarget) {
+    gfxCriticalNote << "BorrowDrawTarget failure, original backend " << (int)mBackend;
+  }
+
+  return mDrawTarget;
+}
+
+void
+BufferTextureClient::UpdateFromSurface(gfx::SourceSurface* aSurface)
+{
+  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
+
+  RefPtr<DataSourceSurface> surface = serializer.GetAsSurface();
+
+  if (!surface) {
+    gfxCriticalError() << "Failed to get serializer as surface!";
+    return;
+  }
+
+  RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
+
+  if (!srcSurf) {
+    gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
+    return;
+  }
 
-  if (!srcData.CopyInto(mapped)) {
+  if (surface->GetSize() != srcSurf->GetSize() || surface->GetFormat() != srcSurf->GetFormat()) {
+    gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format! This: " << surface->GetSize() << " " << surface->GetFormat() << " Other: " << aSurface->GetSize() << " " << aSurface->GetFormat();
+    return;
+  }
+
+  DataSourceSurface::MappedSurface sourceMap;
+  DataSourceSurface::MappedSurface destMap;
+  if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
+    gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
+    return;
+  }
+
+  if (!surface->Map(DataSourceSurface::WRITE, &destMap)) {
+    srcSurf->Unmap();
+    gfxCriticalError() << "Failed to map destination surface for UpdateFromSurface.";
+    return;
+  }
+
+
+  for (int y = 0; y < srcSurf->GetSize().height; y++) {
+    memcpy(destMap.mData + destMap.mStride * y,
+           sourceMap.mData + sourceMap.mStride * y,
+           srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
+  }
+
+  srcSurf->Unmap();
+  surface->Unmap();
+}
+
+bool
+BufferTextureClient::Lock(OpenMode aMode)
+{
+  MOZ_ASSERT(!mLocked, "The TextureClient is already Locked!");
+  mOpenMode = aMode;
+  mLocked = IsValid() && IsAllocated();;
+  return mLocked;
+}
+
+void
+BufferTextureClient::Unlock()
+{
+  MOZ_ASSERT(mLocked, "The TextureClient is already Unlocked!");
+  mLocked = false;
+  if (!mDrawTarget) {
+    return;
+  }
+
+  // see the comment on TextureClient::BorrowDrawTarget.
+  // This DrawTarget is internal to the TextureClient and is only exposed to the
+  // outside world between Lock() and Unlock(). This assertion checks that no outside
+  // reference remains by the time Unlock() is called.
+  MOZ_ASSERT(mDrawTarget->refCount() == 1);
+
+  if (mReadbackSink) {
+    RefPtr<SourceSurface> snapshot = mDrawTarget->Snapshot();
+    RefPtr<DataSourceSurface> dataSurf = snapshot->GetDataSurface();
+    mReadbackSink->ProcessReadback(dataSurf);
+  }
+
+  mDrawTarget->Flush();
+}
+
+bool
+BufferTextureClient::UpdateYCbCr(const PlanarYCbCrData& aData)
+{
+  MOZ_ASSERT(mLocked);
+  MOZ_ASSERT(mFormat == gfx::SurfaceFormat::YUV, "This textureClient can only use YCbCr data");
+  MOZ_ASSERT(!IsImmutable());
+  MOZ_ASSERT(IsValid());
+  MOZ_ASSERT(aData.mCbSkip == aData.mCrSkip);
+
+  YCbCrImageDataSerializer serializer(GetBuffer(), GetBufferSize());
+  MOZ_ASSERT(serializer.IsValid());
+  if (!serializer.CopyData(aData.mYChannel, aData.mCbChannel, aData.mCrChannel,
+                           aData.mYSize, aData.mYStride,
+                           aData.mCbCrSize, aData.mCbCrStride,
+                           aData.mYSkip, aData.mCbSkip)) {
     NS_WARNING("Failed to copy image data!");
     return false;
   }
 
-  if (TextureRequiresLocking(aTexture->GetFlags())) {
+  if (TextureRequiresLocking(mFlags)) {
     // We don't have support for proper locking yet, so we'll
     // have to be immutable instead.
-    aTexture->MarkImmutable();
+    MarkImmutable();
   }
   return true;
 }
 
+bool
+BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize,
+                                      gfx::IntSize aCbCrSize,
+                                      StereoMode aStereoMode)
+{
+  MOZ_ASSERT(IsValid());
+
+  size_t bufSize = YCbCrImageDataSerializer::ComputeMinBufferSize(aYSize,
+                                                                  aCbCrSize);
+  if (!bufSize || !Allocate(bufSize)) {
+    return false;
+  }
+  YCbCrImageDataSerializer serializer(GetBuffer(), GetBufferSize());
+  serializer.InitializeBufferInfo(aYSize,
+                                  aCbCrSize,
+                                  aStereoMode);
+  mSize = aYSize;
+  return true;
+}
+
+uint8_t*
+BufferTextureClient::GetLockedData() const
+{
+  MOZ_ASSERT(IsLocked());
+
+  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
+  MOZ_ASSERT(serializer.IsValid());
+
+  return serializer.GetData();
+}
+
 already_AddRefed<SyncObject>
 SyncObject::CreateSyncObject(SyncHandle aHandle)
 {
   if (!aHandle) {
     return nullptr;
   }
 
 #ifdef XP_WIN
   return MakeAndAddRef<SyncObjectD3D11>(aHandle);
 #else
   MOZ_ASSERT_UNREACHABLE();
   return nullptr;
 #endif
 }
 
-already_AddRefed<TextureClient>
-TextureClient::CreateWithData(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator)
-{
-  if (!aData) {
-    return nullptr;
-  }
-  return MakeAndAddRef<TextureClient>(aData, aFlags, aAllocator);
-}
-
-bool
-MappedYCbCrChannelData::CopyInto(MappedYCbCrChannelData& aDst)
-{
-  if (!data || !aDst.data || size != aDst.size) {
-    return false;
-  }
-
-  if (stride == aDst.stride) {
-    // fast path!
-    // We assume that the padding in the destination is there for alignment
-    // purposes and doesn't contain useful data.
-    memcpy(aDst.data, data, stride * size.height);
-    return true;
-  }
-
-  for (int32_t i = 0; i < size.height; ++i) {
-    if (aDst.skip == 0 && skip == 0) {
-      // fast-ish path
-      memcpy(aDst.data + i * aDst.stride,
-             data + i * stride,
-             size.width);
-    } else {
-      // slow path
-      uint8_t* src = data + i * stride;
-      uint8_t* dst = aDst.data + i * aDst.stride;
-      for (int32_t j = 0; j < size.width; ++j) {
-        *dst = *src;
-        src += 1 + skip;
-        dst += 1 + aDst.skip;
-      }
-    }
-  }
-  return true;
-}
-
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -34,39 +34,34 @@ class gfxImageSurface;
 namespace mozilla {
 
 // When defined, we track which pool the tile came from and test for
 // any inconsistencies.  This can be defined in release build as well.
 #ifdef DEBUG
 #define GFX_DEBUG_TRACK_CLIENTS_IN_POOL 1
 #endif
 
-namespace gl {
-class SharedSurface_Gralloc;
-}
-
 namespace layers {
 
 class AsyncTransactionWaiter;
 class CompositableForwarder;
 class ISurfaceAllocator;
 class CompositableClient;
 struct PlanarYCbCrData;
 class Image;
 class PTextureChild;
 class TextureChild;
-class TextureData;
-struct RawTextureBuffer;
-class RawYCbCrTextureBuffer;
+class BufferTextureClient;
 class TextureClient;
 class TextureClientRecycleAllocator;
 #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
 class TextureClientPool;
 #endif
 class KeepAlive;
+class GrallocTextureClientOGL;
 
 /**
  * TextureClient is the abstraction that allows us to share data between the
  * content and the compositor side.
  */
 
 enum TextureAllocationFlags {
   ALLOC_DEFAULT = 0,
@@ -96,16 +91,41 @@ public:
   virtual SyncType GetSyncType() = 0;
   virtual void FinalizeFrame() = 0;
 
 protected:
   SyncObject() { }
 };
 
 /**
+ * Interface for TextureClients that can be updated using YCbCr data.
+ */
+class TextureClientYCbCr
+{
+public:
+  /**
+   * Copy aData into this texture client.
+   *
+   * This must never be called on a TextureClient that is not sucessfully locked.
+   */
+  virtual bool UpdateYCbCr(const PlanarYCbCrData& aData) = 0;
+
+  /**
+   * Allocates for a given surface size, taking into account the pixel format
+   * which is part of the state of the TextureClient.
+   *
+   * Does not clear the surface, since we consider that the surface
+   * be painted entirely with opaque content.
+   */
+  virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
+                                gfx::IntSize aCbCrSize,
+                                StereoMode aStereoMode) = 0;
+};
+
+/**
  * This class may be used to asynchronously receive an update when the content
  * drawn to this texture client is available for reading in CPU memory. This
  * can only be used on texture clients that support draw target creation.
  */
 class TextureReadbackSink
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureReadbackSink)
 public:
@@ -122,106 +142,16 @@ protected:
 };
 
 enum class BackendSelector
 {
   Content,
   Canvas
 };
 
-/// Temporary object providing direct access to a Texture's memory.
-///
-/// see TextureClient::CanExposeMappedData() and TextureClient::BorrowMappedData().
-struct MappedTextureData
-{
-  uint8_t* data;
-  gfx::IntSize size;
-  int32_t stride;
-  gfx::SurfaceFormat format;
-};
-
-struct MappedYCbCrChannelData
-{
-  uint8_t* data;
-  gfx::IntSize size;
-  int32_t stride;
-  int32_t skip;
-
-  bool CopyInto(MappedYCbCrChannelData& aDst);
-};
-
-struct MappedYCbCrTextureData {
-  MappedYCbCrChannelData y;
-  MappedYCbCrChannelData cb;
-  MappedYCbCrChannelData cr;
-  // Sad but because of how SharedPlanarYCbCrData is used we have to expose this for now.
-  uint8_t* metadata;
-  StereoMode stereoMode;
-
-  bool CopyInto(MappedYCbCrTextureData& aDst)
-  {
-    return y.CopyInto(aDst.y)
-        && cb.CopyInto(aDst.cb)
-        && cr.CopyInto(aDst.cr);
-  }
-};
-
-class TextureData {
-public:
-  TextureData() { MOZ_COUNT_CTOR(TextureData); }
-
-  virtual ~TextureData() { MOZ_COUNT_DTOR(TextureData); }
-
-  virtual gfx::IntSize GetSize() const = 0;
-
-  virtual gfx::SurfaceFormat GetFormat() const = 0;
-
-  virtual bool Lock(OpenMode aMode, FenceHandle* aFence) = 0;
-
-  virtual void Unlock() = 0;
-
-  virtual bool SupportsMoz2D() const { return false; }
-
-  virtual bool CanExposeMappedData() const { return false; }
-
-  virtual bool HasInternalBuffer() const = 0;
-
-  virtual bool HasSynchronization() const { return false; }
-
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() { return nullptr; }
-
-  virtual bool BorrowMappedData(MappedTextureData&) { return false; }
-
-  virtual bool BorrowMappedYCbCrData(MappedYCbCrTextureData&) { return false; }
-
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) = 0;
-
-  /// Depending on the texture's flags either Deallocate or Forget is called.
-  virtual void Forget(ISurfaceAllocator* aAllocator) {}
-
-  virtual bool Serialize(SurfaceDescriptor& aDescriptor) = 0;
-
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags = TextureFlags::DEFAULT,
-                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const { return nullptr; }
-
-  virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) { return false; };
-
-  virtual bool ReadBack(TextureReadbackSink* aReadbackSink) { return false; }
-
-  /// Ideally this should not be exposed and users of TextureClient would use Lock/Unlock
-  /// preoperly but that requires a few changes to SharedSurface and maybe gonk video.
-  virtual void WaitForFence(FenceHandle* aFence) {};
-
-  virtual void SyncWithObject(SyncObject* aFence) {};
-
-  virtual TextureFlags GetTextureFlags() const { return TextureFlags::NO_FLAGS; }
-};
-
 /**
  * TextureClient is a thin abstraction over texture data that need to be shared
  * between the content process and the compositor process. It is the
  * content-side half of a TextureClient/TextureHost pair. A corresponding
  * TextureHost lives on the compositor-side.
  *
  * TextureClient's primary purpose is to present texture data in a way that is
  * understood by the IPC system. There are two ways to use it:
@@ -239,79 +169,92 @@ public:
  * responsibility of the compositable (which would use two Texture pairs).
  * In order to send several different buffers to the compositor side, use
  * several TextureClients.
  */
 class TextureClient
   : public AtomicRefCountedWithFinalize<TextureClient>
 {
 public:
-  explicit TextureClient(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator);
-
+  explicit TextureClient(ISurfaceAllocator* aAllocator,
+                         TextureFlags aFlags = TextureFlags::DEFAULT);
   virtual ~TextureClient();
 
-  static already_AddRefed<TextureClient>
-  CreateWithData(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator);
-
   // Creates and allocates a TextureClient usable with Moz2D.
   static already_AddRefed<TextureClient>
   CreateForDrawing(CompositableForwarder* aAllocator,
                    gfx::SurfaceFormat aFormat,
                    gfx::IntSize aSize,
                    BackendSelector aSelector,
                    TextureFlags aTextureFlags,
                    TextureAllocationFlags flags = ALLOC_DEFAULT);
 
-  // Creates and allocates a TextureClient supporting the YCbCr format.
-  static already_AddRefed<TextureClient>
+  // Creates and allocates a BufferTextureClient supporting the YCbCr format.
+  static already_AddRefed<BufferTextureClient>
   CreateForYCbCr(ISurfaceAllocator* aAllocator,
                  gfx::IntSize aYSize,
                  gfx::IntSize aCbCrSize,
                  StereoMode aStereoMode,
                  TextureFlags aTextureFlags);
 
-  // Creates and allocates a TextureClient (can be accessed through raw
+  // Creates and allocates a BufferTextureClient (can beaccessed through raw
   // pointers).
-  static already_AddRefed<TextureClient>
+  static already_AddRefed<BufferTextureClient>
   CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
                            gfx::SurfaceFormat aFormat,
                            gfx::IntSize aSize,
                            gfx::BackendType aMoz2dBackend,
                            TextureFlags aTextureFlags,
                            TextureAllocationFlags flags = ALLOC_DEFAULT);
 
-  // Creates and allocates a TextureClient (can beaccessed through raw
+  // Creates and allocates a BufferTextureClient (can beaccessed through raw
   // pointers) with a certain buffer size. It's unfortunate that we need this.
   // providing format and sizes could let us do more optimization.
-  static already_AddRefed<TextureClient>
+  static already_AddRefed<BufferTextureClient>
   CreateWithBufferSize(ISurfaceAllocator* aAllocator,
                        gfx::SurfaceFormat aFormat,
                        size_t aSize,
                        TextureFlags aTextureFlags);
 
   // Creates and allocates a TextureClient of the same type.
-  already_AddRefed<TextureClient>
+  virtual already_AddRefed<TextureClient>
   CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
-                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const;
+                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const = 0;
+
+  /**
+   * Allocates for a given surface size, taking into account the pixel format
+   * which is part of the state of the TextureClient.
+   *
+   * Does not clear the surface by default, clearing the surface can be done
+   * by passing the CLEAR_BUFFER flag.
+   *
+   * TextureClients that can expose a DrawTarget should override this method.
+   */
+  virtual bool AllocateForSurface(gfx::IntSize aSize,
+                                  TextureAllocationFlags flags = ALLOC_DEFAULT)
+  {
+    return false;
+  }
+
+  virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; }
+  virtual GrallocTextureClientOGL* AsGrallocTextureClientOGL() { return nullptr; }
 
   /**
    * Locks the shared data, allowing the caller to get access to it.
    *
    * Please always lock/unlock when accessing the shared data.
    * If Lock() returns false, you should not attempt to access the shared data.
    */
-  bool Lock(OpenMode aMode);
+  virtual bool Lock(OpenMode aMode) { return IsValid(); }
 
-  void Unlock();
+  virtual void Unlock() {}
 
-  bool IsLocked() const { return mIsLocked; }
+  virtual bool IsLocked() const = 0;
 
-  bool CanExposeDrawTarget() const { return mData->SupportsMoz2D(); }
-
-  bool CanExposeMappedData() const { return mData->CanExposeMappedData(); }
+  virtual bool CanExposeDrawTarget() const { return false; }
 
   /**
    * Returns a DrawTarget to draw into the TextureClient.
    * This function should never be called when not on the main thread!
    *
    * This must never be called on a TextureClient that is not sucessfully locked.
    * When called several times within one Lock/Unlock pair, this method should
    * return the same DrawTarget.
@@ -329,71 +272,66 @@ public:
    *   // Restrict this code's scope to ensure all references to dt are gone
    *   // when Unlock is called.
    *   DrawTarget* dt = texture->BorrowDrawTarget();
    *   // use the draw target ...
    * }
    * texture->Unlock();
    *
    */
-  gfx::DrawTarget* BorrowDrawTarget();
-
-  /**
-   * Similar to BorrowDrawTarget but provides direct access to the texture's bits
-   * instead of a DrawTarget.
-   */
-  bool BorrowMappedData(MappedTextureData&);
-  bool BorrowMappedYCbCrData(MappedYCbCrTextureData&);
+  virtual gfx::DrawTarget* BorrowDrawTarget() { return nullptr; }
 
   /**
    * This function can be used to update the contents of the TextureClient
    * off the main thread.
    */
-  void UpdateFromSurface(gfx::SourceSurface* aSurface);
+  virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) { MOZ_CRASH(); }
 
-  virtual gfx::SurfaceFormat GetFormat() const;
+  // TextureClients that can expose a DrawTarget should override this method.
+  virtual gfx::SurfaceFormat GetFormat() const
+  {
+    return gfx::SurfaceFormat::UNKNOWN;
+  }
 
   /**
    * This method is strictly for debugging. It causes locking and
    * needless copies.
    */
-  already_AddRefed<gfx::DataSourceSurface> GetAsSurface() {
+  virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() {
     Lock(OpenMode::OPEN_READ);
     RefPtr<gfx::SourceSurface> surf = BorrowDrawTarget()->Snapshot();
     RefPtr<gfx::DataSourceSurface> data = surf->GetDataSurface();
     Unlock();
     return data.forget();
   }
 
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
 
   /**
    * Copies a rectangle from this texture client to a position in aTarget.
    * It is assumed that the necessary locks are in place; so this should at
    * least have a read lock and aTarget should at least have a write lock.
    */
-  bool CopyToTextureClient(TextureClient* aTarget,
-                           const gfx::IntRect* aRect,
-                           const gfx::IntPoint* aPoint);
+  virtual bool CopyToTextureClient(TextureClient* aTarget,
+                                   const gfx::IntRect* aRect,
+                                   const gfx::IntPoint* aPoint);
 
   /**
-   * Returns true if this texture has a synchronization mechanism (mutex, fence, etc.).
-   * Textures that do not implement synchronization should be immutable or should
+   * 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)
-   * Even if a texture does not implement synchronization, Lock and Unlock need
-   * to be used appropriately since the latter are also there to map/numap data.
    */
-  bool HasSynchronization() const { return false; }
+  virtual bool ImplementsLocking() const { return false; }
 
   /**
    * Indicates whether the TextureClient implementation is backed by an
    * in-memory buffer. The consequence of this is that locking the
    * TextureClient does not contend with locking the texture on the host side.
    */
-  bool HasInternalBuffer() const;
+  virtual bool HasInternalBuffer() const = 0;
 
   /**
    * Allocate and deallocate a TextureChild actor.
    *
    * TextureChild is an implementation detail of TextureClient 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 AllocPextureChild and DeallocPTextureChild).
@@ -401,17 +339,19 @@ public:
   static PTextureChild* CreateIPDLActor();
   static bool DestroyIPDLActor(PTextureChild* actor);
 
   /**
    * Get the TextureClient corresponding to the actor passed in parameter.
    */
   static TextureClient* AsTextureClient(PTextureChild* actor);
 
-  gfx::IntSize GetSize() const;
+  virtual bool IsAllocated() const = 0;
+
+  virtual gfx::IntSize GetSize() const = 0;
 
   /**
    * TextureFlags contain important information about various aspects
    * of the texture, like how its liferime is managed, and how it
    * should be displayed.
    * See TextureFlags in CompositorTypes.h.
    */
   TextureFlags GetFlags() const { return mFlags; }
@@ -442,34 +382,46 @@ public:
    * textures.
    */
   bool IsImmutable() const { return !!(mFlags & TextureFlags::IMMUTABLE); }
 
   void MarkImmutable() { AddFlags(TextureFlags::IMMUTABLE); }
 
   bool IsSharedWithCompositor() const;
 
+  bool ShouldDeallocateInDestructor() const;
+
   /**
    * If this method returns false users of TextureClient are not allowed
    * to access the shared data.
    */
-  bool IsValid() const { return !!mData; }
+  bool IsValid() const { return mValid; }
 
   /**
    * Called when TextureClient is added to CompositableClient.
    */
   void SetAddedToCompositableClient();
 
   /**
    * If this method retuns false, TextureClient is already added to CompositableClient,
    * since its creation or recycling.
    */
   bool IsAddedToCompositableClient() const { return mAddedToCompositableClient; }
 
   /**
+   * kee the passed object alive until the IPDL actor is destroyed. This can
+   * help avoid race conditions in some cases.
+   * It's a temporary hack to ensure that DXGI textures don't get destroyed
+   * between serialization and deserialization.
+   *
+   * This must not be called off the texture's IPDL thread.
+   */
+  void KeepUntilFullDeallocation(UniquePtr<KeepAlive> aKeep, bool aMainThreadOnly = 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.
@@ -483,17 +435,17 @@ public:
    * Triggers the destruction of the shared data and the corresponding TextureHost.
    *
    * If the texture flags contain TextureFlags::DEALLOCATE_CLIENT, the destruction
    * will be synchronously coordinated with the compositor side, otherwise it
    * will be done asynchronously.
    * If sync is true, the destruction will be synchronous regardless of the
    * texture's flags (bad for performance, use with care).
    */
-  void Destroy(bool sync = false);
+  void ForceRemove(bool sync = false);
 
   virtual void SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle)
   {
     mReleaseFenceHandle.Merge(aReleaseFenceHandle);
   }
 
   virtual FenceHandle GetAndResetReleaseFenceHandle()
   {
@@ -510,99 +462,101 @@ public:
   virtual const FenceHandle& GetAcquireFenceHandle() const
   {
     return mAcquireFenceHandle;
   }
 
   /**
    * Set AsyncTransactionTracker of RemoveTextureFromCompositableAsync() transaction.
    */
-  virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter);
+  virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) {}
 
   /**
    * This function waits until the buffer is no longer being used.
-   *
-   * XXX - Ideally we shouldn't need this method because Lock the right
-   * thing already.
    */
-  virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true);
+  virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) {}
 
   /**
    * Track how much of this texture is wasted.
    * For example we might allocate a 256x256 tile but only use 10x10.
    */
    void SetWaste(int aWasteArea) {
      mWasteTracker.Update(aWasteArea, BytesPerPixel(GetFormat()));
    }
 
-  /**
-   * This sets the readback sink that this texture is to use. This will
-   * receive the data for this texture as soon as it becomes available after
-   * texture unlock.
-   */
-  virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) {
-    mReadbackSink = aReadbackSink;
+   /**
+    * This sets the readback sink that this texture is to use. This will
+    * receive the data for this texture as soon as it becomes available after
+    * texture unlock.
+    */
+   virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) {
+     mReadbackSink = aReadbackSink;
+   }
+
+   virtual void SyncWithObject(SyncObject* aSyncObject) { }
+
+   void MarkShared() {
+     mShared = true;
+   }
+
+  ISurfaceAllocator* GetAllocator()
+  {
+    return mAllocator;
   }
 
-  void SyncWithObject(SyncObject* aFence) { mData->SyncWithObject(aFence); }
-
-  ISurfaceAllocator* GetAllocator() { return mAllocator; }
-
    TextureClientRecycleAllocator* GetRecycleAllocator() { return mRecycleAllocator; }
    void SetRecycleAllocator(TextureClientRecycleAllocator* aAllocator);
 
-  /// If you add new code that uses this method, you are probably doing something wrong.
-  TextureData* GetInternalData() { return mData; }
-  const TextureData* GetInternalData() const { return mData; }
-
 private:
   static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);
 
   /**
    * Called once, during the destruction of the Texture, on the thread in which
    * texture's reference count reaches 0 (could be any thread).
    *
    * Here goes the shut-down code that uses virtual methods.
    * Must only be called by Release().
    */
-  B2G_ACL_EXPORT void Finalize() {}
+  B2G_ACL_EXPORT void Finalize();
+
+  /**
+   * Called once during the destruction of the texture on the IPDL thread, if
+   * the texture is shared on the compositor (otherwise it is not called at all).
+   */
+  virtual void FinalizeOnIPDLThread() {}
 
   friend class AtomicRefCountedWithFinalize<TextureClient>;
-  friend class gl::SharedSurface_Gralloc;
+
 protected:
   /**
+   * An invalid TextureClient cannot provide access to its shared data
+   * anymore. This usually means it will soon be destroyed.
+   */
+  void MarkInvalid() { mValid = false; }
+
+  /**
    * Should only be called *once* per texture, in TextureClient::InitIPDLActor.
    * Some texture implementations rely on the fact that the descriptor will be
    * deserialized.
    * Calling ToSurfaceDescriptor again after it has already returned true,
    * or never constructing a TextureHost with aDescriptor may result in a memory
    * leak (see TextureClientD3D9 for example).
    */
-  bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor);
-
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
 
+  RefPtr<TextureChild> mActor;
   RefPtr<ISurfaceAllocator> mAllocator;
-  RefPtr<TextureChild> mActor;
   RefPtr<TextureClientRecycleAllocator> mRecycleAllocator;
-  RefPtr<AsyncTransactionWaiter> mRemoveFromCompositableWaiter;
-
-  TextureData* mData;
-  RefPtr<gfx::DrawTarget> mBorrowedDrawTarget;
-
   TextureFlags mFlags;
   FenceHandle mReleaseFenceHandle;
   FenceHandle mAcquireFenceHandle;
   gl::GfxTextureWasteTracker mWasteTracker;
-
-  OpenMode mOpenMode;
-  DebugOnly<uint32_t> mExpectedDtRefs;
-  bool mIsLocked;
-
+  bool mShared;
+  bool mValid;
   bool mAddedToCompositableClient;
-  bool mWorkaroundAnnoyingSharedSurfaceLifetimeIssues;
 
   RefPtr<TextureReadbackSink> mReadbackSink;
 
   friend class TextureChild;
   friend class RemoveTextureFromCompositableTracker;
   friend void TestTextureClientSurface(TextureClient*, gfxImageSurface*);
   friend void TestTextureClientYCbCr(TextureClient*, PlanarYCbCrData&);
 
@@ -627,16 +581,153 @@ public:
     {
         mTextureClient = nullptr;
     }
 
 private:
     RefPtr<TextureClient> mTextureClient;
 };
 
+/**
+ * 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
+                          , public TextureClientYCbCr
+{
+public:
+  BufferTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
+                      gfx::BackendType aBackend, TextureFlags aFlags);
+
+  virtual ~BufferTextureClient();
+
+  virtual bool IsAllocated() const override = 0;
+
+  virtual uint8_t* GetBuffer() const = 0;
+
+  virtual gfx::IntSize GetSize() const override { return mSize; }
+
+  virtual bool Lock(OpenMode aMode) override;
+
+  virtual void Unlock() override;
+
+  virtual bool IsLocked() const override { return mLocked; }
+
+  uint8_t* GetLockedData() const;
+
+  virtual bool CanExposeDrawTarget() const override { return true; }
+
+  virtual gfx::DrawTarget* BorrowDrawTarget() override;
+
+  virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
+
+  virtual bool AllocateForSurface(gfx::IntSize aSize,
+                                  TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
+
+  // TextureClientYCbCr
+
+  virtual TextureClientYCbCr* AsTextureClientYCbCr() override { return this; }
+
+  virtual bool UpdateYCbCr(const PlanarYCbCrData& aData) override;
+
+  virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
+                                gfx::IntSize aCbCrSize,
+                                StereoMode aStereoMode) override;
+
+  virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
+
+  // XXX - Bug 908196 - Make Allocate(uint32_t) and GetBufferSize() protected.
+  // these two methods should only be called by methods of BufferTextureClient
+  // that are overridden in GrallocTextureClient (which does not implement the
+  // two methods below)
+  virtual bool Allocate(uint32_t aSize) = 0;
+
+  virtual size_t GetBufferSize() const = 0;
+
+  virtual bool HasInternalBuffer() const override { return true; }
+
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
+                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
+
+protected:
+  RefPtr<gfx::DrawTarget> mDrawTarget;
+  gfx::SurfaceFormat mFormat;
+  gfx::IntSize mSize;
+  gfx::BackendType mBackend;
+  OpenMode mOpenMode;
+  bool mLocked;
+};
+
+/**
+ * TextureClient that wraps shared memory.
+ * the corresponding texture on the host side is ShmemTextureHost.
+ */
+class ShmemTextureClient : public BufferTextureClient
+{
+public:
+  ShmemTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
+                     gfx::BackendType aBackend, TextureFlags aFlags);
+
+protected:
+  ~ShmemTextureClient();
+
+public:
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) override;
+
+  virtual bool Allocate(uint32_t aSize) override;
+
+  virtual uint8_t* GetBuffer() const override;
+
+  virtual size_t GetBufferSize() const override;
+
+  virtual bool IsAllocated() const override { return mAllocated; }
+
+  virtual bool HasInternalBuffer() const override { return true; }
+
+  mozilla::ipc::Shmem& GetShmem() { return mShmem; }
+
+protected:
+  mozilla::ipc::Shmem mShmem;
+  bool mAllocated;
+};
+
+/**
+ * TextureClient that wraps raw memory.
+ * The corresponding texture on the host side is MemoryTextureHost.
+ * Can obviously not be used in a cross process setup.
+ */
+class MemoryTextureClient : public BufferTextureClient
+{
+public:
+  MemoryTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
+                      gfx::BackendType aBackend, TextureFlags aFlags);
+
+protected:
+  ~MemoryTextureClient();
+
+public:
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) override;
+
+  virtual bool Allocate(uint32_t aSize) override;
+
+  virtual uint8_t* GetBuffer() const override { return mBuffer; }
+
+  virtual size_t GetBufferSize() const override { return mBufSize; }
+
+  virtual bool IsAllocated() const override { return mBuffer != nullptr; }
+
+  virtual bool HasInternalBuffer() const override { return true; }
+
+protected:
+  uint8_t* mBuffer;
+  size_t mBufSize;
+};
+
 // Automatically lock and unlock a texture. Since texture locking is fallible,
 // Succeeded() must be checked on the guard object before proceeding.
 class MOZ_RAII TextureClientAutoLock
 {
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
 
 public:
   TextureClientAutoLock(TextureClient* aTexture, OpenMode aMode
@@ -677,15 +768,12 @@ template<typename T>
 class TKeepAlive : public KeepAlive
 {
 public:
   explicit TKeepAlive(T* aData) : mData(aData) {}
 protected:
   RefPtr<T> mData;
 };
 
-/// Convenience function to set the content of ycbcr texture.
-bool UpdateYCbCrTextureClient(TextureClient* aTexture, const PlanarYCbCrData& aData);
-
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/client/TextureClientPool.cpp
+++ b/gfx/layers/client/TextureClientPool.cpp
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "TextureClientPool.h"
 #include "CompositableClient.h"
-#include "mozilla/layers/CompositableForwarder.h"
+#include "mozilla/layers/ISurfaceAllocator.h"
 
 #include "gfxPrefs.h"
 
 #include "nsComponentManagerUtils.h"
 
 #define TCP_LOG(...)
 //#define TCP_LOG(...) printf_stderr(__VA_ARGS__);
 
--- a/gfx/layers/client/TextureClientSharedSurface.cpp
+++ b/gfx/layers/client/TextureClientSharedSurface.cpp
@@ -18,140 +18,98 @@
 #include "SharedSurfaceGralloc.h"
 #endif
 
 using namespace mozilla::gl;
 
 namespace mozilla {
 namespace layers {
 
-
-SharedSurfaceTextureData::SharedSurfaceTextureData(UniquePtr<gl::SharedSurface> surf)
-  : mSurf(Move(surf))
-{}
+SharedSurfaceTextureClient::SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator,
+                                                       TextureFlags aFlags,
+                                                       UniquePtr<gl::SharedSurface> surf,
+                                                       gl::SurfaceFactory* factory)
+  : TextureClient(aAllocator,
+                  aFlags | TextureFlags::RECYCLE | surf->GetTextureFlags())
+  , mSurf(Move(surf))
+{
+}
 
-SharedSurfaceTextureData::~SharedSurfaceTextureData()
-{}
-
-void
-SharedSurfaceTextureData::Deallocate(ISurfaceAllocator*)
-{}
+SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
+{
+  // Free the ShSurf implicitly.
+}
 
 gfx::IntSize
-SharedSurfaceTextureData::GetSize() const
+SharedSurfaceTextureClient::GetSize() const
 {
   return mSurf->mSize;
 }
 
 bool
-SharedSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
   return mSurf->ToSurfaceDescriptor(&aOutDescriptor);
 }
 
-
-SharedSurfaceTextureClient::SharedSurfaceTextureClient(SharedSurfaceTextureData* aData,
-                                                       TextureFlags aFlags,
-                                                       ISurfaceAllocator* aAllocator)
-: TextureClient(aData, aFlags, aAllocator)
-{
-  mWorkaroundAnnoyingSharedSurfaceLifetimeIssues = true;
-}
-
-already_AddRefed<SharedSurfaceTextureClient>
-SharedSurfaceTextureClient::Create(UniquePtr<gl::SharedSurface> surf, gl::SurfaceFactory* factory,
-                                   ISurfaceAllocator* aAllocator, TextureFlags aFlags)
-{
-  if (!surf) {
-    return nullptr;
-  }
-  TextureFlags flags = aFlags | TextureFlags::RECYCLE | surf->GetTextureFlags();
-  SharedSurfaceTextureData* data = new SharedSurfaceTextureData(Move(surf));
-  return MakeAndAddRef<SharedSurfaceTextureClient>(data, flags, aAllocator);
-}
-
 void
 SharedSurfaceTextureClient::SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle)
 {
 #ifdef MOZ_WIDGET_GONK
-  gl::SharedSurface_Gralloc* surf = nullptr;
-  if (Surf()->mType == gl::SharedSurfaceType::Gralloc) {
-    surf = gl::SharedSurface_Gralloc::Cast(Surf());
+  SharedSurface_Gralloc* surf = nullptr;
+  if (mSurf->mType == SharedSurfaceType::Gralloc) {
+    surf = SharedSurface_Gralloc::Cast(mSurf.get());
   }
   if (surf && surf->GetTextureClient()) {
     surf->GetTextureClient()->SetReleaseFenceHandle(aReleaseFenceHandle);
     return;
   }
 #endif
   TextureClient::SetReleaseFenceHandle(aReleaseFenceHandle);
 }
 
 FenceHandle
 SharedSurfaceTextureClient::GetAndResetReleaseFenceHandle()
 {
 #ifdef MOZ_WIDGET_GONK
-  gl::SharedSurface_Gralloc* surf = nullptr;
-  if (Surf()->mType == gl::SharedSurfaceType::Gralloc) {
-    surf = gl::SharedSurface_Gralloc::Cast(Surf());
+  SharedSurface_Gralloc* surf = nullptr;
+  if (mSurf->mType == SharedSurfaceType::Gralloc) {
+    surf = SharedSurface_Gralloc::Cast(mSurf.get());
   }
   if (surf && surf->GetTextureClient()) {
     return surf->GetTextureClient()->GetAndResetReleaseFenceHandle();
   }
 #endif
   return TextureClient::GetAndResetReleaseFenceHandle();
 }
 
 void
 SharedSurfaceTextureClient::SetAcquireFenceHandle(const FenceHandle& aAcquireFenceHandle)
 {
 #ifdef MOZ_WIDGET_GONK
-  gl::SharedSurface_Gralloc* surf = nullptr;
-  if (Surf()->mType == gl::SharedSurfaceType::Gralloc) {
-    surf = gl::SharedSurface_Gralloc::Cast(Surf());
+  SharedSurface_Gralloc* surf = nullptr;
+  if (mSurf->mType == SharedSurfaceType::Gralloc) {
+    surf = SharedSurface_Gralloc::Cast(mSurf.get());
   }
   if (surf && surf->GetTextureClient()) {
     return surf->GetTextureClient()->SetAcquireFenceHandle(aAcquireFenceHandle);
   }
 #endif
   TextureClient::SetAcquireFenceHandle(aAcquireFenceHandle);
 }
 
 const FenceHandle&
 SharedSurfaceTextureClient::GetAcquireFenceHandle() const
 {
 #ifdef MOZ_WIDGET_GONK
-  gl::SharedSurface_Gralloc* surf = nullptr;
-  if (Surf()->mType == gl::SharedSurfaceType::Gralloc) {
-    surf = gl::SharedSurface_Gralloc::Cast(Surf());
+  SharedSurface_Gralloc* surf = nullptr;
+  if (mSurf->mType == SharedSurfaceType::Gralloc) {
+    surf = SharedSurface_Gralloc::Cast(mSurf.get());
   }
   if (surf && surf->GetTextureClient()) {
     return surf->GetTextureClient()->GetAcquireFenceHandle();
   }
 #endif
   return TextureClient::GetAcquireFenceHandle();
 }
 
-SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
-{
-  // XXX - Things break when using the proper destruction handshake with
-  // SharedSurfaceTextureData because the TextureData outlives its gl
-  // context. Having a strong reference to the gl context creates a cycle.
-  // This needs to be fixed in a better way, though, because deleting
-  // the TextureData here can race with the compositor and cause flashing.
-  TextureData* data = mData;
-  mData = nullptr;
-
-  Destroy();
-
-  if (data) {
-    // Destroy mData right away without doing the proper deallocation handshake,
-    // because SharedSurface depends on things that may not outlive the texture's
-    // destructor so we can't wait until we know the compositor isn't using the
-    // texture anymore.
-    // It goes without saying that this is really bad and we should fix the bugs
-    // that block doing the right thing such as bug 1224199 sooner rather than
-    // later.
-    delete data;
-  }
-}
-
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/TextureClientSharedSurface.h
+++ b/gfx/layers/client/TextureClientSharedSurface.h
@@ -21,71 +21,60 @@ namespace mozilla {
 namespace gl {
 class GLContext;
 class SharedSurface;
 class SurfaceFactory;
 } // namespace gl
 
 namespace layers {
 
-class SharedSurfaceTextureClient;
-
-class SharedSurfaceTextureData : public TextureData
+class SharedSurfaceTextureClient : public TextureClient
 {
 protected:
   const UniquePtr<gl::SharedSurface> mSurf;
 
-  friend class SharedSurfaceTextureClient;
+  friend class gl::SurfaceFactory;
 
-  explicit SharedSurfaceTextureData(UniquePtr<gl::SharedSurface> surf);
-public:
+  SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags,
+                             UniquePtr<gl::SharedSurface> surf,
+                             gl::SurfaceFactory* factory);
 
-  ~SharedSurfaceTextureData();
+  ~SharedSurfaceTextureClient();
 
-  virtual bool Lock(OpenMode, FenceHandle*) override { return false; }
-
-  virtual void Unlock() override {}
-
+public:
+  virtual bool IsAllocated() const override { return true; }
+  virtual bool Lock(OpenMode) override { return false; }
+  virtual bool IsLocked() const override { return false; }
   virtual bool HasInternalBuffer() const override { return false; }
 
   virtual gfx::SurfaceFormat GetFormat() const override {
     return gfx::SurfaceFormat::UNKNOWN;
   }
 
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags, TextureAllocationFlags) const override {
+    return nullptr;
+  }
+
+  virtual bool AllocateForSurface(gfx::IntSize,
+                                  TextureAllocationFlags) override {
+    MOZ_CRASH("Should never hit this.");
+    return false;
+  }
+
   virtual gfx::IntSize GetSize() const override;
 
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
-
-  virtual void Deallocate(ISurfaceAllocator*) override;
-
-  gl::SharedSurface* Surf() const { return mSurf.get(); }
-};
-
-class SharedSurfaceTextureClient : public TextureClient
-{
-public:
-  SharedSurfaceTextureClient(SharedSurfaceTextureData* aData,
-                             TextureFlags aFlags,
-                             ISurfaceAllocator* aAllocator);
-
-  ~SharedSurfaceTextureClient();
-
-  static already_AddRefed<SharedSurfaceTextureClient>
-  Create(UniquePtr<gl::SharedSurface> surf, gl::SurfaceFactory* factory,
-         ISurfaceAllocator* aAllocator, TextureFlags aFlags);
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
 
   virtual void SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle) override;
-
   virtual FenceHandle GetAndResetReleaseFenceHandle() override;
-
   virtual void SetAcquireFenceHandle(const FenceHandle& aAcquireFenceHandle) override;
-
   virtual const FenceHandle& GetAcquireFenceHandle() const override;
 
   gl::SharedSurface* Surf() const {
-    return static_cast<const SharedSurfaceTextureData*>(GetInternalData())->Surf();
+    return mSurf.get();
   }
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_TEXTURECLIENT_SHAREDSURFACE_H
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -698,17 +698,17 @@ TileClient::DiscardFrontBuffer()
   }
 }
 
 void
 TileClient::DiscardBackBuffer()
 {
   if (mBackBuffer) {
     MOZ_ASSERT(mBackLock);
-    if (!mBackBuffer->HasSynchronization() && mBackLock->GetReadCount() > 1) {
+    if (!mBackBuffer->ImplementsLocking() && mBackLock->GetReadCount() > 1) {
       // Our current back-buffer is still locked by the compositor. This can occur
       // when the client is producing faster than the compositor can consume. In
       // this case we just want to drop it and not return it to the pool.
      mAllocator->ReportClientLost();
      if (mBackBufferOnWhite) {
        mAllocator->ReportClientLost();
      }
     } else {
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -15,64 +15,16 @@
 #include "mozilla/gfx/Logging.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
-static const GUID sD3D11TextureUsage =
-{ 0xd89275b0, 0x6c7d, 0x4038, { 0xb5, 0xfa, 0x4d, 0x87, 0x16, 0xd5, 0xcc, 0x4e } };
-
-/* This class gets its lifetime tied to a D3D texture
- * and increments memory usage on construction and decrements
- * on destruction */
-class TextureMemoryMeasurer : public IUnknown
-{
-public:
-  TextureMemoryMeasurer(size_t aMemoryUsed)
-  {
-    mMemoryUsed = aMemoryUsed;
-    gfxWindowsPlatform::sD3D11MemoryUsed += mMemoryUsed;
-    mRefCnt = 0;
-  }
-  STDMETHODIMP_(ULONG) AddRef() {
-    mRefCnt++;
-    return mRefCnt;
-  }
-  STDMETHODIMP QueryInterface(REFIID riid,
-                              void **ppvObject)
-  {
-    IUnknown *punk = nullptr;
-    if (riid == IID_IUnknown) {
-      punk = this;
-    }
-    *ppvObject = punk;
-    if (punk) {
-      punk->AddRef();
-      return S_OK;
-    } else {
-      return E_NOINTERFACE;
-    }
-  }
-
-  STDMETHODIMP_(ULONG) Release() {
-    int refCnt = --mRefCnt;
-    if (refCnt == 0) {
-      gfxWindowsPlatform::sD3D11MemoryUsed -= mMemoryUsed;
-      delete this;
-    }
-    return refCnt;
-  }
-private:
-  int mRefCnt;
-  int mMemoryUsed;
-};
-
 static DXGI_FORMAT
 SurfaceFormatToDXGIFormat(gfx::SurfaceFormat aFormat)
 {
   switch (aFormat) {
     case SurfaceFormat::B8G8R8A8:
       return DXGI_FORMAT_B8G8R8A8_UNORM;
     case SurfaceFormat::B8G8R8X8:
       return DXGI_FORMAT_B8G8R8A8_UNORM;
@@ -186,474 +138,30 @@ static bool LockD3DTexture(T* aTexture)
     if (FAILED(hr)) {
       NS_WARNING("Failed to lock the texture");
       return false;
     }
   }
   return true;
 }
 
-template<typename T>
-static bool HasKeyedMutex(T* aTexture)
-{
-  RefPtr<IDXGIKeyedMutex> mutex;
-  aTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
-  return !!mutex;
-}
-
 template<typename T> // ID3D10Texture2D or ID3D11Texture2D
 static void UnlockD3DTexture(T* aTexture)
 {
   MOZ_ASSERT(aTexture);
   RefPtr<IDXGIKeyedMutex> mutex;
   aTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
   if (mutex) {
     HRESULT hr = mutex->ReleaseSync(0);
     if (FAILED(hr)) {
       NS_WARNING("Failed to unlock the texture");
     }
   }
 }
 
-DXGITextureData::DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                 bool aNeedsClear, bool aNeedsClearWhite)
-: mSize(aSize)
-, mFormat(aFormat)
-, mNeedsClear(aNeedsClear)
-, mNeedsClearWhite(aNeedsClearWhite)
-, mHasSynchronization(false)
-{}
-
-D3D11TextureData::D3D11TextureData(ID3D11Texture2D* aTexture,
-                                   gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                   bool aNeedsClear, bool aNeedsClearWhite)
-: DXGITextureData(aSize, aFormat, aNeedsClear, aNeedsClearWhite)
-, mTexture(aTexture)
-{
-  MOZ_ASSERT(aTexture);
-  mHasSynchronization = HasKeyedMutex(aTexture);
-}
-
-D3D11TextureData::~D3D11TextureData()
-{
-#ifdef DEBUG
-  // An Azure DrawTarget needs to be locked when it gets nullptr'ed as this is
-  // when it calls EndDraw. This EndDraw should not execute anything so it
-  // shouldn't -really- need the lock but the debug layer chokes on this.
-  if (mDrawTarget) {
-    Lock(OpenMode::OPEN_NONE, nullptr);
-    mDrawTarget = nullptr;
-    Unlock();
-  }
-#endif
-}
-
-D3D10TextureData::D3D10TextureData(ID3D10Texture2D* aTexture,
-                 gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                 bool aNeedsClear, bool aNeedsClearWhite)
-: DXGITextureData(aSize, aFormat, aNeedsClear, aNeedsClearWhite)
-, mTexture(aTexture)
-{
-  MOZ_ASSERT(aTexture);
-  mHasSynchronization = HasKeyedMutex(aTexture);
-}
-
-D3D10TextureData::~D3D10TextureData()
-{
-#ifdef DEBUG
-  // An Azure DrawTarget needs to be locked when it gets nullptr'ed as this is
-  // when it calls EndDraw. This EndDraw should not execute anything so it
-  // shouldn't -really- need the lock but the debug layer chokes on this.
-  if (mDrawTarget) {
-    Lock(OpenMode::OPEN_NONE, nullptr);
-    mDrawTarget = nullptr;
-    Unlock();
-  }
-#endif
-}
-
-bool
-D3D11TextureData::Lock(OpenMode aMode, FenceHandle*)
-{
-  if (!LockD3DTexture(mTexture.get())) {
-    return false;
-  }
-
-  if (NS_IsMainThread()) {
-    if (!PrepareDrawTargetInLock(aMode)) {
-      Unlock();
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool
-D3D10TextureData::Lock(OpenMode aMode, FenceHandle*)
-{
-  if (!LockD3DTexture(mTexture.get())) {
-    return false;
-  }
-
-  if (NS_IsMainThread()) {
-    if (!PrepareDrawTargetInLock(aMode)) {
-      Unlock();
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool
-DXGITextureData::PrepareDrawTargetInLock(OpenMode aMode)
-{
-  // Make sure that successful write-lock means we will have a DrawTarget to
-  // write into.
-  if (!mDrawTarget && (aMode & OpenMode::OPEN_WRITE || mNeedsClear || mNeedsClearWhite)) {
-    mDrawTarget = BorrowDrawTarget();
-    if (!mDrawTarget) {
-      return false;
-    }
-  }
-
-  if (mNeedsClear) {
-    mDrawTarget->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
-    mNeedsClear = false;
-  }
-  if (mNeedsClearWhite) {
-    mDrawTarget->FillRect(Rect(0, 0, GetSize().width, GetSize().height), ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
-    mNeedsClearWhite = false;
-  }
-
-  return true;
-}
-
-void
-D3D11TextureData::Unlock()
-{
-  UnlockD3DTexture(mTexture.get());
-}
-
-void
-D3D10TextureData::Unlock()
-{
-  UnlockD3DTexture(mTexture.get());
-}
-
-void
-D3D11TextureData::SyncWithObject(SyncObject* aSyncObject)
-{
-  if (!aSyncObject || !NS_IsMainThread()) {
-    // When off the main thread we sync using a keyed mutex per texture.
-    return;
-  }
-
-  MOZ_ASSERT(aSyncObject->GetSyncType() == SyncObject::SyncType::D3D11);
-  SyncObjectD3D11* sync = static_cast<SyncObjectD3D11*>(aSyncObject);
-  sync->RegisterTexture(mTexture);
-}
-
-void
-D3D10TextureData::SyncWithObject(SyncObject* aSyncObject)
-{
-  if (!aSyncObject || !NS_IsMainThread()) {
-    // When off the main thread we sync using a keyed mutex per texture.
-    return;
-  }
-
-  MOZ_ASSERT(aSyncObject->GetSyncType() == SyncObject::SyncType::D3D11);
-  SyncObjectD3D11* sync = static_cast<SyncObjectD3D11*>(aSyncObject);
-  sync->RegisterTexture(mTexture);
-}
-
-bool
-DXGITextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
-{
-  RefPtr<IDXGIResource> resource;
-  GetDXGIResource((IDXGIResource**)getter_AddRefs(resource));
-  if (!resource) {
-    return false;
-  }
-  HANDLE sharedHandle;
-  HRESULT hr = resource->GetSharedHandle(&sharedHandle);
-  if (FAILED(hr)) {
-    LOGD3D11("Error getting shared handle for texture.");
-    return false;
-  }
-
-  aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat, mSize);
-  return true;
-}
-
-bool
-D3D10TextureData::ReadBack(TextureReadbackSink* aReadbackSinc)
-{
-  if (NS_IsMainThread() && aReadbackSinc && mTexture) {
-    ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
-
-    D3D10_TEXTURE2D_DESC desc;
-    mTexture->GetDesc(&desc);
-    desc.BindFlags = 0;
-    desc.Usage = D3D10_USAGE_STAGING;
-    desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
-    desc.MiscFlags = 0;
-
-    RefPtr<ID3D10Texture2D> tex;
-    HRESULT hr = device->CreateTexture2D(&desc, nullptr, getter_AddRefs(tex));
-
-    if (SUCCEEDED(hr)) {
-      device->CopyResource(tex, mTexture);
-      gfxWindowsPlatform::GetPlatform()->GetReadbackManager()->PostTask(tex, aReadbackSinc);
-    } else {
-      gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D3D11] CreateTexture2D failure " << mSize << " Code: " << gfx::hexa(hr);
-      aReadbackSinc->ProcessReadback(nullptr);
-    }
-  }
-
-  return true;
-}
-
-DXGITextureData*
-DXGITextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocationFlags aFlags)
-{
-  if (aFormat == SurfaceFormat::A8) {
-    // Currently we don't support A8 surfaces. Fallback.
-    return nullptr;
-  }
-
-  gfxWindowsPlatform* windowsPlatform = gfxWindowsPlatform::GetPlatform();
-  // When we're not on the main thread we're not going to be using Direct2D
-  // to access the contents of this texture client so we will always use D3D11.
-  bool haveD3d11Backend = windowsPlatform->GetContentBackendFor(LayersBackend::LAYERS_D3D11) == BackendType::DIRECT2D1_1 || !NS_IsMainThread();
-
-  if (haveD3d11Backend) {
-    return D3D11TextureData::Create(aSize, aFormat, aFlags);
-  } else {
-    return D3D10TextureData::Create(aSize, aFormat, aFlags);
-  }
-}
-
-DXGITextureData*
-D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocationFlags aFlags,
-                         ID3D11Device* aDevice)
-{
-  RefPtr<ID3D11Texture2D> texture11;
-  ID3D11Device* d3d11device = aDevice ? aDevice
-                            : gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread();
-  MOZ_ASSERT(d3d11device != nullptr);
-  if (!d3d11device) {
-    return nullptr;
-  }
-
-  CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
-                                aSize.width, aSize.height, 1, 1,
-                                D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
-
-  newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
-  if (!NS_IsMainThread()) {
-    // On the main thread we use the syncobject to handle synchronization.
-    newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
-  }
-
-  HRESULT hr = d3d11device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(texture11));
-  if (FAILED(hr)) {
-    gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize)))
-      << "[D3D11] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
-    return nullptr;
-  }
-  texture11->SetPrivateDataInterface(sD3D11TextureUsage,
-                                     new TextureMemoryMeasurer(newDesc.Width * newDesc.Height * 4));
-  return new D3D11TextureData(texture11, aSize, aFormat,
-                              aFlags & ALLOC_CLEAR_BUFFER,
-                              aFlags & ALLOC_CLEAR_BUFFER_WHITE);
-}
-
-void
-D3D11TextureData::Deallocate(ISurfaceAllocator* aAllocator)
-{
-  mTexture = nullptr;
-}
-
-already_AddRefed<TextureClient>
-CreateD3D11TextureClientWithDevice(IntSize aSize, SurfaceFormat aFormat,
-                                   TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
-                                   ID3D11Device* aDevice,
-                                   ISurfaceAllocator* aAllocator)
-{
-  TextureData* data = D3D11TextureData::Create(aSize, aFormat, aAllocFlags, aDevice);
-  if (!data) {
-    return nullptr;
-  }
-  return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
-}
-
-TextureData*
-D3D11TextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
-                                TextureFlags aFlags,
-                                TextureAllocationFlags aAllocFlags) const
-{
-  return D3D11TextureData::Create(mSize, mFormat, aAllocFlags);
-}
-
-DXGITextureData*
-D3D10TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocationFlags aFlags)
-{
-  RefPtr<ID3D10Texture2D> texture10;
-  ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
-
-  CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
-    aSize.width, aSize.height, 1, 1,
-    D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
-
-  newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED;
-
-  HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(texture10));
-  if (FAILED(hr)) {
-    gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize)))
-      << "[D3D10] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
-    return nullptr;
-  }
-  texture10->SetPrivateDataInterface(sD3D11TextureUsage,
-                                     new TextureMemoryMeasurer(newDesc.Width * newDesc.Height * 4));
-
-  return new D3D10TextureData(texture10, aSize, aFormat,
-                              aFlags & ALLOC_CLEAR_BUFFER,
-                              aFlags & ALLOC_CLEAR_BUFFER_WHITE);
-}
-
-void
-D3D10TextureData::Deallocate(ISurfaceAllocator* aAllocator)
-{
-  mTexture = nullptr;
-}
-
-TextureData*
-D3D10TextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
-                                TextureFlags aFlags,
-                                TextureAllocationFlags aAllocFlags) const
-{
-  return D3D10TextureData::Create(mSize, mFormat, aAllocFlags);
-}
-
-void
-D3D11TextureData::GetDXGIResource(IDXGIResource** aOutResource)
-{
-  mTexture->QueryInterface(aOutResource);
-}
-
-void
-D3D10TextureData::GetDXGIResource(IDXGIResource** aOutResource)
-{
-  mTexture->QueryInterface(aOutResource);
-}
-
-DXGIYCbCrTextureData*
-DXGIYCbCrTextureData::Create(ISurfaceAllocator* aAllocator,
-                             TextureFlags aFlags,
-                             IUnknown* aTextureY,
-                             IUnknown* aTextureCb,
-                             IUnknown* aTextureCr,
-                             HANDLE aHandleY,
-                             HANDLE aHandleCb,
-                             HANDLE aHandleCr,
-                             const gfx::IntSize& aSize,
-                             const gfx::IntSize& aSizeY,
-                             const gfx::IntSize& aSizeCbCr)
-{
-  if (!aHandleY || !aHandleCb || !aHandleCr ||
-      !aTextureY || !aTextureCb || !aTextureCr) {
-    return nullptr;
-  }
-
-  DXGIYCbCrTextureData* texture = new DXGIYCbCrTextureData();
-  texture->mHandles[0] = aHandleY;
-  texture->mHandles[1] = aHandleCb;
-  texture->mHandles[2] = aHandleCr;
-  texture->mHoldRefs[0] = aTextureY;
-  texture->mHoldRefs[1] = aTextureCb;
-  texture->mHoldRefs[2] = aTextureCr;
-  texture->mSize = aSize;
-  texture->mSizeY = aSizeY;
-  texture->mSizeCbCr = aSizeCbCr;
-
-  return texture;
-}
-
-DXGIYCbCrTextureData*
-DXGIYCbCrTextureData::Create(ISurfaceAllocator* aAllocator,
-                             TextureFlags aFlags,
-                             ID3D11Texture2D* aTextureY,
-                             ID3D11Texture2D* aTextureCb,
-                             ID3D11Texture2D* aTextureCr,
-                             const gfx::IntSize& aSize,
-                             const gfx::IntSize& aSizeY,
-                             const gfx::IntSize& aSizeCbCr)
-{
-  if (!aTextureY || !aTextureCb || !aTextureCr) {
-    return nullptr;
-  }
-
-  aTextureY->SetPrivateDataInterface(sD3D11TextureUsage,
-    new TextureMemoryMeasurer(aSize.width * aSize.height));
-  aTextureCb->SetPrivateDataInterface(sD3D11TextureUsage,
-    new TextureMemoryMeasurer(aSizeCbCr.width * aSizeCbCr.height));
-  aTextureCr->SetPrivateDataInterface(sD3D11TextureUsage,
-    new TextureMemoryMeasurer(aSizeCbCr.width * aSizeCbCr.height));
-
-  RefPtr<IDXGIResource> resource;
-
-  aTextureY->QueryInterface((IDXGIResource**)getter_AddRefs(resource));
-
-  HANDLE handleY;
-  HRESULT hr = resource->GetSharedHandle(&handleY);
-  if (FAILED(hr)) {
-    return nullptr;
-  }
-
-  aTextureCb->QueryInterface((IDXGIResource**)getter_AddRefs(resource));
-
-  HANDLE handleCb;
-  hr = resource->GetSharedHandle(&handleCb);
-  if (FAILED(hr)) {
-    return nullptr;
-  }
-
-  aTextureCr->QueryInterface((IDXGIResource**)getter_AddRefs(resource));
-  HANDLE handleCr;
-  hr = resource->GetSharedHandle(&handleCr);
-  if (FAILED(hr)) {
-    return nullptr;
-  }
-
-  return DXGIYCbCrTextureData::Create(aAllocator, aFlags,
-                                      aTextureY, aTextureCb, aTextureCr,
-                                      handleY, handleCb, handleCr,
-                                      aSize, aSizeY, aSizeCbCr);
-}
-
-bool
-DXGIYCbCrTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
-{
-  aOutDescriptor = SurfaceDescriptorDXGIYCbCr(
-    (WindowsHandle)mHandles[0], (WindowsHandle)mHandles[1], (WindowsHandle)mHandles[2],
-    GetSize(), mSizeY, mSizeCbCr
-  );
-  return true;
-}
-
-void
-DXGIYCbCrTextureData::Deallocate(ISurfaceAllocator*)
-{
-  mHoldRefs[0] = nullptr;
-  mHoldRefs[1] = nullptr;
-  mHoldRefs[2] = nullptr;
-}
-
 already_AddRefed<TextureHost>
 CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
                        ISurfaceAllocator* aDeallocator,
                        TextureFlags aFlags)
 {
   RefPtr<TextureHost> result;
   switch (aDesc.type()) {
     case SurfaceDescriptor::TSurfaceDescriptorShmem:
@@ -673,114 +181,631 @@ CreateTextureHostD3D11(const SurfaceDesc
     }
     default: {
       NS_WARNING("Unsupported SurfaceDescriptor type");
     }
   }
   return result.forget();
 }
 
+TextureClientD3D11::TextureClientD3D11(ISurfaceAllocator* aAllocator,
+                                       gfx::SurfaceFormat aFormat,
+                                       TextureFlags aFlags)
+  : TextureClient(aAllocator, aFlags)
+  , mFormat(aFormat)
+  , mIsLocked(false)
+  , mNeedsClear(false)
+  , mNeedsClearWhite(false)
+{}
 
-already_AddRefed<DrawTarget>
-D3D11TextureData::BorrowDrawTarget()
+TextureClientD3D11::~TextureClientD3D11()
+{
+#ifdef DEBUG
+  // An Azure DrawTarget needs to be locked when it gets nullptr'ed as this is
+  // when it calls EndDraw. This EndDraw should not execute anything so it
+  // shouldn't -really- need the lock but the debug layer chokes on this.
+  if (mDrawTarget) {
+    MOZ_ASSERT(!mIsLocked);
+    MOZ_ASSERT(mTexture || mTexture10);
+    MOZ_ASSERT(mDrawTarget->refCount() == 1);
+    if (mTexture) {
+      LockD3DTexture(mTexture.get());
+    } else {
+      LockD3DTexture(mTexture10.get());
+    }
+    mDrawTarget = nullptr;
+    if (mTexture) {
+      UnlockD3DTexture(mTexture.get());
+    } else {
+      UnlockD3DTexture(mTexture10.get());
+    }
+  }
+#endif
+}
+
+void
+TextureClientD3D11::FinalizeOnIPDLThread()
 {
-  MOZ_ASSERT(NS_IsMainThread());
+  if (mActor) {
+    if (mTexture) {
+      KeepUntilFullDeallocation(MakeUnique<TKeepAlive<ID3D11Texture2D>>(mTexture));
+    } else if (mTexture10) {
+      KeepUntilFullDeallocation(MakeUnique<TKeepAlive<ID3D10Texture2D>>(mTexture10));
+    }
+  }
+}
+
+// static
+already_AddRefed<TextureClientD3D11>
+TextureClientD3D11::Create(ISurfaceAllocator* aAllocator,
+                           gfx::SurfaceFormat aFormat,
+                           TextureFlags aFlags,
+                           ID3D11Texture2D* aTexture,
+                           gfx::IntSize aSize)
+{
+  RefPtr<TextureClientD3D11> texture = new TextureClientD3D11(aAllocator,
+                                                             aFormat,
+                                                             aFlags);
+  texture->mTexture = aTexture;
+  texture->mSize = aSize;
+  return texture.forget();
+}
+
+already_AddRefed<TextureClientD3D11>
+TextureClientD3D11::Create(ISurfaceAllocator* aAllocator,
+                           gfx::SurfaceFormat aFormat,
+                           TextureFlags aFlags,
+                           ID3D11Device* aDevice,
+                           const gfx::IntSize& aSize)
+{
+  RefPtr<TextureClientD3D11> texture = new TextureClientD3D11(aAllocator,
+                                                              aFormat,
+                                                              aFlags);
+  if (!texture->AllocateD3D11Surface(aDevice, aSize)) {
+    return nullptr;
+  }
+  return texture.forget();
+}
 
-  if (!mDrawTarget && mTexture) {
-    // This may return a null DrawTarget
-    mDrawTarget = Factory::CreateDrawTargetForD3D11Texture(mTexture, mFormat);
-    if (!mDrawTarget) {
-      gfxCriticalNote << "Could not borrow DrawTarget (D3D11) " << (int)mFormat;
+already_AddRefed<TextureClient>
+TextureClientD3D11::CreateSimilar(TextureFlags aFlags,
+                                  TextureAllocationFlags aAllocFlags) const
+{
+  RefPtr<TextureClient> tex = new TextureClientD3D11(mAllocator, mFormat,
+                                                     mFlags | aFlags);
+
+  if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
+    return nullptr;
+  }
+
+  return tex.forget();
+}
+
+void
+TextureClientD3D11::SyncWithObject(SyncObject* aSyncObject)
+{
+  if (!aSyncObject || !NS_IsMainThread()) {
+    // When off the main thread we sync using a keyed mutex per texture.
+    return;
+  }
+
+  MOZ_ASSERT(aSyncObject->GetSyncType() == SyncObject::SyncType::D3D11);
+
+  SyncObjectD3D11* sync = static_cast<SyncObjectD3D11*>(aSyncObject);
+
+  if (mTexture) {
+    sync->RegisterTexture(mTexture);
+  } else {
+    sync->RegisterTexture(mTexture10);
+  }
+}
+
+bool
+TextureClientD3D11::Lock(OpenMode aMode)
+{
+  if (!IsAllocated()) {
+    return false;
+  }
+  MOZ_ASSERT(!mIsLocked, "The Texture is already locked!");
+
+  if (mTexture) {
+    MOZ_ASSERT(!mTexture10);
+    mIsLocked = LockD3DTexture(mTexture.get());
+  } else {
+    MOZ_ASSERT(!mTexture);
+    mIsLocked = LockD3DTexture(mTexture10.get());
+  }
+  if (!mIsLocked) {
+    return false;
+  }
+
+  if (NS_IsMainThread()) {
+    // Make sure that successful write-lock means we will have a DrawTarget to
+    // write into.
+    if (aMode & OpenMode::OPEN_WRITE) {
+      mDrawTarget = BorrowDrawTarget();
+      if (!mDrawTarget) {
+        Unlock();
+        return false;
+      }
+    }
+
+    if (mNeedsClear) {
+      mDrawTarget = BorrowDrawTarget();
+      if (!mDrawTarget) {
+        Unlock();
+        return false;
+      }
+      mDrawTarget->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
+      mNeedsClear = false;
+    }
+    if (mNeedsClearWhite) {
+      mDrawTarget = BorrowDrawTarget();
+      if (!mDrawTarget) {
+        Unlock();
+        return false;
+      }
+      mDrawTarget->FillRect(Rect(0, 0, GetSize().width, GetSize().height), ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
+      mNeedsClearWhite = false;
     }
   }
 
-  RefPtr<DrawTarget> result = mDrawTarget;
-  return result.forget();
+  return true;
 }
 
-already_AddRefed<DrawTarget>
-D3D10TextureData::BorrowDrawTarget()
+void
+TextureClientD3D11::Unlock()
 {
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
+  if (!mIsLocked) {
+    return;
+  }
+
+  if (mDrawTarget) {
+    // see the comment on TextureClient::BorrowDrawTarget.
+    // This DrawTarget is internal to the TextureClient and is only exposed to the
+    // outside world between Lock() and Unlock(). This assertion checks that no outside
+    // reference remains by the time Unlock() is called.
+    MOZ_ASSERT(mDrawTarget->refCount() == 1);
+    mDrawTarget->Flush();
+  }
 
-  if (!mDrawTarget && mTexture) {
-    // This may return a null DrawTarget
-    mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, mFormat);
-    if (!mDrawTarget) {
-      gfxCriticalNote << "Could not borrow DrawTarget (D3D10) " << (int)mFormat;
+  if (NS_IsMainThread() && mReadbackSink && mTexture10) {
+    ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
+    if (!device) {
+      return;
+    }
+
+    D3D10_TEXTURE2D_DESC desc;
+    mTexture10->GetDesc(&desc);
+    desc.BindFlags = 0;
+    desc.Usage = D3D10_USAGE_STAGING;
+    desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
+    desc.MiscFlags = 0;
+
+    RefPtr<ID3D10Texture2D> tex;
+    HRESULT hr = device->CreateTexture2D(&desc, nullptr, getter_AddRefs(tex));
+
+    if (SUCCEEDED(hr)) {
+      device->CopyResource(tex, mTexture10);
+      gfxWindowsPlatform::GetPlatform()->GetReadbackManager()->PostTask(tex, mReadbackSink);
+    } else {
+      gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D3D11] CreateTexture2D failure " << mSize << " Code: " << gfx::hexa(hr);
+      mReadbackSink->ProcessReadback(nullptr);
     }
   }
 
-  RefPtr<DrawTarget> result = mDrawTarget;
-  return result.forget();
+  // The DrawTarget is created only once, and is only usable between calls
+  // to Lock and Unlock.
+  if (mTexture) {
+    UnlockD3DTexture(mTexture.get());
+  } else {
+    UnlockD3DTexture(mTexture10.get());
+  }
+  mIsLocked = false;
 }
 
-bool
-D3D11TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
+DrawTarget*
+TextureClientD3D11::BorrowDrawTarget()
+{
+  MOZ_ASSERT(mIsLocked, "Calling TextureClient::BorrowDrawTarget without locking :(");
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (!mIsLocked || (!mTexture && !mTexture10)) {
+    gfxCriticalError() << "Attempted to borrow a DrawTarget without locking the texture.";
+    return nullptr;
+  }
+
+  if (mDrawTarget) {
+    return mDrawTarget;
+  }
+
+  // This may return a null DrawTarget
+  if (mTexture) {
+    mDrawTarget = Factory::CreateDrawTargetForD3D11Texture(mTexture, mFormat);
+  } else
+  {
+    MOZ_ASSERT(mTexture10);
+    mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture10, mFormat);
+  }
+  if (!mDrawTarget) {
+    gfxCriticalNote << "Invalid draw target for borrowing D3D11 " << (int)mFormat;
+  }
+  return mDrawTarget;
+}
+
+void
+TextureClientD3D11::UpdateFromSurface(gfx::SourceSurface* aSurface)
 {
   RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
 
   if (!srcSurf) {
     gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
-    return false;
+    return;
+  }
+
+  if (mDrawTarget) {
+    // Ensure unflushed work from our outstanding drawtarget won't override this
+    // update later.
+    mDrawTarget->Flush();
+  }
+
+  if (mSize != srcSurf->GetSize() || mFormat != srcSurf->GetFormat()) {
+    gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format!";
+    return;
   }
 
   DataSourceSurface::MappedSurface sourceMap;
   if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
     gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
+    return;
+  }
+
+  if (mTexture) {
+    RefPtr<ID3D11Device> device;
+    mTexture->GetDevice(getter_AddRefs(device));
+    RefPtr<ID3D11DeviceContext> ctx;
+    device->GetImmediateContext(getter_AddRefs(ctx));
+
+    D3D11_BOX box;
+    box.front = 0;
+    box.back = 1;
+    box.top = box.left = 0;
+    box.right = aSurface->GetSize().width;
+    box.bottom = aSurface->GetSize().height;
+
+    ctx->UpdateSubresource(mTexture, 0, &box, sourceMap.mData, sourceMap.mStride, 0);
+  } else {
+    RefPtr<ID3D10Device> device;
+    mTexture10->GetDevice(getter_AddRefs(device));
+
+    D3D10_BOX box;
+    box.front = 0;
+    box.back = 1;
+    box.top = box.left = 0;
+    box.right = aSurface->GetSize().width;
+    box.bottom = aSurface->GetSize().height;
+
+    device->UpdateSubresource(mTexture10, 0, &box, sourceMap.mData, sourceMap.mStride, 0);
+  }
+  srcSurf->Unmap();
+}
+
+static const GUID sD3D11TextureUsage =
+{ 0xd89275b0, 0x6c7d, 0x4038, { 0xb5, 0xfa, 0x4d, 0x87, 0x16, 0xd5, 0xcc, 0x4e } };
+
+/* This class gets its lifetime tied to a D3D texture
+ * and increments memory usage on construction and decrements
+ * on destruction */
+class TextureMemoryMeasurer : public IUnknown
+{
+public:
+  TextureMemoryMeasurer(size_t aMemoryUsed)
+  {
+    mMemoryUsed = aMemoryUsed;
+    gfxWindowsPlatform::sD3D11MemoryUsed += mMemoryUsed;
+    mRefCnt = 0;
+  }
+  STDMETHODIMP_(ULONG) AddRef() {
+    mRefCnt++;
+    return mRefCnt;
+  }
+  STDMETHODIMP QueryInterface(REFIID riid,
+                              void **ppvObject)
+  {
+    IUnknown *punk = nullptr;
+    if (riid == IID_IUnknown) {
+      punk = this;
+    }
+    *ppvObject = punk;
+    if (punk) {
+      punk->AddRef();
+      return S_OK;
+    } else {
+      return E_NOINTERFACE;
+    }
+  }
+
+  STDMETHODIMP_(ULONG) Release() {
+    int refCnt = --mRefCnt;
+    if (refCnt == 0) {
+      gfxWindowsPlatform::sD3D11MemoryUsed -= mMemoryUsed;
+      delete this;
+    }
+    return refCnt;
+  }
+private:
+  int mRefCnt;
+  int mMemoryUsed;
+};
+
+bool
+TextureClientD3D11::AllocateD3D11Surface(ID3D11Device* aDevice, const gfx::IntSize& aSize)
+{
+  MOZ_ASSERT(aDevice != nullptr);
+
+  CD3D11_TEXTURE2D_DESC newDesc(mFormat == SurfaceFormat::A8 ? DXGI_FORMAT_R8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM,
+                                aSize.width, aSize.height, 1, 1,
+                                D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
+
+  newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
+
+  if (!NS_IsMainThread()) {
+    // On the main thread we use the syncobject to handle synchronization.
+    newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
+  }
+
+  HRESULT hr = aDevice->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(mTexture));
+  if (FAILED(hr)) {
+    gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D3D11] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
+    return false;
+  }
+  mTexture->SetPrivateDataInterface(sD3D11TextureUsage,
+                                    new TextureMemoryMeasurer(newDesc.Width * newDesc.Height *
+                                                              (mFormat == SurfaceFormat::A8 ?
+                                                               1 : 4)));
+  mSize = aSize;
+  return true;
+}
+
+bool
+TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
+{
+  mSize = aSize;
+  HRESULT hr;
+
+  if (mFormat == SurfaceFormat::A8) {
+    // Currently TextureClientD3D11 does not support A8 surfaces. Fallback.
     return false;
   }
 
-  RefPtr<ID3D11Device> device;
-  mTexture->GetDevice(getter_AddRefs(device));
-  RefPtr<ID3D11DeviceContext> ctx;
-  device->GetImmediateContext(getter_AddRefs(ctx));
+  gfxWindowsPlatform* windowsPlatform = gfxWindowsPlatform::GetPlatform();
+  ID3D11Device* d3d11device = windowsPlatform->GetD3D11DeviceForCurrentThread();
+
+  // When we're not on the main thread we're not going to be using Direct2D
+  // to access the contents of this texture client so we will always use D3D11.
+  BackendType backend = windowsPlatform->GetContentBackendFor(LayersBackend::LAYERS_D3D11);
+  bool haveD3d11Backend = (backend == BackendType::DIRECT2D1_1) || !NS_IsMainThread();
+
+  if (haveD3d11Backend) {
+    if (!AllocateD3D11Surface(d3d11device, aSize)) {
+      return false;
+    }
+  } else {
+    ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
+    if (!device) {
+      return false;
+    }
 
-  D3D11_BOX box;
-  box.front = 0;
-  box.back = 1;
-  box.top = box.left = 0;
-  box.right = aSurface->GetSize().width;
-  box.bottom = aSurface->GetSize().height;
-  ctx->UpdateSubresource(mTexture, 0, &box, sourceMap.mData, sourceMap.mStride, 0);
-  srcSurf->Unmap();
+    CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
+      aSize.width, aSize.height, 1, 1,
+      D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
+
+    newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED;
+
+    hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(mTexture10));
+    if (FAILED(hr)) {
+      gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D3D10] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
+      return false;
+    }
+    mTexture10->SetPrivateDataInterface(sD3D11TextureUsage,
+                                        new TextureMemoryMeasurer(newDesc.Width * newDesc.Height *
+                                                                  (mFormat == SurfaceFormat::A8 ?
+                                                                   1 : 4)));
+
+  }
+
+  // Defer clearing to the next time we lock to avoid an extra (expensive) lock.
+  mNeedsClear = aFlags & ALLOC_CLEAR_BUFFER;
+  mNeedsClearWhite = aFlags & ALLOC_CLEAR_BUFFER_WHITE;
 
   return true;
 }
 
 bool
-D3D10TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
+TextureClientD3D11::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
-  RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
-
-  if (!srcSurf) {
-    gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
+  if (!IsAllocated()) {
     return false;
   }
+  RefPtr<IDXGIResource> resource;
+  if (mTexture) {
+    mTexture->QueryInterface((IDXGIResource**)getter_AddRefs(resource));
+  } else {
+    mTexture10->QueryInterface((IDXGIResource**)getter_AddRefs(resource));
+  }
 
-  DataSourceSurface::MappedSurface sourceMap;
-  if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
-    gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
+  HANDLE sharedHandle;
+  HRESULT hr = resource->GetSharedHandle(&sharedHandle);
+
+  if (FAILED(hr)) {
+    LOGD3D11("Error getting shared handle for texture.");
     return false;
   }
 
-  RefPtr<ID3D10Device> device;
-  mTexture->GetDevice(getter_AddRefs(device));
+  aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat, mSize);
+  return true;
+}
+
+DXGIYCbCrTextureClient::DXGIYCbCrTextureClient(ISurfaceAllocator* aAllocator,
+                                               TextureFlags aFlags)
+  : TextureClient(aAllocator, aFlags)
+  , mIsLocked(false)
+{
+  MOZ_COUNT_CTOR(DXGIYCbCrTextureClient);
+}
+
+class YCbCrKeepAliveD3D11 : public KeepAlive
+{
+public:
+  YCbCrKeepAliveD3D11(RefPtr<IUnknown> aTextures[3])
+  {
+    mTextures[0] = aTextures[0];
+    mTextures[1] = aTextures[1];
+    mTextures[2] = aTextures[2];
+  }
+
+protected:
+  RefPtr<IUnknown> mTextures[3];
+};
+
+DXGIYCbCrTextureClient::~DXGIYCbCrTextureClient()
+{
+  MOZ_COUNT_DTOR(DXGIYCbCrTextureClient);
+}
+
+void
+DXGIYCbCrTextureClient::FinalizeOnIPDLThread()
+{
+  if (mHoldRefs[0] && mActor) {
+    KeepUntilFullDeallocation(MakeUnique<YCbCrKeepAliveD3D11>(mHoldRefs), true);
+  }
+}
+
+// static
+already_AddRefed<DXGIYCbCrTextureClient>
+DXGIYCbCrTextureClient::Create(ISurfaceAllocator* aAllocator,
+                               TextureFlags aFlags,
+                               IDirect3DTexture9* aTextureY,
+                               IDirect3DTexture9* aTextureCb,
+                               IDirect3DTexture9* aTextureCr,
+                               HANDLE aHandleY,
+                               HANDLE aHandleCb,
+                               HANDLE aHandleCr,
+                               const gfx::IntSize& aSize,
+                               const gfx::IntSize& aSizeY,
+                               const gfx::IntSize& aSizeCbCr)
+{
+  if (!aHandleY || !aHandleCb || !aHandleCr ||
+      !aTextureY || !aTextureCb || !aTextureCr) {
+    return nullptr;
+  }
+
+  aTextureY->SetPrivateData(sD3D11TextureUsage,
+    new TextureMemoryMeasurer(aSizeY.width * aSizeY.height), sizeof(IUnknown*), D3DSPD_IUNKNOWN);
+  aTextureCb->SetPrivateData(sD3D11TextureUsage,
+    new TextureMemoryMeasurer(aSizeCbCr.width * aSizeCbCr.height), sizeof(IUnknown*), D3DSPD_IUNKNOWN);
+  aTextureCr->SetPrivateData(sD3D11TextureUsage,
+    new TextureMemoryMeasurer(aSizeCbCr.width * aSizeCbCr.height), sizeof(IUnknown*), D3DSPD_IUNKNOWN);
+
+  RefPtr<DXGIYCbCrTextureClient> texture =
+    new DXGIYCbCrTextureClient(aAllocator, aFlags);
+  texture->mHandles[0] = aHandleY;
+  texture->mHandles[1] = aHandleCb;
+  texture->mHandles[2] = aHandleCr;
+  texture->mHoldRefs[0] = aTextureY;
+  texture->mHoldRefs[1] = aTextureCb;
+  texture->mHoldRefs[2] = aTextureCr;
+  texture->mSize = aSize;
+  texture->mSizeY = aSizeY;
+  texture->mSizeCbCr = aSizeCbCr;
+  return texture.forget();
+}
 
-  D3D10_BOX box;
-  box.front = 0;
-  box.back = 1;
-  box.top = box.left = 0;
-  box.right = aSurface->GetSize().width;
-  box.bottom = aSurface->GetSize().height;
+already_AddRefed<DXGIYCbCrTextureClient>
+DXGIYCbCrTextureClient::Create(ISurfaceAllocator* aAllocator,
+                               TextureFlags aFlags,
+                               ID3D11Texture2D* aTextureY,
+                               ID3D11Texture2D* aTextureCb,
+                               ID3D11Texture2D* aTextureCr,
+                               const gfx::IntSize& aSize,
+                               const gfx::IntSize& aSizeY,
+                               const gfx::IntSize& aSizeCbCr)
+{
+  if (!aTextureY || !aTextureCb || !aTextureCr) {
+    return nullptr;
+  }
+
+  aTextureY->SetPrivateDataInterface(sD3D11TextureUsage,
+    new TextureMemoryMeasurer(aSize.width * aSize.height));
+  aTextureCb->SetPrivateDataInterface(sD3D11TextureUsage,
+    new TextureMemoryMeasurer(aSizeCbCr.width * aSizeCbCr.height));
+  aTextureCr->SetPrivateDataInterface(sD3D11TextureUsage,
+    new TextureMemoryMeasurer(aSizeCbCr.width * aSizeCbCr.height));
+
+  RefPtr<DXGIYCbCrTextureClient> texture =
+    new DXGIYCbCrTextureClient(aAllocator, aFlags);
+
+  RefPtr<IDXGIResource> resource;
+
+  aTextureY->QueryInterface((IDXGIResource**)getter_AddRefs(resource));
+  HRESULT hr = resource->GetSharedHandle(&texture->mHandles[0]);
+  if (FAILED(hr)) {
+    return nullptr;
+  }
+
+  aTextureCb->QueryInterface((IDXGIResource**)getter_AddRefs(resource));
+  hr = resource->GetSharedHandle(&texture->mHandles[1]);
+  if (FAILED(hr)) {
+    return nullptr;
+  }
 
-  device->UpdateSubresource(mTexture, 0, &box, sourceMap.mData, sourceMap.mStride, 0);
+  aTextureCr->QueryInterface((IDXGIResource**)getter_AddRefs(resource));
+  hr = resource->GetSharedHandle(&texture->mHandles[2]);
+  if (FAILED(hr)) {
+    return nullptr;
+  }
+
+  texture->mHoldRefs[0] = aTextureY;
+  texture->mHoldRefs[1] = aTextureCb;
+  texture->mHoldRefs[2] = aTextureCr;
+  texture->mSize = aSize;
+  texture->mSizeY = aSizeY;
+  texture->mSizeCbCr = aSizeCbCr;
+  return texture.forget();
+}
 
-  srcSurf->Unmap();
+bool
+DXGIYCbCrTextureClient::Lock(OpenMode)
+{
+  MOZ_ASSERT(!mIsLocked);
+  if (!IsValid()) {
+    return false;
+  }
+  mIsLocked = true;
+  return true;
+}
 
+void
+DXGIYCbCrTextureClient::Unlock()
+{
+  MOZ_ASSERT(mIsLocked, "Unlock called while the texture is not locked!");
+  mIsLocked = false;
+}
+
+bool
+DXGIYCbCrTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
+{
+  MOZ_ASSERT(IsValid());
+  if (!IsAllocated()) {
+    return false;
+  }
+
+  aOutDescriptor = SurfaceDescriptorDXGIYCbCr((WindowsHandle)mHandles[0], (WindowsHandle)mHandles[1], (WindowsHandle)mHandles[2],
+                                              GetSize(), mSizeY, mSizeCbCr);
   return true;
 }
 
 DXGITextureHostD3D11::DXGITextureHostD3D11(TextureFlags aFlags,
                                            const SurfaceDescriptorD3D10& aDescriptor)
   : TextureHost(aFlags)
   , mSize(aDescriptor.size())
   , mHandle(aDescriptor.handle())
@@ -844,17 +869,19 @@ DXGITextureHostD3D11::Lock()
   mIsLocked = LockD3DTexture(mTextureSource->GetD3D11Texture());
 
   return mIsLocked;
 }
 
 void
 DXGITextureHostD3D11::Unlock()
 {
+  MOZ_ASSERT(mIsLocked);
   UnlockD3DTexture(mTextureSource->GetD3D11Texture());
+  mIsLocked = false;
 }
 
 bool
 DXGITextureHostD3D11::BindTextureSource(CompositableTextureSourceRef& aTexture)
 {
   MOZ_ASSERT(mIsLocked);
   // If Lock was successful we must have a valid TextureSource.
   MOZ_ASSERT(mTextureSource);
@@ -1103,17 +1130,17 @@ DataTextureSourceD3D11::GetD3D11Texture(
 ID3D11ShaderResourceView*
 DataTextureSourceD3D11::GetShaderResourceView()
 {
   if (mIterating) {
     if (!mTileSRVs[mCurrentTile]) {
       if (!mTileTextures[mCurrentTile]) {
         return nullptr;
       }
-
+      
       RefPtr<ID3D11Device> device;
       mTileTextures[mCurrentTile]->GetDevice(getter_AddRefs(device));
       HRESULT hr = device->CreateShaderResourceView(mTileTextures[mCurrentTile], nullptr, getter_AddRefs(mTileSRVs[mCurrentTile]));
       if (FAILED(hr)) {
         gfxCriticalNote << "[D3D11] DataTextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
         return nullptr;
       }
     }
@@ -1219,17 +1246,17 @@ SyncObjectD3D11::FinalizeFrame()
 
   if (!mD3D10Texture && mD3D10SyncedTextures.size()) {
     ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
     if (!device) {
       return;
     }
 
     hr = device->OpenSharedResource(mHandle, __uuidof(ID3D10Texture2D), (void**)(ID3D10Texture2D**)getter_AddRefs(mD3D10Texture));
-
+    
     if (FAILED(hr) || !mD3D10Texture) {
       gfxCriticalError() << "Failed to D3D10 OpenSharedResource for frame finalization: " << hexa(hr);
 
       if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
         return;
       }
 
       gfxDevCrash(LogReason::D3D10FinalizeFrame) << "Without device reset: " << hexa(hr);
@@ -1246,17 +1273,17 @@ SyncObjectD3D11::FinalizeFrame()
       MOZ_CRASH("GFX: Cannot get D3D10 KeyedMutex");
     }
   }
 
   if (!mD3D11Texture && mD3D11SyncedTextures.size()) {
     ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
 
     hr = device->OpenSharedResource(mHandle, __uuidof(ID3D11Texture2D), (void**)(ID3D11Texture2D**)getter_AddRefs(mD3D11Texture));
-
+    
     if (FAILED(hr) || !mD3D11Texture) {
       gfxCriticalError() << "Failed to D3D11 OpenSharedResource for frame finalization: " << hexa(hr);
 
       if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
         return;
       }
 
       gfxDevCrash(LogReason::D3D11FinalizeFrame) << "Without device reset: " << hexa(hr);
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -1,215 +1,180 @@
 /* -*- 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_GFX_TEXTURED3D11_H
 #define MOZILLA_GFX_TEXTURED3D11_H
 
-#include "mozilla/gfx/2D.h"
 #include "mozilla/layers/Compositor.h"
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/TextureHost.h"
 #include "gfxWindowsPlatform.h"
 #include "mozilla/GfxMessageUtils.h"
 #include <d3d11.h>
 #include "d3d9.h"
 #include <vector>
 
 namespace mozilla {
 namespace layers {
 
 class CompositorD3D11;
 
-class DXGITextureData : public TextureData
+/**
+ * A TextureClient to share a D3D10 texture with the compositor thread.
+ * The corresponding TextureHost is DXGITextureHostD3D11
+ */
+class TextureClientD3D11 : public TextureClient
 {
 public:
-  virtual gfx::IntSize GetSize() const override { return mSize; }
- 
-  virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
- 
-  virtual bool SupportsMoz2D() const override { return true; }
+  TextureClientD3D11(ISurfaceAllocator* aAllocator,
+                     gfx::SurfaceFormat aFormat,
+                     TextureFlags aFlags);
+
+  virtual ~TextureClientD3D11();
+
+  // Creates a TextureClient and init width.
+  static already_AddRefed<TextureClientD3D11>
+  Create(ISurfaceAllocator* aAllocator,
+         gfx::SurfaceFormat aFormat,
+         TextureFlags aFlags,
+         ID3D11Texture2D* aTexture,
+         gfx::IntSize aSize);
+
+  static already_AddRefed<TextureClientD3D11>
+  Create(ISurfaceAllocator* aAllocator,
+         gfx::SurfaceFormat aFormat,
+         TextureFlags aFlags,
+         ID3D11Device* aDevice,
+         const gfx::IntSize& aSize);
+
+  // TextureClient
+
+  virtual bool IsAllocated() const override { return mTexture || mTexture10; }
+
+  virtual bool Lock(OpenMode aOpenMode) override;
+
+  virtual void Unlock() override;
+
+  virtual bool IsLocked() const override { return mIsLocked; }
+
+  virtual bool ImplementsLocking() const override { return true; }
 
   virtual bool HasInternalBuffer() const override { return false; }
 
-  virtual bool HasSynchronization() const override { return mHasSynchronization; }
-
-  virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
 
-  static DXGITextureData*
-  Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
-
-protected:
-  bool PrepareDrawTargetInLock(OpenMode aMode);
+  virtual gfx::IntSize GetSize() const override { return mSize; }
 
-  DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, bool aNeedsClear, bool aNeedsClearWhite);
-
-  virtual void GetDXGIResource(IDXGIResource** aOutResource) = 0;
+  virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
 
-  // Hold on to the DrawTarget because it is expensive to create one each ::Lock.
-  RefPtr<gfx::DrawTarget> mDrawTarget;
-  gfx::IntSize mSize;
-  gfx::SurfaceFormat mFormat;
-  bool mNeedsClear;
-  bool mNeedsClearWhite;
-  bool mHasSynchronization;
-};
+  virtual bool CanExposeDrawTarget() const override { return true; }
+
+  virtual gfx::DrawTarget* BorrowDrawTarget() override;
 
-class D3D11TextureData : public DXGITextureData
-{
-public:
-  // If aDevice is null, use one provided by gfxWindowsPlatform.
-  static DXGITextureData*
-  Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-         TextureAllocationFlags aAllocFlags,
-         ID3D11Device* aDevice = nullptr);
+  virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
-  virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
+  virtual bool AllocateForSurface(gfx::IntSize aSize,
+                                  TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
 
-  virtual bool Lock(OpenMode aMode, FenceHandle*) override;
-
-  virtual void Unlock() override;
-
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
+                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags,
-                TextureAllocationFlags aAllocFlags) const override;
-
-  // TODO - merge this with the FenceHandle API!
-  virtual void SyncWithObject(SyncObject* aSync) override;
+  virtual void SyncWithObject(SyncObject* aSyncObject) override;
 
   ID3D11Texture2D* GetD3D11Texture() { return mTexture; }
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
+protected:
+  bool AllocateD3D11Surface(ID3D11Device* aDevice, const gfx::IntSize& aSize);
+
+  virtual void FinalizeOnIPDLThread() override;
 
-  ~D3D11TextureData();
-protected:
-  D3D11TextureData(ID3D11Texture2D* aTexture,
-                   gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                   bool aNeedsClear, bool aNeedsClearWhite);
-
-  virtual void GetDXGIResource(IDXGIResource** aOutResource) override;
-
+  gfx::IntSize mSize;
+  RefPtr<ID3D10Texture2D> mTexture10;
   RefPtr<ID3D11Texture2D> mTexture;
+  RefPtr<gfx::DrawTarget> mDrawTarget;
+  gfx::SurfaceFormat mFormat;
+  bool mIsLocked;
+  bool mNeedsClear;
+  bool mNeedsClearWhite;
 };
 
-already_AddRefed<TextureClient>
-CreateD3D11extureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                  TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
-                                  ID3D11Device* aDevice,
-                                  ISurfaceAllocator* aAllocator);
-
-
-class D3D10TextureData : public DXGITextureData
+class DXGIYCbCrTextureClient : public TextureClient
 {
 public:
-  static DXGITextureData*
-  Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
-
-  virtual bool Lock(OpenMode aMode, FenceHandle*) override;
-
-  virtual void Unlock() override;
-
-  virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
-
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
-
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags,
-                TextureAllocationFlags aAllocFlags) const override;
-
-  // TODO - merge this with the FenceHandle API!
-  virtual void SyncWithObject(SyncObject* aSync) override;
+  DXGIYCbCrTextureClient(ISurfaceAllocator* aAllocator,
+                         TextureFlags aFlags);
 
-  virtual bool ReadBack(TextureReadbackSink* aReadbackSinc) override;
-
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
-
-  ~D3D10TextureData();
-protected:
-  D3D10TextureData(ID3D10Texture2D* aTexture,
-                   gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                   bool aNeedsClear, bool aNeedsClearWhite);
+  virtual ~DXGIYCbCrTextureClient();
 
-  virtual void GetDXGIResource(IDXGIResource** aOutResource) override;
-
-  RefPtr<ID3D10Texture2D> mTexture;
-};
-
-class DXGIYCbCrTextureData : public TextureData
-{
-public:
-  static DXGIYCbCrTextureData*
+  // Creates a TextureClient and init width.
+  static already_AddRefed<DXGIYCbCrTextureClient>
   Create(ISurfaceAllocator* aAllocator,
          TextureFlags aFlags,
-         IUnknown* aTextureY,
-         IUnknown* aTextureCb,
-         IUnknown* aTextureCr,
+         IDirect3DTexture9* aTextureY,
+         IDirect3DTexture9* aTextureCb,
+         IDirect3DTexture9* aTextureCr,
          HANDLE aHandleY,
          HANDLE aHandleCb,
          HANDLE aHandleCr,
          const gfx::IntSize& aSize,
          const gfx::IntSize& aSizeY,
          const gfx::IntSize& aSizeCbCr);
 
-  static DXGIYCbCrTextureData*
+  // Creates a TextureClient and init width.
+  static already_AddRefed<DXGIYCbCrTextureClient>
   Create(ISurfaceAllocator* aAllocator,
          TextureFlags aFlags,
+         ID3D11Texture2D* aTextureY,
          ID3D11Texture2D* aTextureCb,
-         ID3D11Texture2D* aTextureY,
          ID3D11Texture2D* aTextureCr,
          const gfx::IntSize& aSize,
          const gfx::IntSize& aSizeY,
          const gfx::IntSize& aSizeCbCr);
 
-  virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
+  // TextureClient
 
-  virtual void Unlock() override {}
-
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
+  virtual bool IsAllocated() const override{ return !!mHoldRefs[0]; }
 
-  // TODO - DXGIYCbCrTextureClient returned true but that looks like a mistake
-  virtual bool HasInternalBuffer() const override{ return false; }
+  virtual bool Lock(OpenMode aOpenMode) override;
 
-  virtual gfx::IntSize GetSize() const override { return mSize; }
-
-  virtual gfx::SurfaceFormat GetFormat() const { return gfx::SurfaceFormat::YUV; }
-
-  virtual bool SupportsMoz2D() const { return false; }
+  virtual void Unlock() override;
 
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() { return nullptr; }
+  virtual bool IsLocked() const override{ return mIsLocked; }
 
-  // This TextureData should not be used in a context where we use CreateSimilar
-  // (ex. component alpha) because the underlying texture is always created by
-  // an external producer.
-  virtual DXGIYCbCrTextureData*
-  CreateSimilar(ISurfaceAllocator*, TextureFlags, TextureAllocationFlags) const override { return nullptr; }
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
-
-  virtual bool UpdateFromSurface(gfx::SourceSurface*) override { return false; }
-
-  virtual TextureFlags GetTextureFlags() const override
+  virtual gfx::IntSize GetSize() const
   {
-    return TextureFlags::DEALLOCATE_MAIN_THREAD;
+    return mSize;
   }
 
-protected:
-   RefPtr<IUnknown> mHoldRefs[3];
-   HANDLE mHandles[3];
-   gfx::IntSize mSize;
-   gfx::IntSize mSizeY;
-   gfx::IntSize mSizeCbCr;
+  virtual bool HasInternalBuffer() const override{ return true; }
+
+    // This TextureClient should not be used in a context where we use CreateSimilar
+    // (ex. component alpha) because the underlying texture data is always created by
+    // an external producer.
+    virtual already_AddRefed<TextureClient>
+    CreateSimilar(TextureFlags, TextureAllocationFlags) const override{ return nullptr; }
+
+private:
+  virtual void FinalizeOnIPDLThread() override;
+
+  RefPtr<IUnknown> mHoldRefs[3];
+  HANDLE mHandles[3];
+  gfx::IntSize mSize;
+  gfx::IntSize mSizeY;
+  gfx::IntSize mSizeCbCr;
+  bool mIsLocked;
 };
 
+
 /**
  * TextureSource that provides with the necessary APIs to be composited by a
  * CompositorD3D11.
  */
 class TextureSourceD3D11
 {
 public:
   TextureSourceD3D11() {}
@@ -297,23 +262,16 @@ protected:
   gfx::SurfaceFormat mFormat;
   TextureFlags mFlags;
   uint32_t mCurrentTile;
   bool mIsTiled;
   bool mIterating;
 
 };
 
-already_AddRefed<TextureClient>
-CreateD3D11TextureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                   TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
-                                   ID3D11Device* aDevice,
-                                   ISurfaceAllocator* aAllocator);
-
-
 /**
  * A TextureHost for shared D3D11 textures.
  */
 class DXGITextureHostD3D11 : public TextureHost
 {
 public:
   DXGITextureHostD3D11(TextureFlags aFlags,
                        const SurfaceDescriptorD3D10& aDescriptor);
@@ -364,17 +322,17 @@ public:
   virtual void SetCompositor(Compositor* aCompositor) override;
 
   virtual gfx::SurfaceFormat GetFormat() const override{ return gfx::SurfaceFormat::YUV; }
 
   virtual bool Lock() override;
 
   virtual void Unlock() override;
 
-  virtual gfx::IntSize GetSize() const override { return mSize; }
+  virtual gfx::IntSize GetSize() const override{ return mSize; }
 
   virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
   {
     return nullptr;
   }
 
 protected:
   ID3D11Device* GetDevice();
@@ -410,19 +368,19 @@ private:
 
   RefPtr<ID3D11RenderTargetView> mRTView;
 };
 
 class SyncObjectD3D11 : public SyncObject
 {
 public:
   SyncObjectD3D11(SyncHandle aSyncHandle);
-  virtual void FinalizeFrame();
 
   virtual SyncType GetSyncType() { return SyncType::D3D11; }
+  virtual void FinalizeFrame();
 
   void RegisterTexture(ID3D11Texture2D* aTexture);
   void RegisterTexture(ID3D10Texture2D* aTexture);
 
 private:
   RefPtr<ID3D11Texture2D> mD3D11Texture;
   RefPtr<ID3D10Texture2D> mD3D10Texture;
   std::vector<ID3D10Texture2D*> mD3D10SyncedTextures;
--- a/gfx/layers/d3d9/TextureD3D9.cpp
+++ b/gfx/layers/d3d9/TextureD3D9.cpp
@@ -437,260 +437,332 @@ DataTextureSourceD3D9::GetTileRect(uint3
 }
 
 IntRect
 DataTextureSourceD3D9::GetTileRect()
 {
   return GetTileRect(mCurrentTile);
 }
 
-
-D3D9TextureData::D3D9TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                 IDirect3DTexture9* aTexture)
-: mTexture(aTexture)
-, mSize(aSize)
-, mFormat(aFormat)
-, mNeedsClear(false)
-, mNeedsClearWhite(false)
+TextureClientD3D9::TextureClientD3D9(ISurfaceAllocator* aAllocator,
+                                     gfx::SurfaceFormat aFormat,
+                                     TextureFlags aFlags)
+  : TextureClient(aAllocator, aFlags)
+  , mFormat(aFormat)
+  , mIsLocked(false)
+  , mNeedsClear(false)
+  , mNeedsClearWhite(false)
+  , mLockRect(false)
 {
-  MOZ_COUNT_CTOR(D3D9TextureData);
-}
-
-D3D9TextureData::~D3D9TextureData()
-{
-  MOZ_COUNT_DTOR(D3D9TextureData);
+  MOZ_COUNT_CTOR(TextureClientD3D9);
 }
 
-D3D9TextureData*
-D3D9TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                        TextureAllocationFlags aAllocFlags)
+TextureClientD3D9::~TextureClientD3D9()
 {
-  _D3DFORMAT format = SurfaceFormatToD3D9Format(aFormat);
-  DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
-  RefPtr<IDirect3DTexture9> d3d9Texture = deviceManager ? deviceManager->CreateTexture(aSize, format,
-                                                                                       D3DPOOL_SYSTEMMEM,
-                                                                                       nullptr)
-                                                        : nullptr;
-  if (!d3d9Texture) {
-    NS_WARNING("Could not create a d3d9 texture");
+  MOZ_COUNT_DTOR(TextureClientD3D9);
+}
+
+already_AddRefed<TextureClient>
+TextureClientD3D9::CreateSimilar(TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
+{
+  RefPtr<TextureClient> tex = new TextureClientD3D9(mAllocator, mFormat,
+                                                    mFlags | aFlags);
+
+  if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
     return nullptr;
   }
-  D3D9TextureData* data = new D3D9TextureData(aSize, aFormat, d3d9Texture);
 
-  data->mNeedsClear = aAllocFlags & ALLOC_CLEAR_BUFFER;
-  data->mNeedsClearWhite = aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE;
-
-  return data;
-}
-
-TextureData*
-D3D9TextureData::CreateSimilar(ISurfaceAllocator*, TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
-{
-  return D3D9TextureData::Create(mSize, mFormat, aAllocFlags);
+  return tex.forget();
 }
 
 bool
-D3D9TextureData::Lock(OpenMode aMode, FenceHandle*)
+TextureClientD3D9::Lock(OpenMode aMode)
 {
+  MOZ_ASSERT(!mIsLocked);
+  if (!IsValid() || !IsAllocated()) {
+    return false;
+  }
+
   if (!gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
     // If the device has failed then we should not lock the surface,
     // even if we could.
     mD3D9Surface = nullptr;
     return false;
   }
 
   if (!mD3D9Surface) {
     HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(mD3D9Surface));
     if (FAILED(hr)) {
       NS_WARNING("Failed to get texture surface level.");
       return false;
     }
   }
+
+  mIsLocked = true;
+
   return true;
 }
+
 void
-D3D9TextureData::Unlock()
+TextureClientD3D9::Unlock()
 {
+  MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
+  if (!mIsLocked) {
+    return;
+  }
+
+  if (mDrawTarget) {
+    mDrawTarget->Flush();
+    mDrawTarget = nullptr;
+  }
+
   if (mLockRect) {
     mD3D9Surface->UnlockRect();
     mLockRect = false;
   }
+
+  mIsLocked = false;
 }
 
 bool
-D3D9TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+TextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
+  MOZ_ASSERT(IsValid());
+  if (!IsAllocated()) {
+    return false;
+  }
+
   mTexture->AddRef(); // Release in TextureHostD3D9::TextureHostD3D9
   aOutDescriptor = SurfaceDescriptorD3D9(reinterpret_cast<uintptr_t>(mTexture.get()));
   return true;
 }
 
-already_AddRefed<gfx::DrawTarget>
-D3D9TextureData::BorrowDrawTarget()
+gfx::DrawTarget*
+TextureClientD3D9::BorrowDrawTarget()
 {
-  MOZ_ASSERT(mD3D9Surface);
-  if (!mD3D9Surface) {
+  MOZ_ASSERT(mIsLocked && mD3D9Surface);
+  if (!mIsLocked || !mD3D9Surface) {
+    NS_WARNING("Calling BorrowDrawTarget on an Unlocked TextureClient");
+    gfxCriticalNote << "BorrowDrawTarget on an Unlocked TextureClient";
     return nullptr;
   }
 
-  RefPtr<DrawTarget> dt;
+  if (mDrawTarget) {
+    return mDrawTarget;
+  }
+
   if (ContentForFormat(mFormat) == gfxContentType::COLOR) {
     RefPtr<gfxASurface> surface = new gfxWindowsSurface(mD3D9Surface);
     if (!surface || surface->CairoStatus()) {
-      NS_WARNING("Could not create gfxASurface for d3d9 surface");
+      NS_WARNING("Could not create surface for d3d9 surface");
+      gfxCriticalNote << "Failed creation on D3D9";
       return nullptr;
     }
-    dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, mSize);
-
-    if (!dt) {
-      return nullptr;
+    mDrawTarget =
+      gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, mSize);
+    if (!mDrawTarget) {
+      gfxCriticalNote << "Bad draw target creation for surface D3D9 " << mSize;
     }
   } else {
     // gfxWindowsSurface don't support transparency so we can't use the d3d9
     // windows surface optimization.
     // Instead we have to use a gfxImageSurface and fallback for font drawing.
     D3DLOCKED_RECT rect;
     HRESULT hr = mD3D9Surface->LockRect(&rect, nullptr, 0);
     if (FAILED(hr) || !rect.pBits) {
       gfxCriticalError() << "Failed to lock rect borrowing the target in D3D9 " << hexa(hr);
       return nullptr;
     }
-    dt = gfxPlatform::GetPlatform()->CreateDrawTargetForData((uint8_t*)rect.pBits, mSize,
-                                                             rect.Pitch, mFormat);
-    if (!dt) {
-      return nullptr;
+    mDrawTarget =
+     gfxPlatform::GetPlatform()->CreateDrawTargetForData((uint8_t*)rect.pBits, mSize,
+                                                         rect.Pitch, mFormat);
+    if (!mDrawTarget) {
+      gfxCriticalNote << "Bad draw target creation for data D3D9 " << mSize << ", " << (int)mFormat;
     }
-
-     mLockRect = true;
+    mLockRect = true;
   }
 
   if (mNeedsClear) {
-    dt->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
+    mDrawTarget->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
     mNeedsClear = false;
   }
   if (mNeedsClearWhite) {
-    dt->FillRect(Rect(0, 0, GetSize().width, GetSize().height), ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
+    mDrawTarget->FillRect(Rect(0, 0, GetSize().width, GetSize().height), ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
     mNeedsClearWhite = false;
   }
 
-  return dt.forget();
+  return mDrawTarget;
 }
 
-bool
-D3D9TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
+void
+TextureClientD3D9::UpdateFromSurface(gfx::SourceSurface* aSurface)
 {
-  MOZ_ASSERT(mD3D9Surface);
+  MOZ_ASSERT(mIsLocked && mD3D9Surface);
 
   // gfxWindowsSurface don't support transparency so we can't use the d3d9
   // windows surface optimization.
   // Instead we have to use a gfxImageSurface and fallback for font drawing.
   D3DLOCKED_RECT rect;
   HRESULT hr = mD3D9Surface->LockRect(&rect, nullptr, 0);
   if (FAILED(hr) || !rect.pBits) {
     gfxCriticalError() << "Failed to lock rect borrowing the target in D3D9 " << hexa(hr);
-    return false;
+    return;
   }
 
   RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
 
   if (!srcSurf) {
     gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
-    mD3D9Surface->UnlockRect();
-    return false;
+    return;
+  }
+
+  if (mSize != srcSurf->GetSize() || mFormat != srcSurf->GetFormat()) {
+    gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format! This: " << mSize << " " << mFormat << " Other: " << srcSurf->GetSize() << " " << srcSurf->GetFormat();
+    return;
   }
 
   DataSourceSurface::MappedSurface sourceMap;
   if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
     gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
-    return false;
+    return;
   }
 
   for (int y = 0; y < srcSurf->GetSize().height; y++) {
     memcpy((uint8_t*)rect.pBits + rect.Pitch * y,
            sourceMap.mData + sourceMap.mStride * y,
            srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
   }
 
   srcSurf->Unmap();
   mD3D9Surface->UnlockRect();
+}
 
+bool
+TextureClientD3D9::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
+{
+  MOZ_ASSERT(!IsAllocated());
+  mSize = aSize;
+  _D3DFORMAT format = SurfaceFormatToD3D9Format(mFormat);
+
+  DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
+  if (!deviceManager ||
+      !(mTexture = deviceManager->CreateTexture(mSize, format, D3DPOOL_SYSTEMMEM, nullptr))) {
+    NS_WARNING("Could not create d3d9 texture");
+    return false;
+  }
+
+  mNeedsClear = aFlags & ALLOC_CLEAR_BUFFER;
+  mNeedsClearWhite = aFlags & ALLOC_CLEAR_BUFFER_WHITE;
+
+  MOZ_ASSERT(mTexture);
   return true;
 }
 
-DXGID3D9TextureData::DXGID3D9TextureData(gfx::SurfaceFormat aFormat,
-                                         IDirect3DTexture9* aTexture, HANDLE aHandle,
-                                         IDirect3DDevice9* aDevice)
-: mFormat(aFormat)
-, mTexture(aTexture)
-, mHandle(aHandle)
-, mDevice(aDevice)
+SharedTextureClientD3D9::SharedTextureClientD3D9(ISurfaceAllocator* aAllocator,
+                                                 gfx::SurfaceFormat aFormat,
+                                                 TextureFlags aFlags)
+  : TextureClient(aAllocator, aFlags)
+  , mFormat(aFormat)
+  , mHandle(0)
+  , mIsLocked(false)
 {
-  MOZ_COUNT_CTOR(DXGID3D9TextureData);
+  MOZ_COUNT_CTOR(SharedTextureClientD3D9);
 }
 
-DXGID3D9TextureData::~DXGID3D9TextureData()
+SharedTextureClientD3D9::~SharedTextureClientD3D9()
 {
-  gfxWindowsPlatform::sD3D9SharedTextureUsed -= mDesc.Width * mDesc.Height * 4;
-  MOZ_COUNT_DTOR(DXGID3D9TextureData);
+  MOZ_COUNT_DTOR(SharedTextureClientD3D9);
+  if (mTexture) {
+    gfxWindowsPlatform::sD3D9SharedTextureUsed -= mDesc.Width * mDesc.Height * 4;
+  }
+}
+
+void
+SharedTextureClientD3D9::FinalizeOnIPDLThread()
+{
+  if (mTexture && mActor) {
+    KeepUntilFullDeallocation(MakeUnique<TKeepAlive<IDirect3DTexture9>>(mTexture));
+  }
 }
 
 // static
-DXGID3D9TextureData*
-DXGID3D9TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                            TextureFlags aFlags,
-                            IDirect3DDevice9* aDevice)
+already_AddRefed<SharedTextureClientD3D9>
+SharedTextureClientD3D9::Create(ISurfaceAllocator* aAllocator,
+                                gfx::SurfaceFormat aFormat,
+                                TextureFlags aFlags,
+                                IDirect3DDevice9* aDevice,
+                                const gfx::IntSize& aSize)
 {
   MOZ_ASSERT(aFormat == gfx::SurfaceFormat::B8G8R8X8);
-  if (aFormat != gfx::SurfaceFormat::B8G8R8X8) {
-    return nullptr;
-  }
 
   RefPtr<IDirect3DTexture9> texture;
   HANDLE shareHandle = nullptr;
-  HRESULT hr = aDevice->CreateTexture(aSize.width, aSize.height,
+  HRESULT hr = aDevice->CreateTexture(aSize.width,
+                                      aSize.height,
                                       1,
                                       D3DUSAGE_RENDERTARGET,
                                       D3DFMT_X8R8G8B8,
                                       D3DPOOL_DEFAULT,
                                       getter_AddRefs(texture),
                                       &shareHandle);
-  if (FAILED(hr) || !shareHandle) {
-    return nullptr;
-  }
+  NS_ENSURE_TRUE(SUCCEEDED(hr) && shareHandle, nullptr);
 
-  D3DSURFACE_DESC surfaceDesc;
-  hr = texture->GetLevelDesc(0, &surfaceDesc);
-  if (FAILED(hr)) {
-    return nullptr;
-  }
-  DXGID3D9TextureData* data = new DXGID3D9TextureData(aFormat, texture, shareHandle, aDevice);
-  data->mDesc = surfaceDesc;
+  RefPtr<SharedTextureClientD3D9> client =
+    new SharedTextureClientD3D9(aAllocator,
+                                aFormat,
+                                aFlags);
+
+  client->mDevice = aDevice;
+  client->mTexture = texture;
+  client->mHandle = shareHandle;
+  texture->GetLevelDesc(0, &client->mDesc);
 
   gfxWindowsPlatform::sD3D9SharedTextureUsed += aSize.width * aSize.height * 4;
-  return data;
+  return client.forget();
 }
 
 already_AddRefed<IDirect3DSurface9>
-DXGID3D9TextureData::GetD3D9Surface() const
+SharedTextureClientD3D9::GetD3D9Surface() const
 {
   RefPtr<IDirect3DSurface9> textureSurface;
   HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(textureSurface));
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
   return textureSurface.forget();
 }
 
 bool
-DXGID3D9TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+SharedTextureClientD3D9::Lock(OpenMode)
 {
+  MOZ_ASSERT(!mIsLocked);
+  if (!IsValid()) {
+    return false;
+  }
+  mIsLocked = true;
+  return true;
+}
+
+void
+SharedTextureClientD3D9::Unlock()
+{
+  MOZ_ASSERT(mIsLocked, "Unlock called while the texture is not locked!");
+}
+
+bool
+SharedTextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
+{
+  MOZ_ASSERT(IsValid());
+  if (!IsAllocated()) {
+    return false;
+  }
+
   aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)(mHandle), mFormat, GetSize());
   return true;
 }
 
-
 TextureHostD3D9::TextureHostD3D9(TextureFlags aFlags,
                                  const SurfaceDescriptorD3D9& aDescriptor)
   : TextureHost(aFlags)
   , mFormat(SurfaceFormat::UNKNOWN)
   , mIsLocked(false)
 {
   mTexture = reinterpret_cast<IDirect3DTexture9*>(aDescriptor.texture());
   MOZ_ASSERT(mTexture);
--- a/gfx/layers/d3d9/TextureD3D9.h
+++ b/gfx/layers/d3d9/TextureD3D9.h
@@ -5,17 +5,16 @@
 
 #ifndef MOZILLA_GFX_TEXTURED3D9_H
 #define MOZILLA_GFX_TEXTURED3D9_H
 
 #include "mozilla/layers/Compositor.h"
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/GfxMessageUtils.h"
-#include "mozilla/gfx/2D.h"
 #include "gfxWindowsPlatform.h"
 #include "d3d9.h"
 #include <vector>
 #include "DeviceManagerD3D9.h"
 
 namespace mozilla {
 namespace gfxs {
 class DrawTarget;
@@ -170,109 +169,135 @@ protected:
   bool mIsTiled;
   bool mIterating;
 };
 
 /**
  * Needs a D3D9 context on the client side.
  * The corresponding TextureHost is TextureHostD3D9.
  */
-class D3D9TextureData : public TextureData
+class TextureClientD3D9 : public TextureClient
 {
 public:
-  ~D3D9TextureData();
+  TextureClientD3D9(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
+                         TextureFlags aFlags);
 
-  virtual bool SupportsMoz2D() const override { return true; }
+  virtual ~TextureClientD3D9();
 
-  virtual bool HasInternalBuffer() const override { return true; }
+  // TextureClient
 
-  virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
+  virtual bool IsAllocated() const override { return !!mTexture; }
 
-  virtual bool Lock(OpenMode aMode, FenceHandle*) override;
+  virtual bool Lock(OpenMode aOpenMode) override;
 
   virtual void Unlock() override;
 
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
+  virtual bool IsLocked() const override { return mIsLocked; }
 
-  virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
+
+  virtual gfx::IntSize GetSize() const { return mSize; }
 
-  virtual gfx::IntSize GetSize() const override { return mSize; }
+  virtual gfx::SurfaceFormat GetFormat() const { return mFormat; }
 
-  virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
+  virtual bool CanExposeDrawTarget() const override { return true; }
+
+  virtual gfx::DrawTarget* BorrowDrawTarget() override;
 
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags,
-                TextureAllocationFlags aAllocFlags) const override;
+  virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
+
+  virtual bool AllocateForSurface(gfx::IntSize aSize,
+                                  TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
 
-  static D3D9TextureData*
-  Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
-
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) {}
+  virtual bool HasInternalBuffer() const override { return true; }
 
-protected:
-  D3D9TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                  IDirect3DTexture9* aTexture);
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
+                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
+private:
   RefPtr<IDirect3DTexture9> mTexture;
   RefPtr<IDirect3DSurface9> mD3D9Surface;
+  RefPtr<gfx::DrawTarget> mDrawTarget;
   gfx::IntSize mSize;
   gfx::SurfaceFormat mFormat;
+  bool mIsLocked;
   bool mNeedsClear;
   bool mNeedsClearWhite;
   bool mLockRect;
 };
 
 /**
  * Wraps a D3D9 texture, shared with the compositor though DXGI.
  * At the moment it is only used with D3D11 compositing, and the corresponding
  * TextureHost is DXGITextureHostD3D11.
  */
-class DXGID3D9TextureData : public TextureData
+class SharedTextureClientD3D9 : public TextureClient
 {
 public:
-  static DXGID3D9TextureData*
-  Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureFlags aFlags, IDirect3DDevice9* aDevice);
+  SharedTextureClientD3D9(ISurfaceAllocator* aAllocator,
+                          gfx::SurfaceFormat aFormat,
+                          TextureFlags aFlags);
+
+  virtual ~SharedTextureClientD3D9();
 
-  ~DXGID3D9TextureData();
+  // Creates a TextureClient and init width.
+  static already_AddRefed<SharedTextureClientD3D9>
+  Create(ISurfaceAllocator* aAllocator,
+         gfx::SurfaceFormat aFormat,
+         TextureFlags aFlags,
+         IDirect3DDevice9* aDevice,
+         const gfx::IntSize& aSize);
 
-  virtual gfx::IntSize GetSize() const { return gfx::IntSize(mDesc.Width, mDesc.Height); }
+  // TextureClient
+
+  virtual bool IsAllocated() const override { return !!mTexture; }
 
   virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
 
-  virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
+  virtual bool Lock(OpenMode aOpenMode) override;
+
+  virtual void Unlock() override;
 
-  virtual void Unlock() override {}
+  virtual bool IsLocked() const override { return mIsLocked; }
+
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
 
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
+  virtual gfx::IntSize GetSize() const
+  {
+    return gfx::IntSize(mDesc.Width, mDesc.Height);
+  }
 
-  virtual bool HasInternalBuffer() const override { return false; }
+  virtual bool HasInternalBuffer() const override { return true; }
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) {}
+  // This TextureClient should not be used in a context where we use CreateSimilar
+  // (ex. component alpha) because the underlying texture data is always created by
+  // an external producer.
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags, TextureAllocationFlags) const override { return nullptr; }
 
   IDirect3DDevice9* GetD3D9Device() { return mDevice; }
   IDirect3DTexture9* GetD3D9Texture() { return mTexture; }
   HANDLE GetShareHandle() const { return mHandle; }
   already_AddRefed<IDirect3DSurface9> GetD3D9Surface() const;
 
   const D3DSURFACE_DESC& GetDesc() const
   {
     return mDesc;
   }
 
-protected:
-  DXGID3D9TextureData(gfx::SurfaceFormat aFormat,
-                      IDirect3DTexture9* aTexture, HANDLE aHandle,
-                      IDirect3DDevice9* aDevice);
+private:
+  virtual void FinalizeOnIPDLThread() override;
 
   RefPtr<IDirect3DDevice9> mDevice;
   RefPtr<IDirect3DTexture9> mTexture;
   gfx::SurfaceFormat mFormat;
   HANDLE mHandle;
   D3DSURFACE_DESC mDesc;
+  bool mIsLocked;
 };
 
 class TextureHostD3D9 : public TextureHost
 {
 public:
   TextureHostD3D9(TextureFlags aFlags,
                   const SurfaceDescriptorD3D9& aDescriptor);
 
--- a/gfx/layers/ipc/CompositableForwarder.h
+++ b/gfx/layers/ipc/CompositableForwarder.h
@@ -103,16 +103,22 @@ public:
    * It is used when the TextureClient recycled.
    * Only ImageBridge implements it.
    */
   virtual void RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker,
                                                   CompositableClient* aCompositable,
                                                   TextureClient* aTexture) {}
 
   /**
+   * Tell the compositor side to delete the TextureHost corresponding to the
+   * TextureClient passed in parameter.
+   */
+  virtual void RemoveTexture(TextureClient* aTexture) = 0;
+
+  /**
    * Holds a reference to a TextureClient until after the next
    * compositor transaction, and then drops it.
    */
   virtual void HoldUntilTransaction(TextureClient* aClient)
   {
     if (aClient) {
       mTexturesToRemove.AppendElement(aClient);
     }
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -193,17 +193,17 @@ static void ImageBridgeShutdownStep1(Ree
     for (int i = compositables.Length() - 1; i >= 0; --i) {
       CompositableClient::FromIPDLActor(compositables[i])->Destroy();
     }
     InfallibleTArray<PTextureChild*> textures;
     sImageBridgeChildSingleton->ManagedPTextureChild(textures);
     for (int i = textures.Length() - 1; i >= 0; --i) {
       RefPtr<TextureClient> client = TextureClient::AsTextureClient(textures[i]);
       if (client) {
-        client->Destroy();
+        client->ForceRemove();
       }
     }
     sImageBridgeChildSingleton->SendWillStop();
     sImageBridgeChildSingleton->MarkShutDown();
     // From now on, no message can be sent through the image bridge from the
     // client side except the final Stop message.
   }
 
@@ -761,17 +761,17 @@ bool ImageBridgeChild::StartUpOnThread(T
 bool InImageBridgeChildThread()
 {
   return ImageBridgeChild::IsCreated() &&
     sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId();
 }
 
 MessageLoop * ImageBridgeChild::GetMessageLoop() const
 {
-  return sImageBridgeChildThread ? sImageBridgeChildThread->message_loop() : nullptr;
+  return sImageBridgeChildThread->message_loop();
 }
 
 void ImageBridgeChild::ConnectAsync(ImageBridgeParent* aParent)
 {
   GetMessageLoop()->PostTask(FROM_HERE, NewRunnableFunction(&ConnectImageBridge,
                                                             this, aParent));
 }
 
@@ -1125,16 +1125,48 @@ ImageBridgeChild::RemoveTextureFromCompo
                                            aAsyncTransactionTracker->GetId(),
                                            nullptr, aCompositable->GetIPDLActor(),
                                            nullptr, aTexture->GetIPDLActor()));
   // Hold AsyncTransactionTracker until receving reply
   CompositableClient::HoldUntilComplete(aCompositable->GetIPDLActor(),
                                         aAsyncTransactionTracker);
 }
 
+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()) {
+    MOZ_ASSERT(!mShuttingDown);
+    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();
+  }
+}
+
 bool ImageBridgeChild::IsSameProcess() const
 {
   return OtherPid() == base::GetCurrentProcId();
 }
 
 void ImageBridgeChild::SendPendingAsyncMessges()
 {
 }
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -254,16 +254,18 @@ public:
 
   virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable,
                                              TextureClient* aTexture) override;
 
   virtual void RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker,
                                                   CompositableClient* aCompositable,
                                                   TextureClient* aTexture) override;
 
+  virtual void RemoveTexture(TextureClient* aTexture) override;
+
   virtual void UseTiledLayerBuffer(CompositableClient* aCompositable,
                                    const SurfaceDescriptorTiles& aTileLayerDescriptor) override
   {
     NS_RUNTIMEABORT("should not be called");
   }
 
   virtual void UpdateTextureRegion(CompositableClient* aCompositable,
                                    const ThebesBufferData& aThebesBufferData,
--- a/gfx/layers/ipc/LayerTransactionChild.cpp
+++ b/gfx/layers/ipc/LayerTransactionChild.cpp
@@ -35,17 +35,17 @@ LayerTransactionChild::Destroy()
   mDestroyed = true;
   MOZ_ASSERT(0 == ManagedPLayerChild().Count(),
              "layers should have been cleaned up by now");
 
   const ManagedContainer<PTextureChild>& textures = ManagedPTextureChild();
   for (auto iter = textures.ConstIter(); !iter.Done(); iter.Next()) {
     TextureClient* texture = TextureClient::AsTextureClient(iter.Get()->GetKey());
     if (texture) {
-      texture->Destroy();
+      texture->ForceRemove();
     }
   }
 
   SendShutdown();
 }
 
 
 PLayerChild*
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -465,16 +465,48 @@ ShadowLayerForwarder::RemoveTextureFromC
 }
 
 bool
 ShadowLayerForwarder::InWorkerThread()
 {
   return MessageLoop::current() && (GetMessageLoop()->id() == MessageLoop::current()->id());
 }
 
+static void RemoveTextureWorker(TextureClient* aTexture, ReentrantMonitor* aBarrier, bool* aDone)
+{
+  aTexture->ForceRemove();
+
+  ReentrantMonitorAutoEnter autoMon(*aBarrier);
+  *aDone = true;
+  aBarrier->NotifyAll();
+}
+
+void
+ShadowLayerForwarder::RemoveTexture(TextureClient* aTexture)
+{
+  MOZ_ASSERT(aTexture);
+  if (InWorkerThread()) {
+    aTexture->ForceRemove();
+    return;
+  }
+
+  ReentrantMonitor barrier("ShadowLayerForwarder::RemoveTexture Lock");
+  ReentrantMonitorAutoEnter autoMon(barrier);
+  bool done = false;
+
+  GetMessageLoop()->PostTask(
+    FROM_HERE,
+    NewRunnableFunction(&RemoveTextureWorker, aTexture, &barrier, &done));
+
+  // Wait until the TextureClient has been ForceRemoved on the worker thread
+  while (!done) {
+    barrier.Wait();
+  }
+}
+
 void
 ShadowLayerForwarder::StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration>&
                                                       aConfigurations)
 {
   // Cache new plugin widget configs here until we call update, at which
   // point this data will get shipped over to chrome.
   mPluginWindowData.Clear();
   for (uint32_t idx = 0; idx < aConfigurations.Length(); idx++) {
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -216,16 +216,18 @@ public:
 
   virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable,
                                              TextureClient* aTexture) override;
 
   virtual void RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker,
                                                   CompositableClient* aCompositable,
                                                   TextureClient* aTexture) override;
 
+  virtual void RemoveTexture(TextureClient* aTexture) override;
+
   /**
    * Communicate to the compositor that aRegion in the texture identified by aLayer
    * and aIdentifier has been updated to aThebesBuffer.
    */
   virtual void UpdateTextureRegion(CompositableClient* aCompositable,
                                    const ThebesBufferData& aThebesBufferData,
                                    const nsIntRegion& aUpdatedRegion) override;
 
--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
@@ -8,18 +8,17 @@
 #include <stdio.h>                      // for printf
 #include "gfx2DGlue.h"                  // for Moz2D transition helpers
 #include "ISurfaceAllocator.h"          // for ISurfaceAllocator, etc
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat::SurfaceFormat::YUV
 #include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
 #include "mozilla/layers/ImageClient.h"  // for ImageClient
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
-#include "mozilla/layers/TextureClient.h"
-#include "mozilla/layers/BufferTexture.h"
+#include "mozilla/layers/TextureClient.h"  // for BufferTextureClient, etc
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
 #include "mozilla/layers/ImageBridgeChild.h"  // for ImageBridgeChild
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsISupportsImpl.h"            // for Image::AddRef
 #include "mozilla/ipc/Shmem.h"
 
 namespace mozilla {
 namespace layers {
@@ -61,19 +60,17 @@ TextureClient*
 SharedPlanarYCbCrImage::GetTextureClient(CompositableClient* aClient)
 {
   return mTextureClient.get();
 }
 
 uint8_t*
 SharedPlanarYCbCrImage::GetBuffer()
 {
-  // This should never be used
-  MOZ_ASSERT(false);
-  return nullptr;
+  return mTextureClient ? mTextureClient->GetBuffer() : nullptr;
 }
 
 already_AddRefed<gfx::SourceSurface>
 SharedPlanarYCbCrImage::GetAsSourceSurface()
 {
   if (!mTextureClient) {
     NS_WARNING("Can't get as surface");
     return nullptr;
@@ -87,23 +84,25 @@ SharedPlanarYCbCrImage::SetData(const Pl
   // If mTextureClient has not already been allocated (through Allocate(aData))
   // allocate it. This code path is slower than the one used when Allocate has
   // been called since it will trigger a full copy.
   PlanarYCbCrData data = aData;
   if (!mTextureClient && !Allocate(data)) {
     return false;
   }
 
+  MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr());
+
   TextureClientAutoLock autoLock(mTextureClient, OpenMode::OPEN_WRITE_ONLY);
   if (!autoLock.Succeeded()) {
     MOZ_ASSERT(false, "Failed to lock the texture.");
     return false;
   }
 
-  if (!UpdateYCbCrTextureClient(mTextureClient, aData)) {
+  if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) {
     MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
     return false;
   }
   mTextureClient->MarkImmutable();
   return true;
 }
 
 // needs to be overriden because the parent class sets mBuffer which we
@@ -124,28 +123,18 @@ SharedPlanarYCbCrImage::AllocateAndGetNe
   // get new buffer _without_ setting mBuffer.
   if (!mTextureClient) {
     return nullptr;
   }
 
   // update buffer size
   mBufferSize = size;
 
-  MappedYCbCrTextureData mapped;
-  if (mTextureClient->BorrowMappedYCbCrData(mapped)) {
-    // The caller expects a pointer to the beginning of the writable part of the
-    // buffer (after the metadata) which is where the y channel starts by default.
-    // The caller might choose to write the y channel at a different offset and
-    // if it does so, it will also update the metadata.
-    // Anyway, we return the y channel here but the intent is to obtain the start of
-    // the writable part of the buffer.
-    return mapped.y.data;
-  } else {
-    MOZ_CRASH();
-  }
+  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
+  return serializer.GetData();
 }
 
 bool
 SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
 {
   MOZ_ASSERT(mTextureClient, "This Image should have already allocated data");
   if (!mTextureClient) {
     return false;
@@ -153,21 +142,17 @@ SharedPlanarYCbCrImage::SetDataNoCopy(co
   mData = aData;
   mSize = aData.mPicSize;
   /* SetDataNoCopy is used to update YUV plane offsets without (re)allocating
    * memory previously allocated with AllocateAndGetNewBuffer().
    * serializer.GetData() returns the address of the memory previously allocated
    * with AllocateAndGetNewBuffer(), that we subtract from the Y, Cb, Cr
    * channels to compute 0-based offsets to pass to InitializeBufferInfo.
    */
-  MappedYCbCrTextureData mapped;
-  if(!mTextureClient->BorrowMappedYCbCrData(mapped)) {
-    MOZ_CRASH();
-  }
-  YCbCrImageDataSerializer serializer(mapped.metadata, mBufferSize);
+  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   uint8_t *base = serializer.GetData();
   uint32_t yOffset = aData.mYChannel - base;
   uint32_t cbOffset = aData.mCbChannel - base;
   uint32_t crOffset = aData.mCrChannel - base;
   serializer.InitializeBufferInfo(yOffset,
                                   cbOffset,
                                   crOffset,
                                   aData.mYStride,
@@ -193,28 +178,25 @@ SharedPlanarYCbCrImage::Allocate(PlanarY
                                                  aData.mYSize, aData.mCbCrSize,
                                                  aData.mStereoMode,
                                                  mCompositable->GetTextureFlags());
   if (!mTextureClient) {
     NS_WARNING("SharedPlanarYCbCrImage::Allocate failed.");
     return false;
   }
 
-  MappedYCbCrTextureData mapped;
-  // The locking here is sort of a lie. The SharedPlanarYCbCrImage just pulls
-  // pointers out of the TextureClient and keeps them around, which works only
-  // because the underlyin BufferTextureData is always mapped in memory even outside
-  // of the lock/unlock interval. That's sad and new code should follow this example.
-  if (!mTextureClient->Lock(OpenMode::OPEN_READ) || !mTextureClient->BorrowMappedYCbCrData(mapped)) {
-    MOZ_CRASH();
-  }
+  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
+  serializer.InitializeBufferInfo(aData.mYSize,
+                                  aData.mCbCrSize,
+                                  aData.mStereoMode);
+  MOZ_ASSERT(serializer.IsValid());
 
-  aData.mYChannel = mapped.y.data;
-  aData.mCbChannel = mapped.cb.data;
-  aData.mCrChannel = mapped.cr.data;
+  aData.mYChannel = serializer.GetYData();
+  aData.mCbChannel = serializer.GetCbData();
+  aData.mCrChannel = serializer.GetCrData();
 
   // copy some of aData's values in mData (most of them)
   mData.mYChannel = aData.mYChannel;
   mData.mCbChannel = aData.mCbChannel;
   mData.mCrChannel = aData.mCrChannel;
   mData.mYSize = aData.mYSize;
   mData.mCbCrSize = aData.mCbCrSize;
   mData.mPicX = aData.mPicX;
@@ -231,15 +213,13 @@ SharedPlanarYCbCrImage::Allocate(PlanarY
 
   // do not set mBuffer like in PlanarYCbCrImage because the later
   // will try to manage this memory without knowing it belongs to a
   // shmem.
   mBufferSize = YCbCrImageDataSerializer::ComputeMinBufferSize(mData.mYSize,
                                                                mData.mCbCrSize);
   mSize = mData.mPicSize;
 
-  mTextureClient->Unlock();
-
   return mBufferSize > 0;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.h
+++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.h
@@ -13,16 +13,17 @@
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR
 
 #ifndef MOZILLA_LAYERS_SHAREDPLANARYCBCRIMAGE_H
 #define MOZILLA_LAYERS_SHAREDPLANARYCBCRIMAGE_H
 
 namespace mozilla {
 namespace layers {
 
+class BufferTextureClient;
 class ImageClient;
 class TextureClient;
 
 class SharedPlanarYCbCrImage : public PlanarYCbCrImage
 {
 public:
   explicit SharedPlanarYCbCrImage(ImageClient* aCompositable);
 
@@ -45,16 +46,16 @@ public:
   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
 
 private:
-  RefPtr<TextureClient> mTextureClient;
+  RefPtr<BufferTextureClient> mTextureClient;
   RefPtr<ImageClient> mCompositable;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/ipc/SharedRGBImage.cpp
+++ b/gfx/layers/ipc/SharedRGBImage.cpp
@@ -3,19 +3,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SharedRGBImage.h"
 #include "ImageTypes.h"                 // for ImageFormat::SHARED_RGB, etc
 #include "Shmem.h"                      // for Shmem
 #include "gfx2DGlue.h"                  // for ImageFormatToSurfaceFormat, etc
 #include "gfxPlatform.h"                // for gfxPlatform, gfxImageFormat
 #include "mozilla/gfx/Point.h"          // for IntSIze
-#include "mozilla/layers/BufferTexture.h"
 #include "mozilla/layers/ISurfaceAllocator.h"  // for ISurfaceAllocator, etc
 #include "mozilla/layers/ImageClient.h"  // for ImageClient
+#include "mozilla/layers/ImageDataSerializer.h"  // for ImageDataSerializer
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "mozilla/layers/TextureClient.h"  // for BufferTextureClient, etc
 #include "mozilla/layers/ImageBridgeChild.h"  // for ImageBridgeChild
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Image::AddRef, etc
 #include "nsRect.h"                     // for mozilla::gfx::IntRect
@@ -82,29 +82,37 @@ SharedRGBImage::Allocate(gfx::IntSize aS
                                                             gfx::BackendType::NONE,
                                                             TextureFlags::DEFAULT);
   return !!mTextureClient;
 }
 
 uint8_t*
 SharedRGBImage::GetBuffer()
 {
-  MappedTextureData mapped;
-  if (mTextureClient && mTextureClient->BorrowMappedData(mapped)) {
-    return mapped.data;
+  if (!mTextureClient) {
+    return nullptr;
   }
-  return 0;
+
+  ImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
+  return serializer.GetData();
 }
 
 gfx::IntSize
 SharedRGBImage::GetSize()
 {
   return mSize;
 }
 
+size_t
+SharedRGBImage::GetBufferSize()
+{
+  return mTextureClient ? mTextureClient->GetBufferSize()
+                        : 0;
+}
+
 TextureClient*
 SharedRGBImage::GetTextureClient(CompositableClient* aClient)
 {
   return mTextureClient.get();
 }
 
 already_AddRefed<gfx::SourceSurface>
 SharedRGBImage::GetAsSourceSurface()
--- a/gfx/layers/ipc/SharedRGBImage.h
+++ b/gfx/layers/ipc/SharedRGBImage.h
@@ -13,16 +13,17 @@
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat
 #include "nsCOMPtr.h"                   // for already_AddRefed
 
 namespace mozilla {
 namespace layers {
 
+class BufferTextureClient;
 class ImageClient;
 class TextureClient;
 
 already_AddRefed<Image> CreateSharedRGBImage(ImageContainer* aImageContainer,
                                              gfx::IntSize aSize,
                                              gfxImageFormat aImageFormat);
 
 /**
@@ -39,21 +40,23 @@ protected:
 
 public:
   virtual TextureClient* GetTextureClient(CompositableClient* aClient) override;
 
   virtual uint8_t* GetBuffer() override;
 
   gfx::IntSize GetSize() override;
 
+  size_t GetBufferSize();
+
   already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
 
   bool Allocate(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
 private:
   gfx::IntSize mSize;
   RefPtr<ImageClient> mCompositable;
-  RefPtr<TextureClient> mTextureClient;
+  RefPtr<BufferTextureClient> mTextureClient;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -111,17 +111,16 @@ EXPORTS.mozilla.layers += [
     'apz/util/InputAPZContext.h',
     'AsyncCanvasRenderer.h',
     'AtomicRefCountedWithFinalize.h',
     'AxisPhysicsModel.h',
     'AxisPhysicsMSDModel.h',
     'basic/BasicCompositor.h',
     'basic/MacIOSurfaceTextureHostBasic.h',
     'basic/TextureHostBasic.h',
-    'BufferTexture.h',
     'client/CanvasClient.h',
     'client/CompositableClient.h',
     'client/ContentClient.h',
     'client/ImageClient.h',
     'client/SingleTiledContentClient.h',
     'client/TextureClient.h',
     'client/TextureClientPool.h',
     'client/TextureClientRecycleAllocator.h',
@@ -266,17 +265,16 @@ UNIFIED_SOURCES += [
     'basic/BasicColorLayer.cpp',
     'basic/BasicCompositor.cpp',
     'basic/BasicContainerLayer.cpp',
     'basic/BasicImages.cpp',
     'basic/BasicLayerManager.cpp',
     'basic/BasicLayersImpl.cpp',
     'basic/BasicPaintedLayer.cpp',
     'basic/TextureHostBasic.cpp',
-    'BufferTexture.cpp',
     'BufferUnrotate.cpp',
     'client/CanvasClient.cpp',
     'client/ClientCanvasLayer.cpp',
     'client/ClientColorLayer.cpp',
     'client/ClientContainerLayer.cpp',
     'client/ClientImageLayer.cpp',
     'client/ClientLayerManager.cpp',
     'client/ClientPaintedLayer.cpp',
--- a/gfx/layers/opengl/GrallocTextureClient.cpp
+++ b/gfx/layers/opengl/GrallocTextureClient.cpp
@@ -19,398 +19,390 @@
 #endif
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 using namespace android;
 
-static bool
-DisableGralloc(SurfaceFormat aFormat, const gfx::IntSize& aSizeHint)
+GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
+                                                 gfx::SurfaceFormat aFormat,
+                                                 gfx::BackendType aMoz2dBackend,
+                                                 TextureFlags aFlags)
+: BufferTextureClient(aAllocator, aFormat, aMoz2dBackend, aFlags)
+, mGrallocHandle(null_t())
+, mMappedBuffer(nullptr)
+, mMediaBuffer(nullptr)
+, mIsOpaque(gfx::IsOpaque(aFormat))
+{
+  MOZ_COUNT_CTOR(GrallocTextureClientOGL);
+}
+
+GrallocTextureClientOGL::~GrallocTextureClientOGL()
+{
+  MOZ_COUNT_DTOR(GrallocTextureClientOGL);
+  ISurfaceAllocator* allocator = GetAllocator();
+  if (ShouldDeallocateInDestructor()) {
+    allocator->DeallocGrallocBuffer(&mGrallocHandle);
+  } else {
+    allocator->DropGrallocBuffer(&mGrallocHandle);
+  }
+}
+
+already_AddRefed<TextureClient>
+GrallocTextureClientOGL::CreateSimilar(TextureFlags aFlags,
+                                       TextureAllocationFlags aAllocFlags) const
+{
+  RefPtr<TextureClient> tex = new GrallocTextureClientOGL(
+    mAllocator, mFormat, mBackend, mFlags | aFlags
+  );
+
+  if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
+    return nullptr;
+  }
+
+  return tex.forget();
+}
+
+bool
+GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
-  if (gfxPrefs::DisableGralloc()) {
-    return true;
+  MOZ_ASSERT(IsValid());
+  if (!IsAllocated()) {
+    return false;
+  }
+
+  aOutDescriptor = NewSurfaceDescriptorGralloc(mGrallocHandle, mIsOpaque);
+  return true;
+}
+
+void
+GrallocTextureClientOGL::SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter)
+{
+  mRemoveFromCompositableWaiter = aWaiter;
+}
+
+void
+GrallocTextureClientOGL::WaitForBufferOwnership(bool aWaitReleaseFence)
+{
+  if (mRemoveFromCompositableWaiter) {
+    mRemoveFromCompositableWaiter->WaitComplete();
+    mRemoveFromCompositableWaiter = nullptr;
+  }
+
+  if (!aWaitReleaseFence) {
+    return;
   }
-  if (aFormat == gfx::SurfaceFormat::A8) {
+
+#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
+   if (mReleaseFenceHandle.IsValid()) {
+     RefPtr<FenceHandle::FdObj> fdObj = mReleaseFenceHandle.GetAndResetFdObj();
+     android::sp<Fence> fence = new Fence(fdObj->GetAndResetFd());
+#if ANDROID_VERSION == 17
+     fence->waitForever(1000, "GrallocTextureClientOGL::Lock");
+     // 1000 is what Android uses. It is a warning timeout in ms.
+     // This timeout was removed in ANDROID_VERSION 18.
+#else
+     fence->waitForever("GrallocTextureClientOGL::Lock");
+#endif
+     mReleaseFenceHandle = FenceHandle();
+   }
+#endif
+}
+
+bool
+GrallocTextureClientOGL::Lock(OpenMode aMode)
+{
+  MOZ_ASSERT(IsValid());
+  if (!IsValid() || !IsAllocated()) {
+    return false;
+  }
+
+  if (mMappedBuffer) {
     return true;
   }
-#if ANDROID_VERSION <= 15
-  // Adreno 200 has a problem of drawing gralloc buffer width less than 64 and
-  // drawing gralloc buffer with a height 9px-16px.
-  // See Bug 983971.
-  if (aSizeHint.width < 64 || aSizeHint.height < 32) {
-    return true;
-  }
+
+#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
+  WaitForBufferOwnership(false /* aWaitReleaseFence */);
+#else
+  WaitForBufferOwnership();
 #endif
 
-  return false;
+  uint32_t usage = 0;
+  if (aMode & OpenMode::OPEN_READ) {
+    usage |= GRALLOC_USAGE_SW_READ_OFTEN;
+  }
+  if (aMode & OpenMode::OPEN_WRITE) {
+    usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
+  }
+#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
+  RefPtr<FenceHandle::FdObj> fdObj = mReleaseFenceHandle.GetAndResetFdObj();
+  int32_t rv = mGraphicBuffer->lockAsync(usage,
+                                         reinterpret_cast<void**>(&mMappedBuffer),
+                                         fdObj->GetAndResetFd());
+#else
+  int32_t rv = mGraphicBuffer->lock(usage,
+                                    reinterpret_cast<void**>(&mMappedBuffer));
+#endif
+  if (rv) {
+    mMappedBuffer = nullptr;
+    NS_WARNING("Couldn't lock graphic buffer");
+    return false;
+  }
+  return BufferTextureClient::Lock(aMode);
 }
 
-gfx::SurfaceFormat
+void
+GrallocTextureClientOGL::Unlock()
+{
+  BufferTextureClient::Unlock();
+  mDrawTarget = nullptr;
+  if (mMappedBuffer) {
+    mMappedBuffer = nullptr;
+    mGraphicBuffer->unlock();
+  }
+}
+
+uint8_t*
+GrallocTextureClientOGL::GetBuffer() const
+{
+  MOZ_ASSERT(IsValid());
+  NS_WARN_IF_FALSE(mMappedBuffer, "Trying to get a gralloc buffer without getting the lock?");
+  return mMappedBuffer;
+}
+
+static gfx::SurfaceFormat
 SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
 {
   switch (aFormat) {
   case PIXEL_FORMAT_RGBA_8888:
     return gfx::SurfaceFormat::R8G8B8A8;
   case PIXEL_FORMAT_BGRA_8888:
     return gfx::SurfaceFormat::B8G8R8A8;
   case PIXEL_FORMAT_RGBX_8888:
     return gfx::SurfaceFormat::R8G8B8X8;
   case PIXEL_FORMAT_RGB_565:
     return gfx::SurfaceFormat::R5G6B5_UINT16;
   case HAL_PIXEL_FORMAT_YV12:
     return gfx::SurfaceFormat::YUV;
   default:
-    return gfx::SurfaceFormat::UNKNOWN;
-  }
-}
-
-bool
-IsGrallocRBSwapped(gfx::SurfaceFormat aFormat) {
-  switch (aFormat) {
-  case gfx::SurfaceFormat::B8G8R8A8:
-  case gfx::SurfaceFormat::B8G8R8X8:
-    return true;
-  default:
-    return false;
+    MOZ_CRASH("Unknown gralloc pixel format");
   }
-}
-
-uint32_t GetAndroidFormat(gfx::SurfaceFormat aFormat)
-{
-  switch (aFormat) {
-  case gfx::SurfaceFormat::R8G8B8A8:
-  case gfx::SurfaceFormat::B8G8R8A8:
-    return android::PIXEL_FORMAT_RGBA_8888;
-  case gfx::SurfaceFormat::R8G8B8X8:
-  case gfx::SurfaceFormat::B8G8R8X8:
-    return android::PIXEL_FORMAT_RGBX_8888;
-  case gfx::SurfaceFormat::R5G6B5_UINT16:
-    return android::PIXEL_FORMAT_RGB_565;
-  case gfx::SurfaceFormat::YUV:
-    return HAL_PIXEL_FORMAT_YV12;
-  case gfx::SurfaceFormat::A8:
-    NS_WARNING("gralloc does not support SurfaceFormat::A8");
-  default:
-    NS_WARNING("Unsupported surface format");
-    return android::PIXEL_FORMAT_UNKNOWN;
-  }
+  return gfx::SurfaceFormat::R8G8B8A8;
 }
 
-GrallocTextureData::GrallocTextureData(MaybeMagicGrallocBufferHandle aGrallocHandle,
-                                       gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                       gfx::BackendType aMoz2DBackend)
-: mSize(aSize)
-, mFormat(aFormat)
-, mMoz2DBackend(aMoz2DBackend)
-, mGrallocHandle(aGrallocHandle)
-, mMappedBuffer(nullptr)
-, mMediaBuffer(nullptr)
+gfx::DrawTarget*
+GrallocTextureClientOGL::BorrowDrawTarget()
 {
-  mGraphicBuffer = GetGraphicBufferFrom(aGrallocHandle);
-  MOZ_COUNT_CTOR(GrallocTextureData);
-}
+  MOZ_ASSERT(IsValid());
+  MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::BorrowDrawTarget without locking :(");
 
-GrallocTextureData::~GrallocTextureData()
-{
-  MOZ_COUNT_DTOR(GrallocTextureData);
-}
-
-void
-GrallocTextureData::Deallocate(ISurfaceAllocator* aAllocator)
-{
-  MOZ_ASSERT(aAllocator);
-  if (aAllocator) {
-    aAllocator->DeallocGrallocBuffer(&mGrallocHandle);
+  if (!IsValid() || !IsAllocated() || !mMappedBuffer) {
+    return nullptr;
   }
 
-  mGrallocHandle = null_t();
-  mGraphicBuffer = nullptr;
-}
-
-void
-GrallocTextureData::Forget(ISurfaceAllocator* aAllocator)
-{
-  MOZ_ASSERT(aAllocator);
-  if (aAllocator) {
-    aAllocator->DropGrallocBuffer(&mGrallocHandle);
+  if (mDrawTarget) {
+    return mDrawTarget;
   }
 
-  mGrallocHandle = null_t();
-  mGraphicBuffer = nullptr;
-}
-
-bool
-GrallocTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
-{
-  aOutDescriptor = NewSurfaceDescriptorGralloc(mGrallocHandle, gfx::IsOpaque(mFormat));
-  return true;
+  gfx::SurfaceFormat format = SurfaceFormatForPixelFormat(mGraphicBuffer->getPixelFormat());
+  long pixelStride = mGraphicBuffer->getStride();
+  long byteStride = pixelStride * BytesPerPixel(format);
+  mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForData(GetBuffer(),
+                                                                    mSize,
+                                                                    byteStride,
+                                                                    mFormat);
+  return mDrawTarget;
 }
 
 void
-GrallocTextureData::WaitForFence(FenceHandle* aFence)
-{
-#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION < 21 && ANDROID_VERSION >= 17
-   if (aFence && aFence->IsValid()) {
-     RefPtr<FenceHandle::FdObj> fdObj = aFence->GetAndResetFdObj();
-     android::sp<Fence> fence = new Fence(fdObj->GetAndResetFd());
-#if ANDROID_VERSION == 17
-     fence->waitForever(1000, "GrallocTextureData::Lock");
-     // 1000 is what Android uses. It is a warning timeout in ms.
-     // This timeout was removed in ANDROID_VERSION 18.
-#else
-     fence->waitForever("GrallocTextureData::Lock");
-#endif
-   }
-#endif
-}
-
-bool
-GrallocTextureData::Lock(OpenMode aMode, FenceHandle* aReleaseFence)
+GrallocTextureClientOGL::UpdateFromSurface(gfx::SourceSurface* aSurface)
 {
-  MOZ_ASSERT(!mMappedBuffer);
-
-  uint32_t usage = 0;
-  if (aMode & OpenMode::OPEN_READ) {
-    usage |= GRALLOC_USAGE_SW_READ_OFTEN;
-  }
-  if (aMode & OpenMode::OPEN_WRITE) {
-    usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
-  }
-
-  void** mappedBufferPtr = reinterpret_cast<void**>(&mMappedBuffer);
-
-  int32_t rv = 0;
-#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
-  if (aReleaseFence) {
-    RefPtr<FenceHandle::FdObj> fdObj = aReleaseFence->GetAndResetFdObj();
-    rv = mGraphicBuffer->lockAsync(usage, mappedBufferPtr,
-                                   fdObj->GetAndResetFd());
-  } else {
-    rv = mGraphicBuffer->lock(usage, mappedBufferPtr);
-  }
-#else
-  // older versions of android don't have lockAsync
-  WaitForFence(aReleaseFence);
-  rv = mGraphicBuffer->lock(usage, mappedBufferPtr);
-#endif
-
-  if (rv) {
-    mMappedBuffer = nullptr;
-    NS_WARNING("Couldn't lock graphic buffer");
-    return false;
-  }
-
-  return true;
-}
-
-void
-GrallocTextureData::Unlock()
-{
-  MOZ_ASSERT(mMappedBuffer);
-  mMappedBuffer = nullptr;
-  mGraphicBuffer->unlock();
-}
-
-already_AddRefed<gfx::DrawTarget>
-GrallocTextureData::BorrowDrawTarget()
-{
-  MOZ_ASSERT(mMappedBuffer);
-  if (!mMappedBuffer) {
-    return nullptr;
-  }
-  long byteStride = mGraphicBuffer->getStride() * BytesPerPixel(mFormat);
-  return gfxPlatform::GetPlatform()->CreateDrawTargetForData(mMappedBuffer, mSize,
-                                                             byteStride, mFormat);
-}
-
-bool
-GrallocTextureData::BorrowMappedData(MappedTextureData& aMap)
-{
-  if (mFormat == gfx::SurfaceFormat::YUV || !mMappedBuffer) {
-    return false;
-  }
-
-  aMap.data = mMappedBuffer;
-  aMap.size = mSize;
-  aMap.stride = mGraphicBuffer->getStride() * BytesPerPixel(mFormat);
-  aMap.format = mFormat;
-
-  return true;
-}
-
-bool
-GrallocTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
-{
+  MOZ_ASSERT(IsValid());
   MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::BorrowDrawTarget without locking :(");
 
-  if (!mMappedBuffer) {
-    return false;
+  if (!IsValid() || !IsAllocated() || !mMappedBuffer) {
+    return;
   }
 
   RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
 
   if (!srcSurf) {
     gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
-    return false;
+    return;
   }
 
   gfx::SurfaceFormat format = SurfaceFormatForPixelFormat(mGraphicBuffer->getPixelFormat());
   if (mSize != srcSurf->GetSize() || mFormat != srcSurf->GetFormat()) {
     gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format! This: " << mSize << " " << format << " Other: " << srcSurf->GetSize() << " " << srcSurf->GetFormat();
-    return false;
+    return;
   }
 
   long pixelStride = mGraphicBuffer->getStride();
   long byteStride = pixelStride * BytesPerPixel(format);
 
   DataSourceSurface::MappedSurface sourceMap;
 
   if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
     gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
-    return false;
+    return;
   }
 
+  uint8_t* buffer = GetBuffer();
+
   for (int y = 0; y < srcSurf->GetSize().height; y++) {
-    memcpy(mMappedBuffer + byteStride * y,
+    memcpy(buffer + byteStride * y,
            sourceMap.mData + sourceMap.mStride * y,
            srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
   }
 
   srcSurf->Unmap();
+}
 
-  return true;
+bool
+GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize,
+                                            TextureAllocationFlags)
+{
+  MOZ_ASSERT(IsValid());
+
+  uint32_t format;
+  uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
+                   android::GraphicBuffer::USAGE_SW_WRITE_OFTEN |
+                   android::GraphicBuffer::USAGE_HW_TEXTURE;
+
+  switch (mFormat) {
+  case gfx::SurfaceFormat::R8G8B8A8:
+    format = android::PIXEL_FORMAT_RGBA_8888;
+    break;
+  case gfx::SurfaceFormat::B8G8R8A8:
+     format = android::PIXEL_FORMAT_RGBA_8888;
+     mFlags |= TextureFlags::RB_SWAPPED;
+    break;
+  case gfx::SurfaceFormat::R8G8B8X8:
+    format = android::PIXEL_FORMAT_RGBX_8888;
+    break;
+  case gfx::SurfaceFormat::B8G8R8X8:
+     format = android::PIXEL_FORMAT_RGBX_8888;
+     mFlags |= TextureFlags::RB_SWAPPED;
+    break;
+  case gfx::SurfaceFormat::R5G6B5_UINT16:
+    format = android::PIXEL_FORMAT_RGB_565;
+    break;
+  case gfx::SurfaceFormat::YUV:
+    format = HAL_PIXEL_FORMAT_YV12;
+    break;
+  case gfx::SurfaceFormat::A8:
+    NS_WARNING("gralloc does not support gfx::SurfaceFormat::A8");
+    return false;
+  default:
+    NS_WARNING("Unsupported surface format");
+    return false;
+  }
+
+  return AllocateGralloc(aSize, format, usage);
 }
 
-// static
-GrallocTextureData*
-GrallocTextureData::Create(gfx::IntSize aSize, AndroidFormat aAndroidFormat,
-                           gfx::BackendType aMoz2dBackend, uint32_t aUsage,
-                           ISurfaceAllocator* aAllocator)
+bool
+GrallocTextureClientOGL::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize, StereoMode aStereoMode)
+{
+  MOZ_ASSERT(IsValid());
+  return AllocateGralloc(aYSize,
+                         HAL_PIXEL_FORMAT_YV12,
+                         android::GraphicBuffer::USAGE_SW_READ_OFTEN);
+}
+
+bool
+GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize)
 {
-  if (!aAllocator) {
-    return nullptr;
-  }
-  int32_t maxSize = aAllocator->GetMaxTextureSize();
-  if (aSize.width > maxSize || aSize.height > maxSize) {
-    return nullptr;
-  }
-  gfx::SurfaceFormat format;
-  switch (aAndroidFormat) {
-  case android::PIXEL_FORMAT_RGBA_8888:
-    format = gfx::SurfaceFormat::B8G8R8A8;
+  MOZ_ASSERT(IsValid());
+
+  uint32_t format;
+  uint32_t usage = android::GraphicBuffer::USAGE_HW_RENDER |
+                   android::GraphicBuffer::USAGE_HW_TEXTURE;
+
+  switch (mFormat) {
+  case gfx::SurfaceFormat::R8G8B8A8:
+  case gfx::SurfaceFormat::B8G8R8A8:
+    format = android::PIXEL_FORMAT_RGBA_8888;
     break;
-  case android::PIXEL_FORMAT_BGRA_8888:
-    format = gfx::SurfaceFormat::B8G8R8A8;
-    break;
-  case android::PIXEL_FORMAT_RGBX_8888:
-    format = gfx::SurfaceFormat::B8G8R8X8;
+  case gfx::SurfaceFormat::R8G8B8X8:
+  case gfx::SurfaceFormat::B8G8R8X8:
+    // there is no android BGRX format?
+    format = android::PIXEL_FORMAT_RGBX_8888;
     break;
-  case android::PIXEL_FORMAT_RGB_565:
-    format = gfx::SurfaceFormat::R5G6B5_UINT16;
-    break;
-  case HAL_PIXEL_FORMAT_YV12:
-    format = gfx::SurfaceFormat::YUV;
+  case gfx::SurfaceFormat::R5G6B5_UINT16:
+    format = android::PIXEL_FORMAT_RGB_565;
     break;
   default:
-    format = gfx::SurfaceFormat::UNKNOWN;
+    NS_WARNING("Unsupported surface format");
+    return false;
   }
 
-  if (DisableGralloc(format, aSize)) {
-    return nullptr;
-  }
+  return AllocateGralloc(aSize, format, usage);
+}
+
+bool
+GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize,
+                                         uint32_t aAndroidFormat,
+                                         uint32_t aUsage)
+{
+  MOZ_ASSERT(IsValid());
+  ISurfaceAllocator* allocator = GetAllocator();
 
   MaybeMagicGrallocBufferHandle handle;
-  if (!aAllocator->AllocGrallocBuffer(aSize, aAndroidFormat, aUsage, &handle)) {
-    return nullptr;
+  bool allocateResult =
+    allocator->AllocGrallocBuffer(aSize,
+                                  aAndroidFormat,
+                                  aUsage,
+                                  &handle);
+  if (!allocateResult) {
+    return false;
   }
 
   sp<GraphicBuffer> graphicBuffer = GetGraphicBufferFrom(handle);
   if (!graphicBuffer.get()) {
-    return nullptr;
+    return false;
   }
 
   if (graphicBuffer->initCheck() != NO_ERROR) {
-    return nullptr;
+    return false;
   }
 
-  return new GrallocTextureData(handle, aSize, format, aMoz2dBackend);
+  mGrallocHandle = handle;
+  mGraphicBuffer = graphicBuffer;
+  mSize = aSize;
+  return true;
 }
 
-// static
-GrallocTextureData*
-GrallocTextureData::CreateForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                     gfx::BackendType aMoz2dBackend,
-                                     ISurfaceAllocator* aAllocator)
+bool
+GrallocTextureClientOGL::IsAllocated() const
 {
-  if (DisableGralloc(aFormat, aSize)) {
-    return nullptr;
-  }
-  uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
-                   android::GraphicBuffer::USAGE_SW_WRITE_OFTEN |
-                   android::GraphicBuffer::USAGE_HW_TEXTURE;
-  auto data =  GrallocTextureData::Create(aSize, GetAndroidFormat(aFormat),
-                                          aMoz2dBackend, usage, aAllocator);
-
-  if (!data) {
-    return nullptr;
-  }
-
-  DebugOnly<gfx::SurfaceFormat> grallocFormat =
-    SurfaceFormatForPixelFormat(data->mGraphicBuffer->getPixelFormat());
-  // mFormat may be different from the format the graphic buffer reports if we
-  // swap the R and B channels but we should always have at least the same bytes
-  // per pixel!
-  MOZ_ASSERT(BytesPerPixel(data->mFormat) == BytesPerPixel(grallocFormat));
-
-  return data;
+  return !!mGraphicBuffer.get();
 }
 
-TextureFlags
-GrallocTextureData::GetTextureFlags() const
+bool
+GrallocTextureClientOGL::Allocate(uint32_t aSize)
 {
-  if (IsGrallocRBSwapped(mFormat)) {
-    return TextureFlags::RB_SWAPPED;
-  }
-  return TextureFlags::NO_FLAGS;
+  // see Bug 908196
+  MOZ_CRASH("This method should never be called.");
+  return false;
 }
 
-
-// static
-GrallocTextureData*
-GrallocTextureData::CreateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize,
-                                   ISurfaceAllocator* aAllocator)
+size_t
+GrallocTextureClientOGL::GetBufferSize() const
 {
-  MOZ_ASSERT(aYSize.width == aCbCrSize.width * 2);
-  MOZ_ASSERT(aYSize.height == aCbCrSize.height * 2);
-  return GrallocTextureData::Create(aYSize, HAL_PIXEL_FORMAT_YV12,
-                                    gfx::BackendType::NONE,
-                                    android::GraphicBuffer::USAGE_SW_READ_OFTEN,
-                                    aAllocator);
+  // see Bug 908196
+  MOZ_CRASH("This method should never be called.");
+  return 0;
 }
 
-// static
-GrallocTextureData*
-GrallocTextureData::CreateForGLRendering(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                         ISurfaceAllocator* aAllocator)
-{
-  if (aFormat == gfx::SurfaceFormat::YUV) {
-    return nullptr;
-  }
-  uint32_t usage = android::GraphicBuffer::USAGE_HW_RENDER |
-                   android::GraphicBuffer::USAGE_HW_TEXTURE;
-  return GrallocTextureData::Create(aSize, GetAndroidFormat(aFormat),
-                                    gfx::BackendType::NONE, usage, aAllocator);
-}
-
-// static
-already_AddRefed<TextureClient>
-GrallocTextureData::TextureClientFromSharedSurface(gl::SharedSurface* abstractSurf,
-                                                   TextureFlags flags)
+/*static*/ already_AddRefed<TextureClient>
+GrallocTextureClientOGL::FromSharedSurface(gl::SharedSurface* abstractSurf,
+                                           TextureFlags flags)
 {
   auto surf = gl::SharedSurface_Gralloc::Cast(abstractSurf);
 
   RefPtr<TextureClient> ret = surf->GetTextureClient();
 
   TextureFlags mask = TextureFlags::ORIGIN_BOTTOM_LEFT |
                       TextureFlags::RB_SWAPPED |
                       TextureFlags::NON_PREMULTIPLIED;
@@ -421,24 +413,12 @@ GrallocTextureData::TextureClientFromSha
     printf_stderr("Present flags: 0x%x. Required: 0x%x.\n",
                   (uint32_t)present,
                   (uint32_t)required);
     MOZ_CRASH("Flag requirement mismatch.");
   }
   return ret.forget();
 }
 
-TextureData*
-GrallocTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
-                                  TextureFlags aFlags,
-                                  TextureAllocationFlags aAllocFlags) const
-{
-  if (mFormat == gfx::SurfaceFormat::YUV) {
-    return GrallocTextureData::CreateForYCbCr(mSize, mSize*2, aAllocator);
-  } else {
-    return GrallocTextureData::CreateForDrawing(mSize, mFormat, mMoz2DBackend, aAllocator);
-  }
-}
-
 } // namesapace layers
 } // namesapace mozilla
 
 #endif // MOZ_WIDGET_GONK
--- a/gfx/layers/opengl/GrallocTextureClient.h
+++ b/gfx/layers/opengl/GrallocTextureClient.h
@@ -20,118 +20,138 @@ class MediaBuffer;
 
 namespace mozilla {
 namespace gl {
 class SharedSurface;
 }
 
 namespace layers {
 
-/// A TextureData implementation based on android::GraphicBuffer (also referred to
-/// as "gralloc").
-///
-/// Gralloc lets us map texture data in memory (accessible through pointers)
-/// and also use it directly as an OpenGL texture without the cost of texture
-/// uploads.
-/// Gralloc buffers can also be shared accros processes.
-///
-/// More info about Gralloc here: https://wiki.mozilla.org/Platform/GFX/Gralloc
-///
-/// This is only used in Firefox OS
-class GrallocTextureData : public TextureData {
+/**
+ * A TextureClient implementation based on android::GraphicBuffer (also referred to
+ * as "gralloc").
+ *
+ * Gralloc lets us map texture data in memory (accessible through pointers)
+ * and also use it directly as an OpenGL texture without the cost of texture
+ * uploads.
+ * Gralloc buffers can also be shared accros processes.
+ *
+ * More info about Gralloc here: https://wiki.mozilla.org/Platform/GFX/Gralloc
+ *
+ * This is only used in Firefox OS
+ */
+class GrallocTextureClientOGL : public BufferTextureClient
+{
 public:
-  typedef uint32_t AndroidFormat;
+  GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
+                          gfx::SurfaceFormat aFormat,
+                          gfx::BackendType aMoz2dBackend,
+                          TextureFlags aFlags = TextureFlags::DEFAULT);
 
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
+  ~GrallocTextureClientOGL();
 
-  virtual bool Lock(OpenMode aMode, FenceHandle* aFence) override;
+  virtual bool Lock(OpenMode aMode) override;
 
   virtual void Unlock() override;
 
-  virtual gfx::IntSize GetSize() const override { return mSize; }
-
-  virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
-
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
-
-  virtual bool CanExposeMappedData() const override { return true; }
-
-  virtual bool BorrowMappedData(MappedTextureData& aMap) override;
-
-  virtual bool SupportsMoz2D() const override { return true; }
+  virtual bool ImplementsLocking() const override { return true; }
 
   virtual bool HasInternalBuffer() const override { return false; }
 
-  virtual bool HasSynchronization() const override { return true; }
+  virtual bool IsAllocated() const override;
+
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
+
+  virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) override;
+
+  virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) override;
 
-  virtual void Deallocate(ISurfaceAllocator*) override;
+  GrallocTextureClientOGL* AsGrallocTextureClientOGL() override {
+    return this;
+  }
 
-  virtual void Forget(ISurfaceAllocator*) override;
+  void SetTextureFlags(TextureFlags aFlags) { AddFlags(aFlags); }
+
+  gfx::IntSize GetSize() const override { return mSize; }
 
-  static GrallocTextureData* CreateForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                              gfx::BackendType aMoz2dBackend,
-                                              ISurfaceAllocator* aAllocator);
+  android::sp<android::GraphicBuffer> GetGraphicBuffer()
+  {
+    return mGraphicBuffer;
+  }
 
-  static GrallocTextureData* CreateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize,
-                                            ISurfaceAllocator* aAllocator);
+  android::PixelFormat GetPixelFormat()
+  {
+    return mGraphicBuffer->getPixelFormat();
+  }
+
+  virtual uint8_t* GetBuffer() const override;
+
+  virtual gfx::DrawTarget* BorrowDrawTarget() override;
+
+  virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
-  static GrallocTextureData* CreateForGLRendering(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                                  ISurfaceAllocator* aAllocator);
+  virtual bool AllocateForSurface(gfx::IntSize aSize,
+                                  TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
+
+  virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
+                                gfx::IntSize aCbCrSize,
+                                StereoMode aStereoMode) override;
 
-  static GrallocTextureData* Create(gfx::IntSize aSize, AndroidFormat aFormat,
-                                    gfx::BackendType aMoz2DBackend, uint32_t aUsage,
-                                    ISurfaceAllocator* aAllocator);
+  bool AllocateForGLRendering(gfx::IntSize aSize);
+
+  bool AllocateGralloc(gfx::IntSize aYSize, uint32_t aAndroidFormat, uint32_t aUsage);
+
+  void SetIsOpaque(bool aIsOpaque) { mIsOpaque = aIsOpaque; }
+
+  virtual bool Allocate(uint32_t aSize) override;
+
+  virtual size_t GetBufferSize() const override;
 
-
-  static already_AddRefed<TextureClient>
-  TextureClientFromSharedSurface(gl::SharedSurface* abstractSurf, TextureFlags flags);
+  /**
+   * Hold android::MediaBuffer.
+   * MediaBuffer needs to be add refed to keep MediaBuffer alive
+   * during TextureClient is in use.
+   */
+  void SetMediaBuffer(android::MediaBuffer* aMediaBuffer)
+  {
+    mMediaBuffer = aMediaBuffer;
+  }
 
-  virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
-                TextureFlags aFlags = TextureFlags::DEFAULT,
+  android::MediaBuffer* GetMediaBuffer()
+  {
+    return mMediaBuffer;
+  }
+
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
-  // use TextureClient's default implementation
-  virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
-
-  /// Hold android::MediaBuffer.
-  /// MediaBuffer needs to be add refed to keep MediaBuffer alive while the texture
-  /// is in use.
-  ///
-  /// TODO - ideally we should be able to put the MediaBuffer in the texture's
-  /// constructor and not expose these methods.
-  void SetMediaBuffer(android::MediaBuffer* aMediaBuffer) { mMediaBuffer = aMediaBuffer; }
-  android::MediaBuffer* GetMediaBuffer() { return mMediaBuffer; }
-
-  android::sp<android::GraphicBuffer> GetGraphicBuffer() { return mGraphicBuffer; }
-
-  virtual void WaitForFence(FenceHandle* aFence) override;
-
-  ~GrallocTextureData();
-
-  virtual TextureFlags GetTextureFlags() const override;
+  static already_AddRefed<TextureClient> FromSharedSurface(gl::SharedSurface* surf,
+                                                       TextureFlags flags);
 
 protected:
-  GrallocTextureData(MaybeMagicGrallocBufferHandle aGrallocHandle,
-                     gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                     gfx::BackendType aMoz2DBackend);
+  /**
+   * Unfortunately, until bug 879681 is fixed we need to use a GrallocBufferActor.
+   */
+  MaybeMagicGrallocBufferHandle mGrallocHandle;
 
-  gfx::IntSize mSize;
-  gfx::SurfaceFormat mFormat;
-  gfx::BackendType mMoz2DBackend;
+  RefPtr<AsyncTransactionWaiter> mRemoveFromCompositableWaiter;
 
-  MaybeMagicGrallocBufferHandle mGrallocHandle;
   android::sp<android::GraphicBuffer> mGraphicBuffer;
 
-  // Points to a mapped gralloc buffer between calls to lock and unlock.
-  // Should be null outside of the lock-unlock pair.
+  /**
+   * Points to a mapped gralloc buffer between calls to lock and unlock.
+   * Should be null outside of the lock-unlock pair.
+   */
   uint8_t* mMappedBuffer;
 
+  RefPtr<gfx::DrawTarget> mDrawTarget;
+
   android::MediaBuffer* mMediaBuffer;
+
+  bool mIsOpaque;
 };
 
-gfx::SurfaceFormat SurfaceFormatForPixelFormat(android::PixelFormat aFormat);
-
 } // namespace layers
 } // namespace mozilla
 
 #endif // MOZ_WIDGET_GONK
 #endif
--- a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp
@@ -1,61 +1,92 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MacIOSurfaceTextureClientOGL.h"
-#include "mozilla/gfx/MacIOSurface.h" 
+#include "mozilla/gfx/MacIOSurface.h"
 
 namespace mozilla {
 namespace layers {
 
-MacIOSurfaceTextureData::MacIOSurfaceTextureData(MacIOSurface* aSurface)
-: mSurface(aSurface)
-{
-  MOZ_ASSERT(mSurface);
-}
-
-MacIOSurfaceTextureData::~MacIOSurfaceTextureData()
+MacIOSurfaceTextureClientOGL::MacIOSurfaceTextureClientOGL(ISurfaceAllocator* aAllcator,
+                                                           TextureFlags aFlags)
+  : TextureClient(aAllcator, aFlags)
+  , mIsLocked(false)
 {}
 
-// static
-MacIOSurfaceTextureData*
-MacIOSurfaceTextureData::Create(MacIOSurface* aSurface)
+MacIOSurfaceTextureClientOGL::~MacIOSurfaceTextureClientOGL()
+{
+}
+
+void
+MacIOSurfaceTextureClientOGL::FinalizeOnIPDLThread()
 {
-  MOZ_ASSERT(aSurface);
-  if (!aSurface) {
-    return nullptr;
+  if (mActor && mSurface) {
+    KeepUntilFullDeallocation(MakeUnique<TKeepAlive<MacIOSurface>>(mSurface));
   }
-  return new MacIOSurfaceTextureData(aSurface);
+}
+
+// static
+already_AddRefed<MacIOSurfaceTextureClientOGL>
+MacIOSurfaceTextureClientOGL::Create(ISurfaceAllocator* aAllocator,
+                                     TextureFlags aFlags,
+                                     MacIOSurface* aSurface)
+{
+  RefPtr<MacIOSurfaceTextureClientOGL> texture =
+      new MacIOSurfaceTextureClientOGL(aAllocator, aFlags);
+  MOZ_ASSERT(texture->IsValid());
+  MOZ_ASSERT(!texture->IsAllocated());
+  texture->mSurface = aSurface;
+  return texture.forget();
 }
 
 bool
-MacIOSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+MacIOSurfaceTextureClientOGL::Lock(OpenMode aMode)
+{
+  MOZ_ASSERT(!mIsLocked);
+  mIsLocked = true;
+  return IsValid() && IsAllocated();
+}
+
+void
+MacIOSurfaceTextureClientOGL::Unlock()
 {
+  MOZ_ASSERT(mIsLocked);
+  mIsLocked = false;
+}
+
+bool
+MacIOSurfaceTextureClientOGL::IsLocked() const
+{
+  return mIsLocked;
+}
+
+bool
+MacIOSurfaceTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
+{
+  MOZ_ASSERT(IsValid());
+  if (!IsAllocated()) {
+    return false;
+  }
   aOutDescriptor = SurfaceDescriptorMacIOSurface(mSurface->GetIOSurfaceID(),
                                                  mSurface->GetContentsScaleFactor(),
                                                  !mSurface->HasAlpha());
   return true;
 }
 
 gfx::IntSize
-MacIOSurfaceTextureData::GetSize() const
+MacIOSurfaceTextureClientOGL::GetSize() const
 {
   return gfx::IntSize(mSurface->GetDevicePixelWidth(), mSurface->GetDevicePixelHeight());
 }
 
-gfx::SurfaceFormat
-MacIOSurfaceTextureData::GetFormat() const
-{
-  return mSurface->GetFormat();
-}
-
 already_AddRefed<gfx::DataSourceSurface>
-MacIOSurfaceTextureData::GetAsSurface()
+MacIOSurfaceTextureClientOGL::GetAsSurface()
 {
   RefPtr<gfx::SourceSurface> surf = mSurface->GetAsSurface();
   return surf->GetDataSurface();
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h
+++ b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h
@@ -8,44 +8,55 @@
 
 #include "mozilla/layers/TextureClientOGL.h"
 
 class MacIOSurface;
 
 namespace mozilla {
 namespace layers {
 
-class MacIOSurfaceTextureData : public TextureData
+class MacIOSurfaceTextureClientOGL : public TextureClient
 {
 public:
-  static MacIOSurfaceTextureData* Create(MacIOSurface* aSurface);
+  explicit MacIOSurfaceTextureClientOGL(ISurfaceAllocator* aAllcator,
+                                        TextureFlags aFlags);
+
+  virtual ~MacIOSurfaceTextureClientOGL();
 
-  ~MacIOSurfaceTextureData();
+  // Creates a TextureClient and init width.
+  static already_AddRefed<MacIOSurfaceTextureClientOGL>
+  Create(ISurfaceAllocator* aAllocator,
+         TextureFlags aFlags,
+         MacIOSurface* aSurface);
+
+  virtual bool Lock(OpenMode aMode) override;
+
+  virtual void Unlock() override;
+
+  virtual bool IsLocked() const override;
+
+  virtual bool IsAllocated() const override { return !!mSurface; }
+
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
 
   virtual gfx::IntSize GetSize() const override;
 
-  virtual gfx::SurfaceFormat GetFormat() const override;
-
-  virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
-
-  virtual void Unlock() override {}
-
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
-
   virtual bool HasInternalBuffer() const override { return false; }
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override { mSurface = nullptr; }
+  virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
 
-  virtual void Forget(ISurfaceAllocator* aAllocator) override { mSurface = nullptr; }
-
-  // For debugging purposes only.
-  already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
+  // This TextureClient should not be used in a context where we use CreateSimilar
+  // (ex. component alpha) because the underlying texture data is always created by
+  // an external producer.
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags, TextureAllocationFlags) const override { return nullptr; }
 
 protected:
-  explicit MacIOSurfaceTextureData(MacIOSurface* aSurface);
+  virtual void FinalizeOnIPDLThread() override;
 
   RefPtr<MacIOSurface> mSurface;
+  bool mIsLocked;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_MACIOSURFACETEXTURECLIENTOGL_H
--- a/gfx/layers/opengl/TextureClientOGL.cpp
+++ b/gfx/layers/opengl/TextureClientOGL.cpp
@@ -13,105 +13,125 @@
 using namespace mozilla::gl;
 
 namespace mozilla {
 namespace layers {
 
 class CompositableForwarder;
 
 ////////////////////////////////////////////////////////////////////////
-// EGLImage
+// EGLImageTextureClient
 
-EGLImageTextureData::EGLImageTextureData(EGLImageImage* aImage, gfx::IntSize aSize)
-: mImage(aImage)
-, mSize(aSize)
-{
-  MOZ_ASSERT(aImage);
-}
-
-already_AddRefed<TextureClient>
-EGLImageTextureData::CreateTextureClient(EGLImageImage* aImage, gfx::IntSize aSize,
-                                         ISurfaceAllocator* aAllocator, TextureFlags aFlags)
+EGLImageTextureClient::EGLImageTextureClient(ISurfaceAllocator* aAllocator,
+                                             TextureFlags aFlags,
+                                             EGLImageImage* aImage,
+                                             gfx::IntSize aSize)
+  : TextureClient(aAllocator, aFlags)
+  , mImage(aImage)
+  , mSize(aSize)
+  , mIsLocked(false)
 {
   MOZ_ASSERT(XRE_IsParentProcess(),
              "Can't pass an `EGLImage` between processes.");
 
-  if (!aImage || !XRE_IsParentProcess()) {
-    return nullptr;
-  }
-
-  // XXX - This is quite sad and slow.
-  aFlags |= TextureFlags::DEALLOCATE_CLIENT;
+  AddFlags(TextureFlags::DEALLOCATE_CLIENT);
 
   if (aImage->GetOriginPos() == gl::OriginPos::BottomLeft) {
-    aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
+    AddFlags(TextureFlags::ORIGIN_BOTTOM_LEFT);
   }
-
-  return TextureClient::CreateWithData(
-    new EGLImageTextureData(aImage, aSize),
-    aFlags, aAllocator
-  );
 }
 
 bool
-EGLImageTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+EGLImageTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
+  MOZ_ASSERT(IsValid());
+  MOZ_ASSERT(IsAllocated());
+
   const bool hasAlpha = true;
   aOutDescriptor =
     EGLImageDescriptor((uintptr_t)mImage->GetImage(),
                        (uintptr_t)mImage->GetSync(),
                        mImage->GetSize(), hasAlpha);
   return true;
 }
 
+bool
+EGLImageTextureClient::Lock(OpenMode mode)
+  {
+    MOZ_ASSERT(!mIsLocked);
+    if (!IsValid() || !IsAllocated()) {
+      return false;
+    }
+    mIsLocked = true;
+    return true;
+  }
+
+void
+EGLImageTextureClient::Unlock()
+{
+  MOZ_ASSERT(mIsLocked);
+  mIsLocked = false;
+}
+
 ////////////////////////////////////////////////////////////////////////
-// AndroidSurface
+// SurfaceTextureClient
 
 #ifdef MOZ_WIDGET_ANDROID
 
-already_AddRefed<TextureClient>
-AndroidSurfaceTextureData::CreateTextureClient(AndroidSurfaceTexture* aSurfTex,
-                                               gfx::IntSize aSize,
-                                               gl::OriginPos aOriginPos,
-                                               ISurfaceAllocator* aAllocator,
-                                               TextureFlags aFlags)
+SurfaceTextureClient::SurfaceTextureClient(ISurfaceAllocator* aAllocator,
+                                           TextureFlags aFlags,
+                                           AndroidSurfaceTexture* aSurfTex,
+                                           gfx::IntSize aSize,
+                                           gl::OriginPos aOriginPos)
+  : TextureClient(aAllocator, aFlags)
+  , mSurfTex(aSurfTex)
+  , mSize(aSize)
+  , mIsLocked(false)
 {
   MOZ_ASSERT(XRE_IsParentProcess(),
-             "Can't pass an android surfaces between processes.");
+             "Can't pass pointers between processes.");
 
-  if (!aSurfTex || !XRE_IsParentProcess()) {
-    return nullptr;
-  }
-
-  // XXX - This is quite sad and slow.
-  aFlags |= TextureFlags::DEALLOCATE_CLIENT;
+  // Our data is always owned externally.
+  AddFlags(TextureFlags::DEALLOCATE_CLIENT);
 
   if (aOriginPos == gl::OriginPos::BottomLeft) {
-    aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
+    AddFlags(TextureFlags::ORIGIN_BOTTOM_LEFT);
   }
-
-  return TextureClient::CreateWithData(
-    new AndroidSurfaceTextureData(aSurfTex, aSize),
-    aFlags, aAllocator
-  );
 }
 
-AndroidSurfaceTextureData::AndroidSurfaceTextureData(AndroidSurfaceTexture* aSurfTex,
-                                                     gfx::IntSize aSize)
-  : mSurfTex(aSurfTex)
-  , mSize(aSize)
-{}
-
-AndroidSurfaceTextureData::~AndroidSurfaceTextureData()
-{}
+SurfaceTextureClient::~SurfaceTextureClient()
+{
+  // Our data is always owned externally.
+}
 
 bool
-AndroidSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+SurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
+  MOZ_ASSERT(IsValid());
+  MOZ_ASSERT(IsAllocated());
+
   aOutDescriptor = SurfaceTextureDescriptor((uintptr_t)mSurfTex.get(),
                                             mSize);
   return true;
 }
 
+bool
+SurfaceTextureClient::Lock(OpenMode mode)
+{
+  MOZ_ASSERT(!mIsLocked);
+  if (!IsValid() || !IsAllocated()) {
+    return false;
+  }
+  mIsLocked = true;
+  return true;
+}
+
+void
+SurfaceTextureClient::Unlock()
+{
+  MOZ_ASSERT(mIsLocked);
+  mIsLocked = false;
+}
+
 #endif // MOZ_WIDGET_ANDROID
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/opengl/TextureClientOGL.h
+++ b/gfx/layers/opengl/TextureClientOGL.h
@@ -15,90 +15,111 @@
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/TextureClient.h"  // for TextureClient, etc
 #include "AndroidSurfaceTexture.h"
 
 namespace mozilla {
 
 namespace layers {
 
-class EGLImageTextureData : public TextureData
+class EGLImageTextureClient : public TextureClient
 {
 public:
+  EGLImageTextureClient(ISurfaceAllocator* aAllocator,
+                        TextureFlags aFlags,
+                        EGLImageImage* aImage,
+                        gfx::IntSize aSize);
 
-  static already_AddRefed<TextureClient>
-  CreateTextureClient(EGLImageImage* aImage, gfx::IntSize aSize,
-                      ISurfaceAllocator* aAllocator, TextureFlags aFlags);
+  virtual bool IsAllocated() const override { return true; }
 
   virtual bool HasInternalBuffer() const override { return false; }
 
   virtual gfx::IntSize GetSize() const override { return mSize; }
 
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
-
-  virtual void Deallocate(ISurfaceAllocator*) override { mImage = nullptr; }
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
 
-  virtual void Forget(ISurfaceAllocator*) override { mImage = nullptr; }
+  // Useless functions.
+  virtual bool Lock(OpenMode mode) override;
 
-  // Unused functions.
-  virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
+  virtual void Unlock() override;
 
-  virtual void Unlock() override {}
+  virtual bool IsLocked() const override { return mIsLocked; }
 
   virtual gfx::SurfaceFormat GetFormat() const override
   {
     return gfx::SurfaceFormat::UNKNOWN;
   }
 
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
+                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override
+  {
+    return nullptr;
+  }
+
+  virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) override
+  {
+    return false;
+  }
+
 protected:
-  EGLImageTextureData(EGLImageImage* aImage, gfx::IntSize aSize);
-
   RefPtr<EGLImageImage> mImage;
   const gfx::IntSize mSize;
+  bool mIsLocked;
 };
 
 #ifdef MOZ_WIDGET_ANDROID
 
-class AndroidSurfaceTextureData : public TextureData
+class SurfaceTextureClient : public TextureClient
 {
 public:
-  static already_AddRefed<TextureClient>
-  CreateTextureClient(gl::AndroidSurfaceTexture* aSurfTex,
-                      gfx::IntSize aSize,
-                      gl::OriginPos aOriginPos,
-                      ISurfaceAllocator* aAllocator,
-                      TextureFlags aFlags);
+  SurfaceTextureClient(ISurfaceAllocator* aAllocator,
+                       TextureFlags aFlags,
+                       gl::AndroidSurfaceTexture* aSurfTex,
+                       gfx::IntSize aSize,
+                       gl::OriginPos aOriginPos);
 
-  ~AndroidSurfaceTextureData();
+  ~SurfaceTextureClient();
+
+  virtual bool IsAllocated() const override { return true; }
 
   virtual bool HasInternalBuffer() const override { return false; }
 
-  virtual gfx::IntSize GetSize() const override { return mSize; }
+  virtual gfx::IntSize GetSize() const { return mSize; }
 
-  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
+  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
 
   // Useless functions.
-  virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
+  virtual bool Lock(OpenMode mode) override;
 
-  virtual void Unlock() override {}
+  virtual void Unlock() override;
+
+  virtual bool IsLocked() const override { return mIsLocked; }
 
   virtual gfx::SurfaceFormat GetFormat() const override
   {
     return gfx::SurfaceFormat::UNKNOWN;
   }
 
-  // Our data is always owned externally.
-  virtual void Deallocate(ISurfaceAllocator*) override {}
+  virtual already_AddRefed<TextureClient>
+  CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
+                TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override
+  {
+    return nullptr;
+  }
+
+  virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) override
+  {
+    return false;
+  }
 
 protected:
-  AndroidSurfaceTextureData(gl::AndroidSurfaceTexture* aSurfTex,
-                            gfx::IntSize aSize);
-
   const RefPtr<gl::AndroidSurfaceTexture> mSurfTex;
   const gfx::IntSize mSize;
+  bool mIsLocked;
 };
 
 #endif // MOZ_WIDGET_ANDROID
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -5,17 +5,16 @@
 
 #include "gtest/gtest.h"
 #include "gmock/gmock.h"
 
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Tools.h"
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/TextureHost.h"
-#include "mozilla/layers/BufferTexture.h"
 #include "mozilla/RefPtr.h"
 #include "gfx2DGlue.h"
 #include "gfxImageSurface.h"
 #include "gfxTypes.h"
 #include "ImageContainer.h"
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
 
 using namespace mozilla;
@@ -144,16 +143,18 @@ void AssertYCbCrSurfacesEqual(PlanarYCbC
   }
 }
 
 // Run the test for a texture client and a surface
 void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface) {
 
   // client allocation
   ASSERT_TRUE(texture->CanExposeDrawTarget());
+  texture->AllocateForSurface(surface->GetSize());
+  ASSERT_TRUE(texture->IsAllocated());
 
   ASSERT_TRUE(texture->Lock(OpenMode::OPEN_READ_WRITE));
   // client painting
   RefPtr<DrawTarget> dt = texture->BorrowDrawTarget();
   RefPtr<SourceSurface> source =
     gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, surface);
   dt->CopySurface(source, IntRect(IntPoint(), source->GetSize()), IntPoint());
 
@@ -193,18 +194,28 @@ void TestTextureClientSurface(TextureCli
                           SurfaceFormatToImageFormat(hostDataSurface->GetFormat()));
     AssertSurfacesEqual(surface, hostSurface.get());
     host->Unlock();
   }
 }
 
 // Same as above, for YCbCr surfaces
 void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
-  client->Lock(OpenMode::OPEN_READ_WRITE);
-  UpdateYCbCrTextureClient(client, ycbcrData);
+
+  // client allocation
+  ASSERT_TRUE(client->AsTextureClientYCbCr() != nullptr);
+  TextureClientYCbCr* texture = client->AsTextureClientYCbCr();
+  texture->AllocateForYCbCr(ycbcrData.mYSize,
+                            ycbcrData.mCbCrSize,
+                            ycbcrData.mStereoMode);
+  ASSERT_TRUE(client->IsAllocated());
+
+  ASSERT_TRUE(client->Lock(OpenMode::OPEN_READ_WRITE));
+  // client painting
+  texture->UpdateYCbCr(ycbcrData);
   client->Unlock();
 
   // client serialization
   SurfaceDescriptor descriptor;
   ASSERT_TRUE(client->ToSurfaceDescriptor(descriptor));
 
   ASSERT_NE(descriptor.type(), SurfaceDescriptor::Tnull_t);
 
@@ -257,25 +268,21 @@ TEST(Layers, TextureSerialization) {
     gfxImageFormat::A8,
   };
 
   for (int f = 0; f < 3; ++f) {
     RefPtr<gfxImageSurface> surface = new gfxImageSurface(IntSize(400,300), formats[f]);
     SetupSurface(surface.get());
     AssertSurfacesEqual(surface, surface);
 
-    auto texData = BufferTextureData::Create(surface->GetSize(),
-      gfx::ImageFormatToSurfaceFormat(surface->Format()),
-      gfx::BackendType::CAIRO, TextureFlags::DEALLOCATE_CLIENT, ALLOC_DEFAULT, nullptr
-    );
-    ASSERT_TRUE(!!texData);
-
-    RefPtr<TextureClient> client = new TextureClient(
-      texData, TextureFlags::DEALLOCATE_CLIENT, nullptr
-    );
+    RefPtr<TextureClient> client
+      = new MemoryTextureClient(nullptr,
+                                mozilla::gfx::ImageFormatToSurfaceFormat(surface->Format()),
+                                gfx::BackendType::CAIRO,
+                                TextureFlags::DEALLOCATE_CLIENT);
 
     TestTextureClientSurface(client, surface);
 
     // XXX - Test more texture client types.
   }
 }
 
 TEST(Layers, TextureYCbCrSerialization) {
@@ -298,15 +305,18 @@ TEST(Layers, TextureYCbCrSerialization) 
   clientData.mStereoMode = StereoMode::MONO;
   clientData.mYSkip = 0;
   clientData.mCbSkip = 0;
   clientData.mCrSkip = 0;
   clientData.mCrSkip = 0;
   clientData.mPicX = 0;
   clientData.mPicX = 0;
 
-  RefPtr<TextureClient> client = TextureClient::CreateForYCbCr(nullptr, clientData.mYSize, clientData.mCbCrSize,
-                                                               StereoMode::MONO, TextureFlags::DEALLOCATE_CLIENT);
+  RefPtr<TextureClient> client
+    = new MemoryTextureClient(nullptr,
+                              mozilla::gfx::SurfaceFormat::YUV,
+                              gfx::BackendType::CAIRO,
+                              TextureFlags::DEALLOCATE_CLIENT);
 
   TestTextureClientYCbCr(client, clientData);
 
   // XXX - Test more texture client types.
 }
--- a/widget/gonk/nativewindow/GonkBufferQueueJB.cpp
+++ b/widget/gonk/nativewindow/GonkBufferQueueJB.cpp
@@ -416,28 +416,29 @@ status_t GonkBufferQueue::dequeueBuffer(
         }
 
         *outFence = mSlots[buf].mFence;
         mSlots[buf].mFence = Fence::NO_FENCE;
     }  // end lock scope
 
     sp<GraphicBuffer> graphicBuffer;
     if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
-
+        RefPtr<GrallocTextureClientOGL> textureClient =
+            new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
+                                        gfx::SurfaceFormat::UNKNOWN,
+                                        gfx::BackendType::NONE,
+                                        TextureFlags::DEALLOCATE_CLIENT);
+        textureClient->SetIsOpaque(true);
         usage |= GraphicBuffer::USAGE_HW_TEXTURE;
-        ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
-        GrallocTextureData* texData = GrallocTextureData::Create(IntSize(w,h), format,
-                                                                 gfx::BackendType::NONE, usage,
-                                                                 allocator);
-        if (!texData) {
+        bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
+        sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
+        if (!result || !graphicBuffer.get()) {
             ST_LOGE("dequeueBuffer: failed to alloc gralloc buffer");
             return -ENOMEM;
         }
-        RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
-        sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
 
         { // Scope for the lock
             Mutex::Autolock lock(mMutex);
 
             if (mAbandoned) {
                 ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
                 return NO_INIT;
             }
--- a/widget/gonk/nativewindow/GonkBufferQueueKK.cpp
+++ b/widget/gonk/nativewindow/GonkBufferQueueKK.cpp
@@ -435,38 +435,41 @@ status_t GonkBufferQueue::dequeueBuffer(
             ALOGE("dequeueBuffer: about to return a NULL fence from mSlot. "
                     "buf=%d, w=%d, h=%d, format=%d",
                     buf, buffer->width, buffer->height, buffer->format);
         }
         *outFence = mSlots[buf].mFence;
         mSlots[buf].mFence = Fence::NO_FENCE;
     }  // end lock scope
 
+    sp<GraphicBuffer> graphicBuffer;
     if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
-
-        ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
+        RefPtr<GrallocTextureClientOGL> textureClient =
+            new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
+                                        gfx::SurfaceFormat::UNKNOWN,
+                                        gfx::BackendType::NONE,
+                                        TextureFlags::DEALLOCATE_CLIENT);
+        textureClient->SetIsOpaque(true);
         usage |= GraphicBuffer::USAGE_HW_TEXTURE;
-        GrallocTextureData* texData = GrallocTextureData::Create(IntSize(w, h), format,
-                                                                 gfx::BackendType::NONE, usage,
-                                                                 allocator);
-        if (!texData) {
+        bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
+        sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
+        if (!result || !graphicBuffer.get()) {
+            ALOGE("dequeueBuffer: failed to alloc gralloc buffer");
             return -ENOMEM;
         }
 
-        RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
-
         { // Scope for the lock
             Mutex::Autolock lock(mMutex);
 
             if (mAbandoned) {
                 ALOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
                 return NO_INIT;
             }
 
-            mSlots[buf].mGraphicBuffer = texData->GetGraphicBuffer();
+            mSlots[buf].mGraphicBuffer = graphicBuffer;
             mSlots[buf].mTextureClient = textureClient;
             ALOGD("dequeueBuffer: returning slot=%d buf=%p ", buf,
                     mSlots[buf].mGraphicBuffer->handle);
 
         }
 
     }
 
--- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp
+++ b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp
@@ -336,29 +336,29 @@ status_t GonkBufferQueueProducer::dequeu
                     found, buffer->width, buffer->height, buffer->format);
         }
 
         *outFence = mSlots[found].mFence;
         mSlots[found].mFence = Fence::NO_FENCE;
     } // Autolock scope
 
     if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
-        ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
+        RefPtr<GrallocTextureClientOGL> textureClient =
+            new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
+                                        gfx::SurfaceFormat::UNKNOWN,
+                                        gfx::BackendType::NONE,
+                                        TextureFlags::DEALLOCATE_CLIENT);
+        textureClient->SetIsOpaque(true);
         usage |= GraphicBuffer::USAGE_HW_TEXTURE;
-        GrallocTextureData* texData = GrallocTextureData::Create(IntSize(width,height), format,
-                                                                 gfx::BackendType::NONE,
-                                                                 usage, allocator);
-        if (!texData) {
+        bool result = textureClient->AllocateGralloc(IntSize(width, height), format, usage);
+        sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
+        if (!result || !graphicBuffer.get()) {
             ALOGE("dequeueBuffer: failed to alloc gralloc buffer");
             return -ENOMEM;
         }
-        RefPtr<TextureClient> textureClient = TextureClient::CreateWithData(
-            texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
-
-        sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
 
         { // Autolock scope
             Mutex::Autolock lock(mCore->mMutex);
 
             if (mCore->mIsAbandoned) {
                 ALOGE("dequeueBuffer: GonkBufferQueue has been abandoned");
                 return NO_INIT;
             }
--- a/widget/gonk/nativewindow/GonkNativeWindowICS.cpp
+++ b/widget/gonk/nativewindow/GonkNativeWindowICS.cpp
@@ -313,40 +313,44 @@ status_t GonkNativeWindow::dequeueBuffer
                 TextureClientReleaseTask* task = new TextureClientReleaseTask(mSlots[buf].mTextureClient);
                 mSlots[buf].mTextureClient = NULL;
                 ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(FROM_HERE, task);
             }
             alloc = true;
         }
     }  // end lock scope
 
+    sp<GraphicBuffer> graphicBuffer;
     if (alloc) {
-        ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
+        RefPtr<GrallocTextureClientOGL> textureClient =
+            new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
+                                        gfx::SurfaceFormat::UNKNOWN,
+                                        gfx::BackendType::NONE,
+                                        TextureFlags::DEALLOCATE_CLIENT);
+        textureClient->SetIsOpaque(true);
         usage |= GraphicBuffer::USAGE_HW_TEXTURE;
-        GrallocTextureData* texData = GrallocTextureData::Create(IntSize(w, h), format,
-                                                                 gfx::BackendType::NONE, usage,
-                                                                 allocator);
-        if (!texData) {
+        bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
+        sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
+        if (!result || !graphicBuffer.get()) {
+            CNW_LOGE("dequeueBuffer: failed to alloc gralloc buffer");
             return -ENOMEM;
         }
 
-        RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
-
         { // Scope for the lock
             Mutex::Autolock lock(mMutex);
 
             if (mAbandoned) {
                 CNW_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
                 return NO_INIT;
             }
 
             if (updateFormat) {
                 mPixelFormat = format;
             }
-            mSlots[buf].mGraphicBuffer = texData->GetGraphicBuffer();
+            mSlots[buf].mGraphicBuffer = graphicBuffer;
             mSlots[buf].mTextureClient = textureClient;
 
             returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
 
             CNW_LOGD("dequeueBuffer: returning slot=%d buf=%p ", buf,
                     mSlots[buf].mGraphicBuffer->handle);
         }
     }