Bug 1144906 - Support fast WebGL on E10S. - r=mattwoodrow,nical
☠☠ backed out by 3d5d1e28ebe4 ☠ ☠
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 06 May 2015 13:48:28 -0700
changeset 274054 93af6e2a390d94f86c85f6d342c94f06857543fc
parent 274053 eb08fbc9aec2ba95fda90a805abfb2053e8de2c0
child 274055 7c7e849bb5fd8f7e4e6a7afd49b6f3377984990e
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, nical
bugs1144906
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1144906 - Support fast WebGL on E10S. - r=mattwoodrow,nical
gfx/gl/GLScreenBuffer.cpp
gfx/gl/GLScreenBuffer.h
gfx/gl/SharedSurface.cpp
gfx/gl/SharedSurface.h
gfx/gl/SharedSurfaceANGLE.cpp
gfx/gl/SharedSurfaceANGLE.h
gfx/gl/SharedSurfaceEGL.cpp
gfx/gl/SharedSurfaceEGL.h
gfx/gl/SharedSurfaceGL.cpp
gfx/gl/SharedSurfaceGL.h
gfx/gl/SharedSurfaceGralloc.cpp
gfx/gl/SharedSurfaceGralloc.h
gfx/gl/SharedSurfaceIO.cpp
gfx/gl/SharedSurfaceIO.h
gfx/gl/SurfaceTypes.h
gfx/layers/AtomicRefCountedWithFinalize.h
gfx/layers/CopyableCanvasLayer.cpp
gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CanvasClient.h
gfx/layers/client/ClientCanvasLayer.cpp
gfx/layers/client/ClientCanvasLayer.h
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/client/TextureClientSharedSurface.cpp
gfx/layers/client/TextureClientSharedSurface.h
gfx/layers/composite/FPSCounter.cpp
gfx/layers/composite/ImageHost.cpp
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/ipc/LayersSurfaces.ipdlh
gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
gfx/layers/ipc/SharedRGBImage.cpp
gfx/layers/moz.build
gfx/layers/opengl/GrallocTextureClient.h
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
gfx/layers/opengl/TextureHostOGL.cpp
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -16,16 +16,17 @@
 #include "nsXULAppAPI.h"
 #endif
 #ifdef XP_MACOSX
 #include "SharedSurfaceIO.h"
 #endif
 #include "ScopedGLHelpers.h"
 #include "gfx2DGlue.h"
 #include "../layers/ipc/ShadowLayers.h"
+#include "mozilla/layers/TextureClientSharedSurface.h"
 
 namespace mozilla {
 namespace gl {
 
 using gfx::SurfaceFormat;
 
 UniquePtr<GLScreenBuffer>
 GLScreenBuffer::Create(GLContext* gl,
@@ -34,50 +35,46 @@ GLScreenBuffer::Create(GLContext* gl,
 {
     UniquePtr<GLScreenBuffer> ret;
     if (caps.antialias &&
         !gl->IsSupported(GLFeature::framebuffer_multisample))
     {
         return Move(ret);
     }
 
-    UniquePtr<SurfaceFactory> factory;
-
-#ifdef MOZ_WIDGET_GONK
-    /* On B2G, we want a Gralloc factory, and we want one right at the start */
-    layers::ISurfaceAllocator* allocator = caps.surfaceAllocator;
-    if (!factory &&
-        allocator &&
-        XRE_GetProcessType() != GeckoProcessType_Default)
-    {
-        layers::TextureFlags flags = layers::TextureFlags::DEALLOCATE_CLIENT |
-                                     layers::TextureFlags::ORIGIN_BOTTOM_LEFT;
-        if (!caps.premultAlpha) {
-            flags |= layers::TextureFlags::NON_PREMULTIPLIED;
-        }
 
-        factory = MakeUnique<SurfaceFactory_Gralloc>(gl, caps, flags,
-                                                     allocator);
+    layers::TextureFlags flags = layers::TextureFlags::ORIGIN_BOTTOM_LEFT;
+    if (!caps.premultAlpha) {
+        flags |= layers::TextureFlags::NON_PREMULTIPLIED;
     }
-#endif
-#ifdef XP_MACOSX
-    /* On OSX, we want an IOSurface factory, and we want one right at the start */
-    if (!factory) {
-        factory = SurfaceFactory_IOSurface::Create(gl, caps);
-    }
-#endif
 
-    if (!factory) {
-        factory = MakeUnique<SurfaceFactory_Basic>(gl, caps);
-    }
+    UniquePtr<SurfaceFactory> factory = MakeUnique<SurfaceFactory_Basic>(gl, caps, flags);
 
     ret.reset( new GLScreenBuffer(gl, caps, Move(factory)) );
     return Move(ret);
 }
 
+GLScreenBuffer::GLScreenBuffer(GLContext* gl,
+                               const SurfaceCaps& caps,
+                               UniquePtr<SurfaceFactory> factory)
+    : mGL(gl)
+    , mCaps(caps)
+    , mFactory(Move(factory))
+    , mNeedsBlit(true)
+    , mUserReadBufferMode(LOCAL_GL_BACK)
+    , mUserDrawFB(0)
+    , mUserReadFB(0)
+    , mInternalDrawFB(0)
+    , mInternalReadFB(0)
+#ifdef DEBUG
+    , mInInternalMode_DrawFB(true)
+    , mInInternalMode_ReadFB(true)
+#endif
+{ }
+
 GLScreenBuffer::~GLScreenBuffer()
 {
     mDraw = nullptr;
     mRead = nullptr;
 
     // bug 914823: it is crucial to destroy the Factory _after_ we destroy
     // the SharedSurfaces around here! Reason: the shared surfaces will want
     // to ask the Allocator (e.g. the ClientLayerManager) to destroy their
@@ -460,17 +457,17 @@ GLScreenBuffer::Attach(SharedSurface* su
     RequireBlit();
 
     return true;
 }
 
 bool
 GLScreenBuffer::Swap(const gfx::IntSize& size)
 {
-    RefPtr<ShSurfHandle> newBack = mFactory->NewShSurfHandle(size);
+    RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
     if (!newBack)
         return false;
 
     if (!Attach(newBack->Surf(), size))
         return false;
     // Attach was successful.
 
     mFront = mBack;
@@ -517,17 +514,17 @@ GLScreenBuffer::PublishFrame(const gfx::
 
     bool good = Swap(size);
     return good;
 }
 
 bool
 GLScreenBuffer::Resize(const gfx::IntSize& size)
 {
-    RefPtr<ShSurfHandle> newBack = mFactory->NewShSurfHandle(size);
+    RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
     if (!newBack)
         return false;
 
     if (!Attach(newBack->Surf(), size))
         return false;
 
     if (mBack)
         mBack->Surf()->ProducerRelease();
--- a/gfx/gl/GLScreenBuffer.h
+++ b/gfx/gl/GLScreenBuffer.h
@@ -19,16 +19,20 @@
 #include "GLDefs.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Point.h"
 #include "mozilla/UniquePtr.h"
 #include "SharedSurface.h"
 #include "SurfaceTypes.h"
 
 namespace mozilla {
+namespace layers {
+class SharedSurfaceTextureClient;
+}
+
 namespace gl {
 
 class GLContext;
 class SharedSurface;
 class ShSurfHandle;
 class SurfaceFactory;
 
 class DrawBuffer
@@ -131,18 +135,18 @@ public:
 
 protected:
     GLContext* const mGL; // Owns us.
 public:
     const SurfaceCaps mCaps;
 protected:
     UniquePtr<SurfaceFactory> mFactory;
 
-    RefPtr<ShSurfHandle> mBack;
-    RefPtr<ShSurfHandle> mFront;
+    RefPtr<layers::SharedSurfaceTextureClient> mBack;
+    RefPtr<layers::SharedSurfaceTextureClient> mFront;
 
     UniquePtr<DrawBuffer> mDraw;
     UniquePtr<ReadBuffer> mRead;
 
     bool mNeedsBlit;
 
     GLenum mUserReadBufferMode;
 
@@ -154,40 +158,26 @@ protected:
 
 #ifdef DEBUG
     bool mInInternalMode_DrawFB;
     bool mInInternalMode_ReadFB;
 #endif
 
     GLScreenBuffer(GLContext* gl,
                    const SurfaceCaps& caps,
-                   UniquePtr<SurfaceFactory> factory)
-        : mGL(gl)
-        , mCaps(caps)
-        , mFactory(Move(factory))
-        , mNeedsBlit(true)
-        , mUserReadBufferMode(LOCAL_GL_BACK)
-        , mUserDrawFB(0)
-        , mUserReadFB(0)
-        , mInternalDrawFB(0)
-        , mInternalReadFB(0)
-#ifdef DEBUG
-        , mInInternalMode_DrawFB(true)
-        , mInInternalMode_ReadFB(true)
-#endif
-    {}
+                   UniquePtr<SurfaceFactory> factory);
 
 public:
     virtual ~GLScreenBuffer();
 
     SurfaceFactory* Factory() const {
         return mFactory.get();
     }
 
-    ShSurfHandle* Front() const {
+    const RefPtr<layers::SharedSurfaceTextureClient>& Front() const {
         return mFront;
     }
 
     SharedSurface* SharedSurf() const {
         MOZ_ASSERT(mRead);
         return mRead->SharedSurf();
     }
 
--- a/gfx/gl/SharedSurface.cpp
+++ b/gfx/gl/SharedSurface.cpp
@@ -7,16 +7,18 @@
 
 #include "../2d/2D.h"
 #include "GLBlitHelper.h"
 #include "GLContext.h"
 #include "GLReadTexImageHelper.h"
 #include "nsThreadUtils.h"
 #include "ScopedGLHelpers.h"
 #include "SharedSurfaceGL.h"
+#include "mozilla/layers/CompositorTypes.h"
+#include "mozilla/layers/TextureClientSharedSurface.h"
 
 namespace mozilla {
 namespace gl {
 
 /*static*/ void
 SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
                         SurfaceFactory* factory)
 {
@@ -27,22 +29,19 @@ SharedSurface::ProdCopy(SharedSurface* s
     MOZ_ASSERT((src == gl->GetLockedSurface()) == src->IsLocked());
 
     gl->MakeCurrent();
 
     if (src->mAttachType  == AttachmentType::Screen &&
         dest->mAttachType == AttachmentType::Screen)
     {
         // Here, we actually need to blit through a temp surface, so let's make one.
-        UniquePtr<SharedSurface_GLTexture> tempSurf;
-        tempSurf = SharedSurface_GLTexture::Create(gl,
-                                                   gl,
-                                                   factory->mFormats,
-                                                   src->mSize,
-                                                   factory->mCaps.alpha);
+        UniquePtr<SharedSurface_Basic> tempSurf;
+        tempSurf = SharedSurface_Basic::Create(gl, factory->mFormats, src->mSize,
+                                               factory->mCaps.alpha);
 
         ProdCopy(src, tempSurf.get(), factory);
         ProdCopy(tempSurf.get(), dest, factory);
         return;
     }
 
     if (src->mAttachType == AttachmentType::Screen) {
         SharedSurface* origLocked = gl->GetLockedSurface();
@@ -198,30 +197,31 @@ SharedSurface::ProdCopy(SharedSurface* s
 ////////////////////////////////////////////////////////////////////////
 // SharedSurface
 
 
 SharedSurface::SharedSurface(SharedSurfaceType type,
                              AttachmentType attachType,
                              GLContext* gl,
                              const gfx::IntSize& size,
-                             bool hasAlpha)
+                             bool hasAlpha,
+                             bool canRecycle)
     : mType(type)
     , mAttachType(attachType)
     , mGL(gl)
     , mSize(size)
     , mHasAlpha(hasAlpha)
+    , mCanRecycle(canRecycle)
     , mIsLocked(false)
     , mIsProducerAcquired(false)
     , mIsConsumerAcquired(false)
 #ifdef DEBUG
     , mOwningThread(NS_GetCurrentThread())
 #endif
-{
-}
+{ }
 
 void
 SharedSurface::LockProd()
 {
     MOZ_ASSERT(!mIsLocked);
 
     LockProdImpl();
 
@@ -257,18 +257,16 @@ SharedSurface::WaitSync_ContentThread()
 
 bool
 SharedSurface::PollSync_ContentThread()
 {
     MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
     return PollSync_ContentThread_Impl();
 }
 
-
-
 ////////////////////////////////////////////////////////////////////////
 // SurfaceFactory
 
 static void
 ChooseBufferBits(const SurfaceCaps& caps,
                  SurfaceCaps* const out_drawCaps,
                  SurfaceCaps* const out_readCaps)
 {
@@ -296,74 +294,93 @@ ChooseBufferBits(const SurfaceCaps& caps
         out_readCaps->alpha = caps.alpha;
         out_readCaps->bpp16 = caps.bpp16;
     } else {
         out_drawCaps->Clear();
         *out_readCaps = screenCaps;
     }
 }
 
-SurfaceFactory::SurfaceFactory(GLContext* gl,
-                               SharedSurfaceType type,
-                               const SurfaceCaps& caps)
-    : mGL(gl)
+SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl,
+                               const SurfaceCaps& caps,
+                               const RefPtr<layers::ISurfaceAllocator>& allocator,
+                               const layers::TextureFlags& flags)
+    : mType(type)
+    , mGL(gl)
     , mCaps(caps)
-    , mType(type)
+    , mAllocator(allocator)
+    , mFlags(flags)
     , mFormats(gl->ChooseGLFormats(caps))
 {
     ChooseBufferBits(mCaps, &mDrawCaps, &mReadCaps);
 }
 
 SurfaceFactory::~SurfaceFactory()
 {
-    while (!mScraps.Empty()) {
-        mScraps.Pop();
+    while (!mRecyclePool.empty()) {
+        RefPtr<layers::SharedSurfaceTextureClient> cur = mRecyclePool.front();
+        mRecyclePool.pop();
+
+        cur->StopRecycling();
     }
 }
 
-UniquePtr<SharedSurface>
-SurfaceFactory::NewSharedSurface(const gfx::IntSize& size)
+TemporaryRef<layers::SharedSurfaceTextureClient>
+SurfaceFactory::NewTexClient(const gfx::IntSize& size)
 {
-    // Attempt to reuse an old surface.
-    while (!mScraps.Empty()) {
-        UniquePtr<SharedSurface> cur = mScraps.Pop();
+    while (!mRecyclePool.empty()) {
+        RefPtr<layers::SharedSurfaceTextureClient> cur = mRecyclePool.front();
+        mRecyclePool.pop();
 
-        if (cur->mSize == size)
-            return Move(cur);
+        if (cur->Surf()->mSize == size) {
+            return cur.forget();
+        }
 
-        // Let `cur` be destroyed as it falls out of scope, if it wasn't
-        // moved.
+        // Let it die.
+        cur->StopRecycling();
     }
 
-    return CreateShared(size);
-}
-
-TemporaryRef<ShSurfHandle>
-SurfaceFactory::NewShSurfHandle(const gfx::IntSize& size)
-{
-    auto surf = NewSharedSurface(size);
+    UniquePtr<SharedSurface> surf = Move(CreateShared(size));
     if (!surf)
         return nullptr;
 
-    // Before next use, wait until SharedSurface's buffer
-    // is no longer being used.
-    surf->WaitForBufferOwnership();
-
-    return new ShSurfHandle(this, Move(surf));
+    RefPtr<layers::SharedSurfaceTextureClient> ret;
+    ret = new layers::SharedSurfaceTextureClient(mAllocator, mFlags, Move(surf), this);
+    return ret.forget();
 }
 
-// Auto-deletes surfs of the wrong type.
-void
-SurfaceFactory::Recycle(UniquePtr<SharedSurface> surf)
+/*static*/ void
+SurfaceFactory::RecycleCallback(layers::TextureClient* tc, void* /*closure*/)
 {
-    MOZ_ASSERT(surf);
+    MOZ_ASSERT(NS_IsMainThread());
+
+    layers::SharedSurfaceTextureClient* sstc = (layers::SharedSurfaceTextureClient*)tc;
+
+    if (sstc->mSurf->mCanRecycle && sstc->mFactory) {
+        if (sstc->mFactory->Recycle(sstc))
+            return;
+    }
+
+    // Did not recover the tex client. End the (re)cycle!
+    sstc->StopRecycling();
+}
 
-    if (surf->mType == mType) {
-        mScraps.Push(Move(surf));
+bool
+SurfaceFactory::Recycle(layers::SharedSurfaceTextureClient* texClient)
+{
+    MOZ_ASSERT(texClient);
+    MOZ_ASSERT(texClient->mFactory == this);
+
+    if (mRecyclePool.size() >= 2) {
+        return false;
     }
+
+    RefPtr<layers::SharedSurfaceTextureClient> texClientRef = texClient;
+    mRecyclePool.push(texClientRef);
+    return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // ScopedReadbackFB
 
 ScopedReadbackFB::ScopedReadbackFB(SharedSurface* src)
     : mGL(src->mGL)
     , mAutoFB(mGL)
--- a/gfx/gl/SharedSurface.h
+++ b/gfx/gl/SharedSurface.h
@@ -29,16 +29,25 @@
 #include "SurfaceTypes.h"
 
 class nsIThread;
 
 namespace mozilla {
 namespace gfx {
 class DrawTarget;
 }
+
+namespace layers {
+class ISurfaceAllocator;
+class SharedSurfaceTextureClient;
+enum class TextureFlags : uint32_t;
+class SurfaceDescriptor;
+class TextureClient;
+}
+
 namespace gl {
 
 class GLContext;
 class SurfaceFactory;
 class ShSurfHandle;
 
 class SharedSurface
 {
@@ -46,27 +55,29 @@ public:
     static void ProdCopy(SharedSurface* src, SharedSurface* dest,
                          SurfaceFactory* factory);
 
     const SharedSurfaceType mType;
     const AttachmentType mAttachType;
     GLContext* const mGL;
     const gfx::IntSize mSize;
     const bool mHasAlpha;
+    const bool mCanRecycle;
 protected:
     bool mIsLocked;
     bool mIsProducerAcquired;
     bool mIsConsumerAcquired;
     DebugOnly<nsIThread* const> mOwningThread;
 
     SharedSurface(SharedSurfaceType type,
                   AttachmentType attachType,
                   GLContext* gl,
                   const gfx::IntSize& size,
-                  bool hasAlpha);
+                  bool hasAlpha,
+                  bool canRecycle);
 
 public:
     virtual ~SharedSurface() {
     }
 
     bool IsLocked() const {
         return mIsLocked;
     }
@@ -168,121 +179,65 @@ public:
                             GLvoid* pixels)
     {
         return false;
     }
 
     virtual bool NeedsIndirectReads() const {
         return false;
     }
-};
 
-template<typename T>
-class UniquePtrQueue
-{
-    std::queue<T*> mQueue;
-
-public:
-    ~UniquePtrQueue() {
-        MOZ_ASSERT(Empty());
-    }
-
-    bool Empty() const {
-        return mQueue.empty();
-    }
-
-    void Push(UniquePtr<T> up) {
-        T* p = up.release();
-        mQueue.push(p);
-    }
-
-    UniquePtr<T> Pop() {
-        UniquePtr<T> ret;
-
-        if (!mQueue.empty()) {
-            ret.reset(mQueue.front());
-            mQueue.pop();
-        }
-
-        return Move(ret);
-    }
+    virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) = 0;
 };
 
 class SurfaceFactory : public SupportsWeakPtr<SurfaceFactory>
 {
 public:
     // Should use the VIRTUAL version, but it's currently incompatible
     // with SupportsWeakPtr. (bug 1049278)
     MOZ_DECLARE_WEAKREFERENCE_TYPENAME(SurfaceFactory)
 
+    const SharedSurfaceType mType;
     GLContext* const mGL;
     const SurfaceCaps mCaps;
-    const SharedSurfaceType mType;
+    const RefPtr<layers::ISurfaceAllocator> mAllocator;
+    const layers::TextureFlags mFlags;
     const GLFormats mFormats;
-
 protected:
     SurfaceCaps mDrawCaps;
     SurfaceCaps mReadCaps;
+    std::queue<RefPtr<layers::SharedSurfaceTextureClient>> mRecyclePool;
 
-    SurfaceFactory(GLContext* gl,
-                   SharedSurfaceType type,
-                   const SurfaceCaps& caps);
+    SurfaceFactory(SharedSurfaceType type, GLContext* gl, const SurfaceCaps& caps,
+                   const RefPtr<layers::ISurfaceAllocator>& allocator,
+                   const layers::TextureFlags& flags);
 
 public:
     virtual ~SurfaceFactory();
 
     const SurfaceCaps& DrawCaps() const {
         return mDrawCaps;
     }
 
     const SurfaceCaps& ReadCaps() const {
         return mReadCaps;
     }
 
 protected:
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) = 0;
 
-    UniquePtrQueue<SharedSurface> mScraps;
-
 public:
     UniquePtr<SharedSurface> NewSharedSurface(const gfx::IntSize& size);
-    TemporaryRef<ShSurfHandle> NewShSurfHandle(const gfx::IntSize& size);
+    //TemporaryRef<ShSurfHandle> NewShSurfHandle(const gfx::IntSize& size);
+    TemporaryRef<layers::SharedSurfaceTextureClient> NewTexClient(const gfx::IntSize& size);
+
+    static void RecycleCallback(layers::TextureClient* tc, void* /*closure*/);
 
     // Auto-deletes surfs of the wrong type.
-    void Recycle(UniquePtr<SharedSurface> surf);
-};
-
-class ShSurfHandle : public RefCounted<ShSurfHandle>
-{
-public:
-    MOZ_DECLARE_REFCOUNTED_TYPENAME(ShSurfHandle)
-
-private:
-    const WeakPtr<SurfaceFactory> mFactory;
-    UniquePtr<SharedSurface> mSurf;
-
-public:
-    ShSurfHandle(SurfaceFactory* factory, UniquePtr<SharedSurface> surf)
-        : mFactory(factory)
-        , mSurf(Move(surf))
-    {
-        MOZ_ASSERT(mFactory);
-        MOZ_ASSERT(mSurf);
-    }
-
-    ~ShSurfHandle() {
-        if (mFactory) {
-            mFactory->Recycle(Move(mSurf));
-        }
-    }
-
-    SharedSurface* Surf() const {
-        MOZ_ASSERT(mSurf.get());
-        return mSurf.get();
-    }
+    bool Recycle(layers::SharedSurfaceTextureClient* texClient);
 };
 
 class ScopedReadbackFB
 {
     GLContext* const mGL;
     ScopedBindFramebuffer mAutoFB;
     GLuint mTempFB;
     GLuint mTempTex;
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -1,19 +1,20 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* 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 "SharedSurfaceANGLE.h"
-#include "GLContextEGL.h"
-#include "GLLibraryEGL.h"
 
 #include <d3d11.h>
 #include "gfxWindowsPlatform.h"
+#include "GLContextEGL.h"
+#include "GLLibraryEGL.h"
+#include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 
 namespace mozilla {
 namespace gl {
 
 // Returns `EGL_NO_SURFACE` (`0`) on error.
 static EGLSurface
 CreatePBufferSurface(GLLibraryEGL* egl,
                      EGLDisplay display,
@@ -100,17 +101,18 @@ SharedSurface_ANGLEShareHandle::SharedSu
                                                                EGLSurface pbuffer,
                                                                HANDLE shareHandle,
                                                                const RefPtr<IDXGIKeyedMutex>& keyedMutex,
                                                                GLuint fence)
     : SharedSurface(SharedSurfaceType::EGLSurfaceANGLE,
                     AttachmentType::Screen,
                     gl,
                     size,
-                    hasAlpha)
+                    hasAlpha,
+                    true)
     , mEGL(egl)
     , mContext(context)
     , mPBuffer(pbuffer)
     , mShareHandle(shareHandle)
     , mKeyedMutex(keyedMutex)
     , mFence(fence)
 {
 }
@@ -248,16 +250,26 @@ SharedSurface_ANGLEShareHandle::PollSync
     if (mFence) {
         mGL->MakeCurrent();
         return mGL->fTestFence(mFence);
     }
 
     return PollSync();
 }
 
+bool
+SharedSurface_ANGLEShareHandle::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+    gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
+                                          : gfx::SurfaceFormat::B8G8R8X8;
+    *out_descriptor = layers::SurfaceDescriptorD3D10((WindowsHandle)mShareHandle, format,
+                                                     mSize);
+    return true;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Factory
 
 static void
 FillPBufferAttribs_ByBits(nsTArray<EGLint>& aAttrs,
                           int redBits, int greenBits,
                           int blueBits, int alphaBits,
                           int depthBits, int stencilBits)
@@ -383,42 +395,45 @@ ChooseConfig(GLContext* gl, GLLibraryEGL
     if (gl->DebugMode()) {
         egl->DumpEGLConfig(config);
     }
 
     return config;
 }
 
 /*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
-SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
-                                        const SurfaceCaps& caps)
+SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
+                                        const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                        const layers::TextureFlags& flags)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
     if (!egl)
         return nullptr;
 
     auto ext = GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle;
     if (!egl->IsExtensionSupported(ext))
         return nullptr;
 
     bool success;
     typedef SurfaceFactory_ANGLEShareHandle ptrT;
-    UniquePtr<ptrT> ret( new ptrT(gl, egl, caps, &success) );
+    UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, egl, &success) );
 
     if (!success)
         return nullptr;
 
     return Move(ret);
 }
 
 SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
+                                                                 const SurfaceCaps& caps,
+                                                                 const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                                 const layers::TextureFlags& flags,
                                                                  GLLibraryEGL* egl,
-                                                                 const SurfaceCaps& caps,
                                                                  bool* const out_success)
-    : SurfaceFactory(gl, SharedSurfaceType::EGLSurfaceANGLE, caps)
+    : SurfaceFactory(SharedSurfaceType::EGLSurfaceANGLE, gl, caps, allocator, flags)
     , mProdGL(gl)
     , mEGL(egl)
 {
     MOZ_ASSERT(out_success);
     *out_success = false;
 
     mContext = GLContextEGL::Cast(mProdGL)->GetEGLContext();
     mConfig = ChooseConfig(mProdGL, mEGL, mReadCaps);
--- a/gfx/gl/SharedSurfaceANGLE.h
+++ b/gfx/gl/SharedSurfaceANGLE.h
@@ -33,17 +33,19 @@ public:
 
         return (SharedSurface_ANGLEShareHandle*)surf;
     }
 
 protected:
     GLLibraryEGL* const mEGL;
     const EGLContext mContext;
     const EGLSurface mPBuffer;
+public:
     const HANDLE mShareHandle;
+protected:
     RefPtr<IDXGIKeyedMutex> mKeyedMutex;
     RefPtr<IDXGIKeyedMutex> mConsumerKeyedMutex;
     RefPtr<ID3D11Texture2D> mConsumerTexture;
 
     const GLuint mFence;
 
     SharedSurface_ANGLEShareHandle(GLContext* gl,
                                    GLLibraryEGL* egl,
@@ -70,45 +72,44 @@ public:
     virtual void ConsumerReleaseImpl() override;
     virtual bool WaitSync() override;
     virtual bool PollSync() override;
 
     virtual void Fence_ContentThread_Impl() override;
     virtual bool WaitSync_ContentThread_Impl() override;
     virtual bool PollSync_ContentThread_Impl() override;
 
-    // Implementation-specific functions below:
-    HANDLE GetShareHandle() {
-        return mShareHandle;
-    }
-
     const RefPtr<ID3D11Texture2D>& GetConsumerTexture() const {
         return mConsumerTexture;
     }
+
+    virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
 };
 
 
 
 class SurfaceFactory_ANGLEShareHandle
     : public SurfaceFactory
 {
 protected:
     GLContext* const mProdGL;
     GLLibraryEGL* const mEGL;
     EGLContext mContext;
     EGLConfig mConfig;
 
 public:
     static UniquePtr<SurfaceFactory_ANGLEShareHandle> Create(GLContext* gl,
-                                                             const SurfaceCaps& caps);
+                                                             const SurfaceCaps& caps,
+                                                             const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                             const layers::TextureFlags& flags);
 
 protected:
-    SurfaceFactory_ANGLEShareHandle(GLContext* gl,
-                                    GLLibraryEGL* egl,
-                                    const SurfaceCaps& caps,
+    SurfaceFactory_ANGLEShareHandle(GLContext* gl, const SurfaceCaps& caps,
+                                    const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                    const layers::TextureFlags& flags, GLLibraryEGL* egl,
                                     bool* const out_success);
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
         bool hasAlpha = mReadCaps.alpha;
         return SharedSurface_ANGLEShareHandle::Create(mProdGL,
                                                       mContext, mConfig,
                                                       size, hasAlpha);
     }
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SharedSurfaceEGL.h"
 
 #include "GLBlitHelper.h"
 #include "GLContextEGL.h"
 #include "GLLibraryEGL.h"
 #include "GLReadTexImageHelper.h"
+#include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "ScopedGLHelpers.h"
 #include "SharedSurface.h"
 #include "TextureGarbageBin.h"
 
 namespace mozilla {
 namespace gl {
 
 /*static*/ UniquePtr<SharedSurface_EGLImage>
@@ -67,17 +68,18 @@ SharedSurface_EGLImage::SharedSurface_EG
                                                bool hasAlpha,
                                                const GLFormats& formats,
                                                GLuint prodTex,
                                                EGLImage image)
     : SharedSurface(SharedSurfaceType::EGLImageShare,
                     AttachmentType::GLTexture,
                     gl,
                     size,
-                    hasAlpha)
+                    hasAlpha,
+                    false) // Can't recycle, as mSync changes never update TextureHost.
     , mMutex("SharedSurface_EGLImage mutex")
     , mEGL(egl)
     , mFormats(formats)
     , mProdTex(prodTex)
     , mImage(image)
     , mCurConsGL(nullptr)
     , mConsTex(0)
     , mSync(0)
@@ -210,28 +212,38 @@ SharedSurface_EGLImage::AcquireConsumerT
         mGarbageBin = consGL->TexGarbageBin();
     }
 
     MOZ_ASSERT(consGL == mCurConsGL);
     *out_texture = mConsTex;
     *out_target = LOCAL_GL_TEXTURE_EXTERNAL;
 }
 
+bool
+SharedSurface_EGLImage::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+    *out_descriptor = layers::EGLImageDescriptor((uintptr_t)mImage, (uintptr_t)mSync,
+                                                 mSize);
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////
 
 /*static*/ UniquePtr<SurfaceFactory_EGLImage>
-SurfaceFactory_EGLImage::Create(GLContext* prodGL,
-                                const SurfaceCaps& caps)
+SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
+                                const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                const layers::TextureFlags& flags)
 {
     EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext();
 
     typedef SurfaceFactory_EGLImage ptrT;
     UniquePtr<ptrT> ret;
 
     GLLibraryEGL* egl = &sEGLLibrary;
     if (SharedSurface_EGLImage::HasExtensions(egl, prodGL)) {
-        ret.reset( new ptrT(prodGL, context, caps) );
+        ret.reset( new ptrT(prodGL, caps, allocator, flags, context) );
     }
 
     return Move(ret);
 }
 
 } /* namespace gfx */
 } /* namespace mozilla */
--- a/gfx/gl/SharedSurfaceEGL.h
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -72,37 +72,42 @@ public:
 
     virtual GLuint ProdTexture() override {
       return mProdTex;
     }
 
     // Implementation-specific functions below:
     // Returns texture and target
     void AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target);
+
+    virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
 };
 
 
 
 class SurfaceFactory_EGLImage
     : public SurfaceFactory
 {
 public:
     // Fallible:
     static UniquePtr<SurfaceFactory_EGLImage> Create(GLContext* prodGL,
-                                                     const SurfaceCaps& caps);
+                                                     const SurfaceCaps& caps,
+                                                     const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                     const layers::TextureFlags& flags);
 
 protected:
     const EGLContext mContext;
 
-    SurfaceFactory_EGLImage(GLContext* prodGL,
-                            EGLContext context,
-                            const SurfaceCaps& caps)
-        : SurfaceFactory(prodGL, SharedSurfaceType::EGLImageShare, caps)
+    SurfaceFactory_EGLImage(GLContext* prodGL, const SurfaceCaps& caps,
+                            const RefPtr<layers::ISurfaceAllocator>& allocator,
+                            const layers::TextureFlags& flags,
+                            EGLContext context)
+        : SurfaceFactory(SharedSurfaceType::EGLImageShare, prodGL, caps, allocator, flags)
         , mContext(context)
-    {}
+    { }
 
 public:
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
         bool hasAlpha = mReadCaps.alpha;
         return SharedSurface_EGLImage::Create(mGL, mFormats, size, hasAlpha, mContext);
     }
 };
 
--- a/gfx/gl/SharedSurfaceGL.cpp
+++ b/gfx/gl/SharedSurfaceGL.cpp
@@ -34,50 +34,47 @@ SharedSurface_Basic::Create(GLContext* g
 
     GLenum err = localError.GetError();
     MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
     if (err) {
         gl->fDeleteTextures(1, &tex);
         return Move(ret);
     }
 
-    SurfaceFormat format = SurfaceFormat::B8G8R8X8;
-    switch (formats.color_texInternalFormat) {
-    case LOCAL_GL_RGB:
-    case LOCAL_GL_RGB8:
-        if (formats.color_texType == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
-            format = SurfaceFormat::R5G6B5;
-        else
-            format = SurfaceFormat::B8G8R8X8;
-        break;
-    case LOCAL_GL_RGBA:
-    case LOCAL_GL_RGBA8:
-    case LOCAL_GL_BGRA:
-    case LOCAL_GL_BGRA8_EXT:
-        format = SurfaceFormat::B8G8R8A8;
-        break;
-    default:
-        MOZ_CRASH("Unhandled Tex format.");
-    }
+    bool ownsTex = true;
+    ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, tex, ownsTex) );
+    return Move(ret);
+}
+
 
-    ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, format, tex) );
+/*static*/ UniquePtr<SharedSurface_Basic>
+SharedSurface_Basic::Wrap(GLContext* gl,
+                          const IntSize& size,
+                          bool hasAlpha,
+                          GLuint tex)
+{
+    bool ownsTex = false;
+    UniquePtr<SharedSurface_Basic> ret( new SharedSurface_Basic(gl, size, hasAlpha, tex,
+                                                                ownsTex) );
     return Move(ret);
 }
 
 SharedSurface_Basic::SharedSurface_Basic(GLContext* gl,
                                          const IntSize& size,
                                          bool hasAlpha,
-                                         SurfaceFormat format,
-                                         GLuint tex)
+                                         GLuint tex,
+                                         bool ownsTex)
     : SharedSurface(SharedSurfaceType::Basic,
                     AttachmentType::GLTexture,
                     gl,
                     size,
-                    hasAlpha)
+                    hasAlpha,
+                    true)
     , mTex(tex)
+    , mOwnsTex(ownsTex)
     , mFB(0)
 {
     mGL->MakeCurrent();
     mGL->fGenFramebuffers(1, &mFB);
 
     ScopedBindFramebuffer autoFB(mGL, mFB);
     mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
                               LOCAL_GL_COLOR_ATTACHMENT0,
@@ -92,155 +89,21 @@ SharedSurface_Basic::SharedSurface_Basic
 SharedSurface_Basic::~SharedSurface_Basic()
 {
     if (!mGL->MakeCurrent())
         return;
 
     if (mFB)
         mGL->fDeleteFramebuffers(1, &mFB);
 
-    mGL->fDeleteTextures(1, &mTex);
+    if (mOwnsTex)
+        mGL->fDeleteTextures(1, &mTex);
 }
 
 ////////////////////////////////////////////////////////////////////////
-// SharedSurface_GLTexture
 
-/*static*/ UniquePtr<SharedSurface_GLTexture>
-SharedSurface_GLTexture::Create(GLContext* prodGL,
-                                GLContext* consGL,
-                                const GLFormats& formats,
-                                const IntSize& size,
-                                bool hasAlpha,
-                                GLuint texture)
-{
-    MOZ_ASSERT(prodGL);
-    MOZ_ASSERT(!consGL || prodGL->SharesWith(consGL));
-
-    prodGL->MakeCurrent();
-
-    GLuint tex = texture;
-
-    bool ownsTex = false;
-
-    UniquePtr<SharedSurface_GLTexture> ret;
-
-    if (!tex) {
-        GLContext::LocalErrorScope localError(*prodGL);
-
-        tex = CreateTextureForOffscreen(prodGL, formats, size);
-
-        GLenum err = localError.GetError();
-        MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
-        if (err) {
-            prodGL->fDeleteTextures(1, &tex);
-            return Move(ret);
-        }
-
-        ownsTex = true;
-    }
-
-    ret.reset( new SharedSurface_GLTexture(prodGL, consGL, size,
-                                           hasAlpha, tex, ownsTex) );
-    return Move(ret);
-}
-
-SharedSurface_GLTexture::~SharedSurface_GLTexture()
-{
-    if (!mGL->MakeCurrent())
-        return;
-
-    if (mOwnsTex) {
-        mGL->fDeleteTextures(1, &mTex);
-    }
-
-    if (mSync) {
-        mGL->fDeleteSync(mSync);
-    }
-}
-
-void
-SharedSurface_GLTexture::Fence()
-{
-    MutexAutoLock lock(mMutex);
-    mGL->MakeCurrent();
-
-    if (mConsGL && mGL->IsExtensionSupported(GLContext::ARB_sync)) {
-        if (mSync) {
-            mGL->fDeleteSync(mSync);
-            mSync = 0;
-        }
-
-        mSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-        if (mSync) {
-            mGL->fFlush();
-            return;
-        }
-    }
-    MOZ_ASSERT(!mSync);
-
-    mGL->fFinish();
-}
-
-bool
-SharedSurface_GLTexture::WaitSync()
-{
-    MutexAutoLock lock(mMutex);
-    if (!mSync) {
-        // We either used glFinish, or we passed this fence already.
-        // (PollSync/WaitSync returned true previously)
-        return true;
-    }
-
-    mConsGL->MakeCurrent();
-    MOZ_ASSERT(mConsGL->IsExtensionSupported(GLContext::ARB_sync));
-
-    mConsGL->fWaitSync(mSync,
-                       0,
-                       LOCAL_GL_TIMEOUT_IGNORED);
-    mConsGL->fDeleteSync(mSync);
-    mSync = 0;
-
-    return true;
-}
-
-bool
-SharedSurface_GLTexture::PollSync()
-{
-    MutexAutoLock lock(mMutex);
-    if (!mSync) {
-        // We either used glFinish, or we passed this fence already.
-        // (PollSync/WaitSync returned true previously)
-        return true;
-    }
-
-    mConsGL->MakeCurrent();
-    MOZ_ASSERT(mConsGL->IsExtensionSupported(GLContext::ARB_sync));
-
-    GLint status = 0;
-    mConsGL->fGetSynciv(mSync,
-                        LOCAL_GL_SYNC_STATUS,
-                        1,
-                        nullptr,
-                        &status);
-    if (status != LOCAL_GL_SIGNALED)
-        return false;
-
-    mConsGL->fDeleteSync(mSync);
-    mSync = 0;
-
-    return true;
-}
-
-GLuint
-SharedSurface_GLTexture::ConsTexture(GLContext* consGL)
-{
-    MutexAutoLock lock(mMutex);
-    MOZ_ASSERT(consGL);
-    MOZ_ASSERT(mGL->SharesWith(consGL));
-    MOZ_ASSERT_IF(mConsGL, consGL == mConsGL);
-
-    mConsGL = consGL;
-
-    return mTex;
-}
+SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
+                                           const layers::TextureFlags& flags)
+    : SurfaceFactory(SharedSurfaceType::Basic, gl, caps, nullptr, flags)
+{ }
 
 } /* namespace gfx */
 } /* namespace mozilla */
--- a/gfx/gl/SharedSurfaceGL.h
+++ b/gfx/gl/SharedSurfaceGL.h
@@ -33,150 +33,67 @@ class SharedSurface_Basic
     : public SharedSurface
 {
 public:
     static UniquePtr<SharedSurface_Basic> Create(GLContext* gl,
                                                  const GLFormats& formats,
                                                  const gfx::IntSize& size,
                                                  bool hasAlpha);
 
+    static UniquePtr<SharedSurface_Basic> Wrap(GLContext* gl,
+                                               const gfx::IntSize& size,
+                                               bool hasAlpha,
+                                               GLuint tex);
+
     static SharedSurface_Basic* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->mType == SharedSurfaceType::Basic);
 
         return (SharedSurface_Basic*)surf;
     }
 
 protected:
     const GLuint mTex;
+    const bool mOwnsTex;
     GLuint mFB;
 
     SharedSurface_Basic(GLContext* gl,
                         const gfx::IntSize& size,
                         bool hasAlpha,
-                        gfx::SurfaceFormat format,
-                        GLuint tex);
+                        GLuint tex,
+                        bool ownsTex);
 
 public:
     virtual ~SharedSurface_Basic();
 
     virtual void LockProdImpl() override {}
     virtual void UnlockProdImpl() override {}
 
     virtual void Fence() override {}
     virtual bool WaitSync() override { return true; }
     virtual bool PollSync() override { return true; }
 
     virtual GLuint ProdTexture() override {
         return mTex;
     }
+
+    virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override {
+        MOZ_CRASH("don't do this");
+        return false;
+    }
 };
 
 class SurfaceFactory_Basic
     : public SurfaceFactory
 {
 public:
-    SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps)
-        : SurfaceFactory(gl, SharedSurfaceType::Basic, caps)
-    {}
+    SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
+                         const layers::TextureFlags& flags);
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
         bool hasAlpha = mReadCaps.alpha;
         return SharedSurface_Basic::Create(mGL, mFormats, size, hasAlpha);
     }
 };
 
-
-// Using shared GL textures:
-class SharedSurface_GLTexture
-    : public SharedSurface
-{
-public:
-    static UniquePtr<SharedSurface_GLTexture> Create(GLContext* prodGL,
-                                                     GLContext* consGL,
-                                                     const GLFormats& formats,
-                                                     const gfx::IntSize& size,
-                                                     bool hasAlpha,
-                                                     GLuint texture = 0);
-
-    static SharedSurface_GLTexture* Cast(SharedSurface* surf) {
-        MOZ_ASSERT(surf->mType == SharedSurfaceType::GLTextureShare);
-
-        return (SharedSurface_GLTexture*)surf;
-    }
-
-protected:
-    GLContext* mConsGL;
-    const GLuint mTex;
-    const bool mOwnsTex;
-    GLsync mSync;
-    mutable Mutex mMutex;
-
-    SharedSurface_GLTexture(GLContext* prodGL,
-                            GLContext* consGL,
-                            const gfx::IntSize& size,
-                            bool hasAlpha,
-                            GLuint tex,
-                            bool ownsTex)
-        : SharedSurface(SharedSurfaceType::GLTextureShare,
-                        AttachmentType::GLTexture,
-                        prodGL,
-                        size,
-                        hasAlpha)
-        , mConsGL(consGL)
-        , mTex(tex)
-        , mOwnsTex(ownsTex)
-        , mSync(0)
-        , mMutex("SharedSurface_GLTexture mutex")
-    {
-    }
-
-public:
-    virtual ~SharedSurface_GLTexture();
-
-    virtual void LockProdImpl() override {}
-    virtual void UnlockProdImpl() override {}
-
-    virtual void Fence() override;
-    virtual bool WaitSync() override;
-    virtual bool PollSync() override;
-
-    virtual GLuint ProdTexture() override {
-        return mTex;
-    }
-
-    // Custom:
-
-    GLuint ConsTexture(GLContext* consGL);
-
-    GLenum ConsTextureTarget() const {
-        return ProdTextureTarget();
-    }
-};
-
-class SurfaceFactory_GLTexture
-    : public SurfaceFactory
-{
-protected:
-    GLContext* const mConsGL;
-
-public:
-    // If we don't know `consGL` at construction time, use `nullptr`, and call
-    // `SetConsumerGL()` on each `SharedSurface_GLTexture` before calling its
-    // `WaitSync()`.
-    SurfaceFactory_GLTexture(GLContext* prodGL,
-                             GLContext* consGL,
-                             const SurfaceCaps& caps)
-        : SurfaceFactory(prodGL, SharedSurfaceType::GLTextureShare, caps)
-        , mConsGL(consGL)
-    {
-        MOZ_ASSERT(consGL != prodGL);
-    }
-
-    virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
-        bool hasAlpha = mReadCaps.alpha;
-        return SharedSurface_GLTexture::Create(mGL, mConsGL, mFormats, size, hasAlpha);
-    }
-};
-
 } /* namespace gfx */
 } /* namespace mozilla */
 
 #endif /* SHARED_SURFACE_GL_H_ */
--- a/gfx/gl/SharedSurfaceGralloc.cpp
+++ b/gfx/gl/SharedSurfaceGralloc.cpp
@@ -30,23 +30,20 @@
 #endif
 
 namespace mozilla {
 namespace gl {
 
 using namespace mozilla::layers;
 using namespace android;
 
-SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL,
-                                               const SurfaceCaps& caps,
-                                               layers::TextureFlags flags,
-                                               layers::ISurfaceAllocator* allocator)
-    : SurfaceFactory(prodGL, SharedSurfaceType::Gralloc, caps)
-    , mFlags(flags)
-    , mAllocator(allocator)
+SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps,
+                                               const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                               const layers::TextureFlags& flags)
+    : SurfaceFactory(SharedSurfaceType::Gralloc, prodGL, caps, allocator, flags)
 {
     MOZ_ASSERT(mAllocator);
 }
 
 /*static*/ UniquePtr<SharedSurface_Gralloc>
 SharedSurface_Gralloc::Create(GLContext* prodGL,
                               const GLFormats& formats,
                               const gfx::IntSize& size,
@@ -127,17 +124,18 @@ SharedSurface_Gralloc::SharedSurface_Gra
                                              GLLibraryEGL* egl,
                                              layers::ISurfaceAllocator* allocator,
                                              layers::GrallocTextureClientOGL* textureClient,
                                              GLuint prodTex)
     : SharedSurface(SharedSurfaceType::Gralloc,
                     AttachmentType::GLTexture,
                     prodGL,
                     size,
-                    hasAlpha)
+                    hasAlpha,
+                    true)
     , mEGL(egl)
     , mSync(0)
     , mAllocator(allocator)
     , mTextureClient(textureClient)
     , mProdTex(prodTex)
 {
 }
 
@@ -279,10 +277,16 @@ SharedSurface_Gralloc::PollSync()
 }
 
 void
 SharedSurface_Gralloc::WaitForBufferOwnership()
 {
     mTextureClient->WaitForBufferOwnership();
 }
 
+bool
+SharedSurface_Gralloc::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+    return mTextureClient->ToSurfaceDescriptor(*out_descriptor);
 }
-}
+
+} // namespace gl
+} // namespace mozilla
--- a/gfx/gl/SharedSurfaceGralloc.h
+++ b/gfx/gl/SharedSurfaceGralloc.h
@@ -68,30 +68,27 @@ public:
 
     virtual GLuint ProdTexture() override {
         return mProdTex;
     }
 
     layers::GrallocTextureClientOGL* GetTextureClient() {
         return mTextureClient;
     }
+
+    virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
 };
 
 class SurfaceFactory_Gralloc
     : public SurfaceFactory
 {
-protected:
-    const layers::TextureFlags mFlags;
-    RefPtr<layers::ISurfaceAllocator> mAllocator;
-
 public:
-    SurfaceFactory_Gralloc(GLContext* prodGL,
-                           const SurfaceCaps& caps,
-                           layers::TextureFlags flags,
-                           layers::ISurfaceAllocator* allocator);
+    SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps,
+                           const RefPtr<layers::ISurfaceAllocator>& allocator,
+                           const layers::TextureFlags& flags);
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
         bool hasAlpha = mReadCaps.alpha;
 
         UniquePtr<SharedSurface> ret;
         if (mAllocator) {
             ret = SharedSurface_Gralloc::Create(mGL, mFormats, size, hasAlpha,
                                                 mFlags, mAllocator);
--- a/gfx/gl/SharedSurfaceIO.cpp
+++ b/gfx/gl/SharedSurfaceIO.cpp
@@ -1,18 +1,19 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* 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 "SharedSurfaceIO.h"
 
 #include "GLContextCGL.h"
+#include "mozilla/DebugOnly.h"
 #include "mozilla/gfx/MacIOSurface.h"
-#include "mozilla/DebugOnly.h"
+#include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "ScopedGLHelpers.h"
 
 namespace mozilla {
 namespace gl {
 
 /*static*/ UniquePtr<SharedSurface_IOSurface>
 SharedSurface_IOSurface::Create(const RefPtr<MacIOSurface>& ioSurf,
                                 GLContext* gl,
@@ -147,17 +148,18 @@ BackTextureWithIOSurf(GLContext* gl, GLu
 SharedSurface_IOSurface::SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
                                                  GLContext* gl,
                                                  const gfx::IntSize& size,
                                                  bool hasAlpha)
   : SharedSurface(SharedSurfaceType::IOSurface,
                   AttachmentType::GLTexture,
                   gl,
                   size,
-                  hasAlpha)
+                  hasAlpha,
+                  true)
   , mIOSurf(ioSurf)
 {
     gl->MakeCurrent();
     mProdTex = 0;
     gl->fGenTextures(1, &mProdTex);
     BackTextureWithIOSurf(gl, mProdTex, mIOSurf);
 }
 
@@ -165,28 +167,39 @@ SharedSurface_IOSurface::~SharedSurface_
 {
     if (mProdTex) {
         DebugOnly<bool> success = mGL->MakeCurrent();
         MOZ_ASSERT(success);
         mGL->fDeleteTextures(1, &mProdTex);
     }
 }
 
+bool
+SharedSurface_IOSurface::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+    bool isOpaque = !mHasAlpha;
+    *out_descriptor = layers::SurfaceDescriptorMacIOSurface(mIOSurf->GetIOSurfaceID(),
+                                                            mIOSurf->GetContentsScaleFactor(),
+                                                            isOpaque);
+    return true;
+}
+
 ////////////////////////////////////////////////////////////////////////
 // SurfaceFactory_IOSurface
 
 /*static*/ UniquePtr<SurfaceFactory_IOSurface>
-SurfaceFactory_IOSurface::Create(GLContext* gl,
-                                 const SurfaceCaps& caps)
+SurfaceFactory_IOSurface::Create(GLContext* gl, const SurfaceCaps& caps,
+                                 const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                 const layers::TextureFlags& flags)
 {
     gfx::IntSize maxDims(MacIOSurface::GetMaxWidth(),
                          MacIOSurface::GetMaxHeight());
 
     typedef SurfaceFactory_IOSurface ptrT;
-    UniquePtr<ptrT> ret( new ptrT(gl, caps, maxDims) );
+    UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, maxDims) );
     return Move(ret);
 }
 
 UniquePtr<SharedSurface>
 SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size)
 {
     if (size.width > mMaxDims.width ||
         size.height > mMaxDims.height)
--- a/gfx/gl/SharedSurfaceIO.h
+++ b/gfx/gl/SharedSurfaceIO.h
@@ -11,21 +11,31 @@
 
 class MacIOSurface;
 
 namespace mozilla {
 namespace gl {
 
 class SharedSurface_IOSurface : public SharedSurface
 {
+private:
+    const RefPtr<MacIOSurface> mIOSurf;
+    GLuint mProdTex;
+
 public:
     static UniquePtr<SharedSurface_IOSurface> Create(const RefPtr<MacIOSurface>& ioSurf,
                                                      GLContext* gl,
                                                      bool hasAlpha);
 
+private:
+    SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
+                            GLContext* gl, const gfx::IntSize& size,
+                            bool hasAlpha);
+
+public:
     ~SharedSurface_IOSurface();
 
     virtual void LockProdImpl() override { }
     virtual void UnlockProdImpl() override { }
 
     virtual void Fence() override;
     virtual bool WaitSync() override { return true; }
     virtual bool PollSync() override { return true; }
@@ -52,41 +62,37 @@ public:
     MacIOSurface* GetIOSurface() const {
         return mIOSurf;
     }
 
     virtual bool NeedsIndirectReads() const override {
         return true;
     }
 
-private:
-    SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
-                            GLContext* gl, const gfx::IntSize& size,
-                            bool hasAlpha);
-
-    RefPtr<MacIOSurface> mIOSurf;
-    GLuint mProdTex;
+    virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
 };
 
 class SurfaceFactory_IOSurface : public SurfaceFactory
 {
 public:
     // Infallible.
     static UniquePtr<SurfaceFactory_IOSurface> Create(GLContext* gl,
-                                                      const SurfaceCaps& caps);
+                                                      const SurfaceCaps& caps,
+                                                      const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                      const layers::TextureFlags& flags);
 protected:
     const gfx::IntSize mMaxDims;
 
-    SurfaceFactory_IOSurface(GLContext* gl,
-                             const SurfaceCaps& caps,
+    SurfaceFactory_IOSurface(GLContext* gl, const SurfaceCaps& caps,
+                             const RefPtr<layers::ISurfaceAllocator>& allocator,
+                             const layers::TextureFlags& flags,
                              const gfx::IntSize& maxDims)
-        : SurfaceFactory(gl, SharedSurfaceType::IOSurface, caps)
+        : SurfaceFactory(SharedSurfaceType::IOSurface, gl, caps, allocator, flags)
         , mMaxDims(maxDims)
-    {
-    }
+    { }
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
 };
 
 } /* namespace gfx */
 } /* namespace mozilla */
 
 #endif /* SHARED_SURFACEIO_H_ */
--- a/gfx/gl/SurfaceTypes.h
+++ b/gfx/gl/SurfaceTypes.h
@@ -65,17 +65,16 @@ struct SurfaceCaps final
         return caps;
     }
 };
 
 enum class SharedSurfaceType : uint8_t {
     Unknown = 0,
 
     Basic,
-    GLTextureShare,
     EGLImageShare,
     EGLSurfaceANGLE,
     DXGLInterop,
     DXGLInterop2,
     Gralloc,
     IOSurface,
 
     Max
--- a/gfx/layers/AtomicRefCountedWithFinalize.h
+++ b/gfx/layers/AtomicRefCountedWithFinalize.h
@@ -7,56 +7,117 @@
 #define MOZILLA_ATOMICREFCOUNTEDWITHFINALIZE_H_
 
 #include "mozilla/RefPtr.h"
 #include "mozilla/Likely.h"
 #include "MainThreadUtils.h"
 #include "base/message_loop.h"
 #include "base/task.h"
 
+#define ADDREF_MANUALLY(obj)  (obj)->AddRefManually(__FUNCTION__, __FILE__, __LINE__)
+#define RELEASE_MANUALLY(obj)  (obj)->ReleaseManually(__FUNCTION__, __FILE__, __LINE__)
+
 namespace mozilla {
 
+template<class U>
+class StaticRefPtr;
+
 template<typename T>
 class AtomicRefCountedWithFinalize
 {
-  protected:
+protected:
     AtomicRefCountedWithFinalize()
       : mRecycleCallback(nullptr)
       , mRefCount(0)
       , mMessageLoopToPostDestructionTo(nullptr)
+#ifdef DEBUG
+      , mSpew(false)
+      , mManualAddRefs(0)
+      , mManualReleases(0)
+#endif
     {}
 
     ~AtomicRefCountedWithFinalize() {}
 
     void SetMessageLoopToPostDestructionTo(MessageLoop* l) {
       MOZ_ASSERT(NS_IsMainThread());
       mMessageLoopToPostDestructionTo = l;
     }
 
     static void DestroyToBeCalledOnMainThread(T* ptr) {
       MOZ_ASSERT(NS_IsMainThread());
       delete ptr;
     }
 
-  public:
+public:
+    // Mark user classes that are considered flawless.
+    template<typename U>
+    friend class RefPtr;
+
+    template<class U>
+    friend class ::mozilla::StaticRefPtr;
+
+    template<typename U>
+    friend class TemporaryRef;
+
+    template<class U>
+    friend class ::nsRefPtr;
+
+    template<class U>
+    friend struct ::RunnableMethodTraits;
+
+    //friend class mozilla::gl::SurfaceFactory;
+
+    void AddRefManually(const char* funcName, const char* fileName, uint32_t lineNum) {
+#ifdef DEBUG
+      uint32_t count = ++mManualAddRefs;
+      if (mSpew) {
+        printf_stderr("AddRefManually() #%u in %s at %s:%u\n", count, funcName,
+                      fileName, lineNum);
+      }
+#else
+      (void)funcName;
+      (void)fileName;
+      (void)lineNum;
+#endif
+      AddRef();
+    }
+
+    void ReleaseManually(const char* funcName, const char* fileName, uint32_t lineNum) {
+#ifdef DEBUG
+      uint32_t count = ++mManualReleases;
+      if (mSpew) {
+        printf_stderr("ReleaseManually() #%u in %s at %s:%u\n", count, funcName,
+                      fileName, lineNum);
+      }
+#else
+      (void)funcName;
+      (void)fileName;
+      (void)lineNum;
+#endif
+      Release();
+    }
+
+private:
     void AddRef() {
-      MOZ_ASSERT(mRefCount >= 0);
+      MOZ_ASSERT(mRefCount >= 0, "AddRef() during/after Finalize()/dtor.");
       ++mRefCount;
     }
 
     void Release() {
-      MOZ_ASSERT(mRefCount > 0);
+      MOZ_ASSERT(mRefCount > 0, "Release() during/after Finalize()/dtor.");
       // Read mRecycleCallback early so that it does not get set to
       // deleted memory, if the object is goes away.
       RecycleCallback recycleCallback = mRecycleCallback;
       int currCount = --mRefCount;
       if (0 == currCount) {
         // Recycle listeners must call ClearRecycleCallback
         // before releasing their strong reference.
         MOZ_ASSERT(mRecycleCallback == nullptr);
+        MOZ_ASSERT(mManualAddRefs == mManualReleases);
 #ifdef DEBUG
         mRefCount = detail::DEAD;
 #endif
         T* derived = static_cast<T*>(this);
         derived->Finalize();
         if (MOZ_LIKELY(!mMessageLoopToPostDestructionTo)) {
           delete derived;
         } else {
@@ -69,16 +130,17 @@ class AtomicRefCountedWithFinalize
           }
         }
       } else if (1 == currCount && recycleCallback) {
         T* derived = static_cast<T*>(this);
         recycleCallback(derived, mClosure);
       }
     }
 
+public:
     typedef void (*RecycleCallback)(T* aObject, void* aClosure);
     /**
      * Set a callback responsible for recycling this object
      * before it is finalized.
      */
     void SetRecycleCallback(RecycleCallback aCallback, void* aClosure)
     {
       mRecycleCallback = aCallback;
@@ -91,13 +153,20 @@ class AtomicRefCountedWithFinalize
       return !!mRecycleCallback;
     }
 
 private:
     RecycleCallback mRecycleCallback;
     void *mClosure;
     Atomic<int> mRefCount;
     MessageLoop *mMessageLoopToPostDestructionTo;
+#ifdef DEBUG
+public:
+    bool mSpew;
+private:
+    Atomic<uint32_t> mManualAddRefs;
+    Atomic<uint32_t> mManualReleases;
+#endif
 };
 
-}
+} // namespace mozilla
 
 #endif
--- a/gfx/layers/CopyableCanvasLayer.cpp
+++ b/gfx/layers/CopyableCanvasLayer.cpp
@@ -1,31 +1,33 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "CopyableCanvasLayer.h"
+
 #include "BasicLayersImpl.h"            // for FillWithMask, etc
-#include "CopyableCanvasLayer.h"
 #include "GLContext.h"                  // for GLContext
 #include "GLScreenBuffer.h"             // for GLScreenBuffer
 #include "SharedSurface.h"              // for SharedSurface
 #include "SharedSurfaceGL.h"              // for SharedSurface
 #include "gfxPattern.h"                 // for gfxPattern, etc
 #include "gfxPlatform.h"                // for gfxPlatform, gfxImageFormat
 #include "gfxRect.h"                    // for gfxRect
 #include "gfxUtils.h"                   // for gfxUtils
 #include "gfx2DGlue.h"                  // for thebes --> moz2d transition
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Tools.h"
 #include "nsDebug.h"                    // for NS_ASSERTION, NS_WARNING, etc
 #include "nsISupportsImpl.h"            // for gfxContext::AddRef, etc
 #include "nsRect.h"                     // for nsIntRect
 #include "nsSize.h"                     // for nsIntSize
 #include "gfxUtils.h"
+#include "client/TextureClientSharedSurface.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 
 CopyableCanvasLayer::CopyableCanvasLayer(LayerManager* aLayerManager, void *aImplData) :
@@ -51,21 +53,18 @@ CopyableCanvasLayer::Initialize(const Da
     mGLContext = aData.mGLContext;
     mIsAlphaPremultiplied = aData.mIsGLAlphaPremult;
     mOriginPos = gl::OriginPos::BottomLeft;
 
     MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
 
     if (aData.mFrontbufferGLTex) {
       gfx::IntSize size(aData.mSize.width, aData.mSize.height);
-      mGLFrontbuffer = SharedSurface_GLTexture::Create(aData.mGLContext,
-                                                       nullptr,
-                                                       aData.mGLContext->GetGLFormats(),
-                                                       size, aData.mHasAlpha,
-                                                       aData.mFrontbufferGLTex);
+      mGLFrontbuffer = SharedSurface_Basic::Wrap(aData.mGLContext, size, aData.mHasAlpha,
+                                                 aData.mFrontbufferGLTex);
     }
   } else if (aData.mDrawTarget) {
     mDrawTarget = aData.mDrawTarget;
     mSurface = mDrawTarget->Snapshot();
   } else {
     MOZ_CRASH("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
   }
 
@@ -103,17 +102,17 @@ CopyableCanvasLayer::UpdateTarget(DrawTa
 
   MOZ_ASSERT(mGLContext);
 
   SharedSurface* frontbuffer = nullptr;
   if (mGLFrontbuffer) {
     frontbuffer = mGLFrontbuffer.get();
   } else {
     GLScreenBuffer* screen = mGLContext->Screen();
-    ShSurfHandle* front = screen->Front();
+    const auto& front = screen->Front();
     if (front) {
       frontbuffer = front->Surf();
     }
   }
 
   if (!frontbuffer) {
     NS_WARNING("Null frame received.");
     return;
@@ -132,17 +131,17 @@ CopyableCanvasLayer::UpdateTarget(DrawTa
     int32_t destStride;
     SurfaceFormat destFormat;
     if (aDestTarget->LockBits(&destData, &destSize, &destStride, &destFormat)) {
       if (destSize == readSize && destFormat == format) {
         RefPtr<DataSourceSurface> data =
           Factory::CreateWrappingDataSourceSurface(destData, destStride, destSize, destFormat);
         mGLContext->Readback(frontbuffer, data);
         if (needsPremult) {
-            gfxUtils::PremultiplyDataSurface(data, data);
+          gfxUtils::PremultiplyDataSurface(data, data);
         }
         aDestTarget->ReleaseBits(destData);
         return;
       }
       aDestTarget->ReleaseBits(destData);
     }
   }
 
--- a/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
+++ b/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
@@ -34,17 +34,17 @@ MacIOSurfaceTextureSourceBasic::GetForma
 }
 
 MacIOSurfaceTextureHostBasic::MacIOSurfaceTextureHostBasic(
     TextureFlags aFlags,
     const SurfaceDescriptorMacIOSurface& aDescriptor
 )
   : TextureHost(aFlags)
 {
-  mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
+  mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(),
                                          aDescriptor.scaleFactor(),
                                          !aDescriptor.isOpaque());
 }
 
 gfx::SourceSurface*
 MacIOSurfaceTextureSourceBasic::GetSurface(gfx::DrawTarget* aTarget)
 {
   if (!mSourceSurface) {
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -17,38 +17,29 @@
 #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
 #include "nsDebug.h"                    // for printf_stderr, NS_ASSERTION
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
-#ifdef MOZ_WIDGET_GONK
-#include "SharedSurfaceGralloc.h"
-#endif
+#include "TextureClientSharedSurface.h"
 
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 
 namespace mozilla {
 namespace layers {
 
 /* static */ TemporaryRef<CanvasClient>
 CanvasClient::CreateCanvasClient(CanvasClientType aType,
                                  CompositableForwarder* aForwarder,
                                  TextureFlags aFlags)
 {
-#ifndef MOZ_WIDGET_GONK
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
-    NS_WARNING("Most platforms still need an optimized way to share GL cross process.");
-    return new CanvasClient2D(aForwarder, aFlags);
-  }
-#endif
-
   switch (aType) {
   case CanvasClientTypeShSurf:
     return new CanvasClientSharedSurface(aForwarder, aFlags);
 
   default:
     return new CanvasClient2D(aForwarder, aFlags);
   }
 }
@@ -142,38 +133,21 @@ CanvasClient2D::CreateTextureClientForCa
 #endif
 }
 
 ////////////////////////////////////////////////////////////////////////
 
 CanvasClientSharedSurface::CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
                                                      TextureFlags aFlags)
   : CanvasClient(aLayerForwarder, aFlags)
-{
-}
+{ }
 
-////////////////////////////////////////
-// Accelerated backends
-
-static TemporaryRef<TextureClient>
-TexClientFromShSurf(ISurfaceAllocator* aAllocator, SharedSurface* surf,
-                    TextureFlags flags)
+CanvasClientSharedSurface::~CanvasClientSharedSurface()
 {
-  switch (surf->mType) {
-    case SharedSurfaceType::Basic:
-      return nullptr;
-
-#ifdef MOZ_WIDGET_GONK
-    case SharedSurfaceType::Gralloc:
-      return GrallocTextureClientOGL::FromSharedSurface(surf, flags);
-#endif
-
-    default:
-      return new SharedSurfaceTextureClient(aAllocator, flags, surf);
-  }
+  ClearSurfaces();
 }
 
 ////////////////////////////////////////
 // Readback
 
 // For formats compatible with R8G8B8A8.
 static inline void SwapRB_R8G8B8A8(uint8_t* pixel) {
   // [RR, GG, BB, AA]
@@ -323,96 +297,97 @@ TexClientFromReadback(SharedSurface* src
     texClient->Unlock();
   }
 
   return texClient.forget();
 }
 
 ////////////////////////////////////////
 
-static TemporaryRef<gl::ShSurfHandle>
+static TemporaryRef<SharedSurfaceTextureClient>
 CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory)
 {
-    RefPtr<gl::ShSurfHandle> dest = factory->NewShSurfHandle(src->mSize);
+    RefPtr<SharedSurfaceTextureClient> dest = factory->NewTexClient(src->mSize);
     if (!dest) {
-        return nullptr;
+      return nullptr;
     }
     SharedSurface::ProdCopy(src, dest->Surf(), factory);
+    dest->Surf()->Fence();
     return dest.forget();
 }
 
 void
 CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
 {
-  if (mFront) {
-    mPrevFront = mFront;
-    mFront = nullptr;
-  }
-
   auto gl = aLayer->mGLContext;
   gl->MakeCurrent();
 
+  RefPtr<TextureClient> newFront;
+
   if (aLayer->mGLFrontbuffer) {
-    mFront = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get());
-    if (mFront)
-      mFront->Surf()->Fence();
+    mShSurfClient = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get());
+    if (!mShSurfClient) {
+      gfxCriticalError() << "Invalid canvas front buffer";
+      return;
+    }
   } else {
-    mFront = gl->Screen()->Front();
+    mShSurfClient = gl->Screen()->Front();
+    if (!mShSurfClient) {
+      return;
+    }
   }
-  if (!mFront) {
-    gfxCriticalError() << "Invalid canvas front buffer";
-    return;
-  }
+  MOZ_ASSERT(mShSurfClient);
+
+  newFront = mShSurfClient;
+
+  SharedSurface* surf = mShSurfClient->Surf();
 
-  // Alright, now sort out the IPC goop.
-  SharedSurface* surf = mFront->Surf();
+  // Readback if needed.
+  mReadbackClient = nullptr;
+
   auto forwarder = GetForwarder();
-  auto flags = GetTextureFlags() | TextureFlags::IMMUTABLE;
 
-  // Get a TexClient from our surf.
-  RefPtr<TextureClient> newTex = TexClientFromShSurf(GetForwarder(), surf, flags);
-  if (!newTex) {
+  bool needsReadback = (surf->mType == SharedSurfaceType::Basic);
+  if (needsReadback) {
+    TextureFlags flags = aLayer->Flags() |
+                         TextureFlags::IMMUTABLE;
+
     auto manager = aLayer->ClientManager();
     auto shadowForwarder = manager->AsShadowForwarder();
     auto layersBackend = shadowForwarder->GetCompositorBackendType();
+    mReadbackClient = TexClientFromReadback(surf, forwarder, flags, layersBackend);
 
-    newTex = TexClientFromReadback(surf, forwarder, flags, layersBackend);
+    newFront = mReadbackClient;
+  } else {
+    mReadbackClient = nullptr;
   }
 
-  if (!newTex) {
+  MOZ_ASSERT(newFront);
+  if (!newFront) {
     // May happen in a release build in case of memory pressure.
-    gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. size: " << aSize;
+    gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. Size: " << aSize;
     return;
   }
 
-  // Add the new TexClient.
-  MOZ_ALWAYS_TRUE( AddTextureClient(newTex) );
-
-  // Remove the old TexClient.
-  if (mFrontTex) {
-    // remove old buffer from CompositableHost
-    RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker();
-    // Hold TextureClient until transaction complete.
-    tracker->SetTextureClient(mFrontTex);
-    mFrontTex->SetRemoveFromCompositableTracker(tracker);
-    // RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
-    GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontTex);
-
-    mFrontTex = nullptr;
+  if (mFront) {
+    if (mFront->GetFlags() & TextureFlags::RECYCLE) {
+      mFront->WaitForCompositorRecycle();
+    }
   }
 
-  // Use the new TexClient.
-  mFrontTex = newTex;
+  mFront = newFront;
 
-  forwarder->UseTexture(this, mFrontTex);
+  // Add the new TexClient.
+  MOZ_ALWAYS_TRUE( AddTextureClient(mFront) );
+
+  forwarder->UseTexture(this, mFront);
 }
 
 void
 CanvasClientSharedSurface::ClearSurfaces()
 {
-  mFrontTex = nullptr;
-  // It is important to destroy the SharedSurface *after* the TextureClient.
   mFront = nullptr;
-  mPrevFront = nullptr;
+  mShSurfClient = nullptr;
+  mReadbackClient = nullptr;
 }
 
-}
-}
+} // namespace layers
+} // namespace mozilla
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -14,27 +14,21 @@
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/TextureClient.h"  // for TextureClient, etc
 #include "mozilla/mozalloc.h"           // for operator delete
 
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat
 
 namespace mozilla {
-namespace gl {
-class SharedSurface;
-class ShSurfHandle;
-}
-}
-
-namespace mozilla {
 namespace layers {
 
 class ClientCanvasLayer;
 class CompositableForwarder;
+class SharedSurfaceTextureClient;
 
 /**
  * Compositable client for 2d and webgl canvas.
  */
 class CanvasClient : public CompositableClient
 {
 public:
   /**
@@ -109,31 +103,27 @@ private:
   RefPtr<TextureClient> mBuffer;
 };
 
 // Used for GL canvases where we don't need to do any readback, i.e., with a
 // GL backend.
 class CanvasClientSharedSurface : public CanvasClient
 {
 private:
-  RefPtr<gl::ShSurfHandle> mFront;
-  RefPtr<gl::ShSurfHandle> mPrevFront;
-
-  RefPtr<TextureClient> mFrontTex;
+  RefPtr<SharedSurfaceTextureClient> mShSurfClient;
+  RefPtr<TextureClient> mReadbackClient;
+  RefPtr<TextureClient> mFront;
 
   void ClearSurfaces();
 
 public:
   CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
                             TextureFlags aFlags);
 
-  ~CanvasClientSharedSurface()
-  {
-    ClearSurfaces();
-  }
+  ~CanvasClientSharedSurface();
 
   virtual TextureInfo GetTextureInfo() const override {
     return TextureInfo(CompositableType::IMAGE);
   }
 
   virtual void Clear() override {
     ClearSurfaces();
   }
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -65,75 +65,67 @@ ClientCanvasLayer::Initialize(const Data
     caps = mGLFrontbuffer->mHasAlpha ? SurfaceCaps::ForRGBA()
                                      : SurfaceCaps::ForRGB();
   } else {
     MOZ_ASSERT(screen);
     caps = screen->mCaps;
   }
   MOZ_ASSERT(caps.alpha == aData.mHasAlpha);
 
+  auto forwarder = ClientManager()->AsShadowForwarder();
+
+  mFlags = TextureFlags::ORIGIN_BOTTOM_LEFT;
+  if (!aData.mIsGLAlphaPremult) {
+    mFlags |= TextureFlags::NON_PREMULTIPLIED;
+  }
+
   UniquePtr<SurfaceFactory> factory;
 
   if (!gfxPrefs::WebGLForceLayersReadback()) {
-    switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) {
+    switch (forwarder->GetCompositorBackendType()) {
       case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
+#if defined(XP_MACOSX)
+        factory = SurfaceFactory_IOSurface::Create(mGLContext, caps, forwarder, mFlags);
+#elif defined(MOZ_WIDGET_GONK)
+        factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext, caps, forwarder, mFlags);
+#else
         if (mGLContext->GetContextType() == GLContextType::EGL) {
-#ifdef MOZ_WIDGET_GONK
-          TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT |
-                               TextureFlags::ORIGIN_BOTTOM_LEFT;
-          if (!aData.mIsGLAlphaPremult) {
-            flags |= TextureFlags::NON_PREMULTIPLIED;
-          }
-          factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext,
-                                                       caps,
-                                                       flags,
-                                                       ClientManager()->AsShadowForwarder());
-#else
-          bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
+          bool isCrossProcess = (XRE_GetProcessType() != GeckoProcessType_Default);
           if (!isCrossProcess) {
-            // [Basic/OGL Layers, OMTC] WebGL layer init.
-            factory = SurfaceFactory_EGLImage::Create(mGLContext, caps);
-          } else {
-            // we could do readback here maybe
-            NS_NOTREACHED("isCrossProcess but not on native B2G!");
+            factory = SurfaceFactory_EGLImage::Create(mGLContext, caps, forwarder,
+                                                      mFlags);
           }
+        }
 #endif
-        } else {
-          // [Basic Layers, OMTC] WebGL layer init.
-          // Well, this *should* work...
-#ifdef XP_MACOSX
-          factory = SurfaceFactory_IOSurface::Create(mGLContext, caps);
-#else
-          GLContext* nullConsGL = nullptr; // Bug 1050044.
-          factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, nullConsGL, caps);
-#endif
-        }
         break;
       }
       case mozilla::layers::LayersBackend::LAYERS_D3D10:
       case mozilla::layers::LayersBackend::LAYERS_D3D11: {
 #ifdef XP_WIN
-        if (mGLContext->IsANGLE() && DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device())) {
-          factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps);
+        if (mGLContext->IsANGLE() &&
+            DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device()))
+        {
+          factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps, forwarder,
+                                                            mFlags);
         }
 #endif
         break;
       }
       default:
         break;
     }
   }
 
   if (mGLFrontbuffer) {
     // We're using a source other than the one in the default screen.
     // (SkiaGL)
     mFactory = Move(factory);
     if (!mFactory) {
       // Absolutely must have a factory here, so create a basic one
-      mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps);
+      mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps, mFlags);
     }
   } else {
     if (factory)
       screen->Morph(Move(factory));
   }
 }
 
 void
--- a/gfx/layers/client/ClientCanvasLayer.h
+++ b/gfx/layers/client/ClientCanvasLayer.h
@@ -1,32 +1,31 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_CLIENTCANVASLAYER_H
 #define GFX_CLIENTCANVASLAYER_H
 
-#include "mozilla/layers/CanvasClient.h"  // for CanvasClient, etc
+#include "CanvasClient.h"               // for CanvasClient, etc
 #include "ClientLayerManager.h"         // for ClientLayerManager, etc
 #include "CopyableCanvasLayer.h"        // for CopyableCanvasLayer
 #include "Layers.h"                     // for CanvasLayer, etc
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/layers/LayersMessages.h"  // for CanvasLayerAttributes, etc
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsRegion.h"                   // for nsIntRegion
 
 namespace mozilla {
 namespace gl {
-class SharedSurface;
 class SurfaceFactory;
 }
 
 namespace layers {
 
 class CompositableClient;
 class ShadowableLayer;
 
@@ -76,28 +75,33 @@ public:
     mCanvasClient = nullptr;
     ClientLayer::Disconnect();
   }
 
   virtual CompositableClient* GetCompositableClient() override
   {
     return mCanvasClient;
   }
+
+  const TextureFlags& Flags() const { return mFlags; }
+
 protected:
   ClientLayerManager* ClientManager()
   {
     return static_cast<ClientLayerManager*>(mManager);
   }
 
   CanvasClientType GetCanvasClientType();
 
   RefPtr<CanvasClient> mCanvasClient;
 
   UniquePtr<gl::SurfaceFactory> mFactory;
 
+  TextureFlags mFlags;
+
   friend class DeprecatedCanvasClient2D;
   friend class CanvasClient2D;
   friend class CanvasClientSharedSurface;
 };
 }
 }
 
 #endif
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -15,18 +15,16 @@
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
 #include "nsDebug.h"                    // for NS_ASSERTION, NS_WARNING, etc
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "ImageContainer.h"             // for PlanarYCbCrData, etc
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Logging.h"        // for gfxDebug
 #include "mozilla/layers/TextureClientOGL.h"
 #include "mozilla/layers/PTextureChild.h"
-#include "SharedSurface.h"
-#include "GLContext.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h" // for CreateDataSourceSurfaceByCloning
 #include "nsPrintfCString.h"            // for nsPrintfCString
 #include "LayersLogging.h"              // for AppendToString
 #include "gfxUtils.h"                   // for gfxUtils::GetAsLZ4Base64Str
 
 #ifdef XP_WIN
 #include "mozilla/layers/TextureD3D9.h"
 #include "mozilla/layers/TextureD3D11.h"
@@ -108,25 +106,25 @@ public:
   , mIPCOpen(false)
   {
   }
 
   bool Recv__delete__() override;
 
   bool RecvCompositorRecycle() override
   {
-    RECYCLE_LOG("Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
+    RECYCLE_LOG("[CLIENT] Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
     mWaitForRecycle = nullptr;
     return true;
   }
 
   void WaitForCompositorRecycle()
   {
     mWaitForRecycle = mTextureClient;
-    RECYCLE_LOG("Wait for recycle %p\n", mWaitForRecycle.get());
+    RECYCLE_LOG("[CLIENT] Wait for recycle %p\n", mWaitForRecycle.get());
     SendClientRecycle();
   }
 
   CompositableForwarder* GetForwarder() { return mForwarder; }
 
   ISurfaceAllocator* GetAllocator() { return mForwarder; }
 
   void ActorDestroy(ActorDestroyReason why) override;
@@ -579,16 +577,20 @@ TextureClient::Finalize()
   // in case TextureChild::ActorDestroy might null mActor concurrently.
   RefPtr<TextureChild> actor = mActor;
 
   if (actor) {
     // 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->mTextureClient = 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
@@ -908,42 +910,16 @@ BufferTextureClient::GetLockedData() con
   MOZ_ASSERT(IsLocked());
 
   ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
   MOZ_ASSERT(serializer.IsValid());
 
   return serializer.GetData();
 }
 
-////////////////////////////////////////////////////////////////////////
-// SharedSurfaceTextureClient
-
-SharedSurfaceTextureClient::SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator,
-                                                       TextureFlags aFlags,
-                                                       gl::SharedSurface* surf)
-  : TextureClient(aAllocator, aFlags)
-  , mIsLocked(false)
-  , mSurf(surf)
-  , mGL(mSurf->mGL)
-{
-  AddFlags(TextureFlags::DEALLOCATE_CLIENT);
-}
-
-SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
-{
-  // the data is owned externally.
-}
-
-bool
-SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
-{
-  aOutDescriptor = SharedSurfaceDescriptor((uintptr_t)mSurf);
-  return true;
-}
-
 TemporaryRef<SyncObject>
 SyncObject::CreateSyncObject(SyncHandle aHandle)
 {
   if (!aHandle) {
     return nullptr;
   }
 
 #ifdef XP_WIN
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -3,17 +3,16 @@
  * 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_TEXTURECLIENT_H
 #define MOZILLA_GFX_TEXTURECLIENT_H
 
 #include <stddef.h>                     // for size_t
 #include <stdint.h>                     // for uint32_t, uint8_t, uint64_t
-#include "GLContextTypes.h"             // for GLContext (ptr only), etc
 #include "GLTextureImage.h"             // for TextureImage
 #include "ImageTypes.h"                 // for StereoMode
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/RefPtr.h"             // for RefPtr, RefCounted
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat
@@ -27,20 +26,16 @@
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsISupportsImpl.h"            // for TextureImage::AddRef, etc
 #include "GfxTexturesReporter.h"
 
 class gfxImageSurface;
 
 namespace mozilla {
-namespace gl {
-class GLContext;
-class SharedSurface;
-}
 
 // 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 layers {
@@ -469,17 +464,17 @@ public:
    /**
     * 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) { }
 
 private:
   /**
    * Called once, just before the destructor.
    *
    * Here goes the shut-down code that uses virtual methods.
    * Must only be called by Release().
@@ -683,76 +678,16 @@ public:
 
   virtual bool HasInternalBuffer() const override { return true; }
 
 protected:
   uint8_t* mBuffer;
   size_t mBufSize;
 };
 
-/**
- * A TextureClient implementation to share SharedSurfaces.
- */
-class SharedSurfaceTextureClient : public TextureClient
-{
-public:
-  SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags,
-                             gl::SharedSurface* surf);
-
-protected:
-  ~SharedSurfaceTextureClient();
-
-public:
-  // Boilerplate start
-  virtual bool IsAllocated() const override { return true; }
-
-  virtual bool Lock(OpenMode) override {
-    MOZ_ASSERT(!mIsLocked);
-    mIsLocked = true;
-    return true;
-  }
-
-  virtual void Unlock() override {
-    MOZ_ASSERT(mIsLocked);
-    mIsLocked = false;
-  }
-
-  virtual bool IsLocked() const override { return mIsLocked; }
-
-  virtual bool HasInternalBuffer() const override { return false; }
-
-  virtual gfx::SurfaceFormat GetFormat() const override {
-    return gfx::SurfaceFormat::UNKNOWN;
-  }
-
-  virtual gfx::IntSize GetSize() const override { return gfx::IntSize(); }
-
-  // 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 TemporaryRef<TextureClient>
-  CreateSimilar(TextureFlags, TextureAllocationFlags) const override {
-    return nullptr;
-  }
-
-  virtual bool AllocateForSurface(gfx::IntSize,
-                                  TextureAllocationFlags) override {
-    MOZ_CRASH("Should never hit this.");
-    return false;
-  }
-  // Boilerplate end
-
-  virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
-
-protected:
-  bool mIsLocked;
-  gl::SharedSurface* const mSurf;
-  RefPtr<gl::GLContext> mGL; // Just for reference holding.
-};
-
 struct TextureClientAutoUnlock
 {
   TextureClient* mTexture;
 
   explicit TextureClientAutoUnlock(TextureClient* aTexture)
   : mTexture(aTexture) {}
 
   ~TextureClientAutoUnlock()
new file mode 100644
--- /dev/null
+++ b/gfx/layers/client/TextureClientSharedSurface.cpp
@@ -0,0 +1,67 @@
+/* -*- 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 "TextureClientSharedSurface.h"
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Logging.h"        // for gfxDebug
+#include "mozilla/layers/ISurfaceAllocator.h"
+#include "SharedSurface.h"
+#include "GLContext.h"
+#include "nsThreadUtils.h"
+
+namespace mozilla {
+namespace layers {
+
+SharedSurfaceTextureClient::SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator,
+                                                       TextureFlags aFlags,
+                                                       UniquePtr<gl::SharedSurface> surf,
+                                                       gl::SurfaceFactory* factory)
+  : TextureClient(aAllocator, aFlags | TextureFlags::RECYCLE)
+  , mSurf(Move(surf))
+  , mFactory(factory)
+  , mRecyclingRef(this)
+{
+  // AtomicRefCountedWithFinalize is a little strange. It attempts to recycle when
+  // Release drops the ref count to 1. The idea is that the recycler holds a strong ref.
+  // Here, we want to keep it simple, and always have a recycle callback, but only recycle
+  // if the WeakPtr mFactory is still non-null. Therefore, we keep mRecyclingRef as ref to
+  // ourself! Call StopRecycling() to end the cycle.
+  mRecyclingRef->SetRecycleCallback(&gl::SurfaceFactory::RecycleCallback, nullptr);
+}
+
+SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
+{
+  // Free the ShSurf implicitly.
+
+  // Tricky issue! We will often call the dtor via Release via StopRecycling, where we
+  // null out mRecyclingRef. Right now, we call Release before actually clearing the
+  // value. This means the dtor will see that mRecyclingRef is non-null, and try to
+  // Release it, even though we're mid-Release! We need to clear mRecyclingRef so the dtor
+  // doesn't try to Release it.
+  mozilla::unused << mRecyclingRef.forget().take();
+}
+
+gfx::IntSize
+SharedSurfaceTextureClient::GetSize() const
+{
+  return mSurf->mSize;
+}
+
+bool
+SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
+{
+  return mSurf->ToSurfaceDescriptor(&aOutDescriptor);
+}
+
+void
+SharedSurfaceTextureClient::StopRecycling()
+{
+  mRecyclingRef->ClearRecycleCallback();
+  mRecyclingRef = nullptr;
+}
+
+} // namespace layers
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/client/TextureClientSharedSurface.h
@@ -0,0 +1,79 @@
+/* -*- 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_TEXTURECLIENT_SHAREDSURFACE_H
+#define MOZILLA_GFX_TEXTURECLIENT_SHAREDSURFACE_H
+
+#include <cstddef>                      // for size_t
+#include <stdint.h>                     // for uint32_t, uint8_t, uint64_t
+#include "GLContextTypes.h"             // for GLContext (ptr only), etc
+#include "TextureClient.h"
+#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
+#include "mozilla/RefPtr.h"             // for RefPtr, RefCounted
+#include "mozilla/gfx/Point.h"          // for IntSize
+#include "mozilla/gfx/Types.h"          // for SurfaceFormat
+#include "mozilla/layers/CompositorTypes.h"  // for TextureFlags, etc
+#include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
+
+namespace mozilla {
+namespace gl {
+class GLContext;
+class SharedSurface;
+class SurfaceFactory;
+}
+
+namespace layers {
+
+class SharedSurfaceTextureClient : public TextureClient
+{
+protected:
+  const UniquePtr<gl::SharedSurface> mSurf;
+  const WeakPtr<gl::SurfaceFactory> mFactory;
+  RefPtr<SharedSurfaceTextureClient> mRecyclingRef;
+
+  friend class gl::SurfaceFactory;
+
+  SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags,
+                             UniquePtr<gl::SharedSurface> surf,
+                             gl::SurfaceFactory* factory);
+
+  ~SharedSurfaceTextureClient();
+
+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 TemporaryRef<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 ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
+
+  gl::SharedSurface* Surf() const {
+    return mSurf.get();
+  }
+
+  void StopRecycling();
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // MOZILLA_GFX_TEXTURECLIENT_SHAREDSURFACE_H
--- a/gfx/layers/composite/FPSCounter.cpp
+++ b/gfx/layers/composite/FPSCounter.cpp
@@ -20,17 +20,16 @@
 #include "nsDirectoryServiceDefs.h"     // for NS_OS_TMP_DIR
 #include "prprf.h"                      // for PR_snprintf
 #include "FPSCounter.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
-using namespace mozilla::gl;
 
 FPSCounter::FPSCounter(const char* aName)
   : mWriteIndex(0)
   , mFPSName(aName)
 {
   Init();
 }
 
@@ -390,17 +389,17 @@ static void DrawDigits(unsigned int aVal
     divisor /= 10;
 
     RefPtr<TexturedEffect> texturedEffect = static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
     texturedEffect->mTextureCoords = Rect(float(digit * FontWidth) / textureWidth, 0, FontWidth / textureWidth, 1.0f);
 
     Rect drawRect = Rect(aOffsetX + n * FontWidth, aOffsetY, FontWidth, FontHeight);
     Rect clipRect = Rect(0, 0, 300, 100);
     aCompositor->DrawQuad(drawRect, clipRect,
-	aEffectChain, opacity, transform);
+  aEffectChain, opacity, transform);
   }
 }
 
 void FPSState::DrawFPS(TimeStamp aNow,
                        int aOffsetX, int aOffsetY,
                        unsigned int aFillRatio,
                        Compositor* aCompositor)
 {
--- a/gfx/layers/composite/ImageHost.cpp
+++ b/gfx/layers/composite/ImageHost.cpp
@@ -29,18 +29,17 @@ class ISurfaceAllocator;
 
 ImageHost::ImageHost(const TextureInfo& aTextureInfo)
   : CompositableHost(aTextureInfo)
   , mHasPictureRect(false)
   , mLocked(false)
 {}
 
 ImageHost::~ImageHost()
-{
-}
+{}
 
 void
 ImageHost::UseTextureHost(TextureHost* aTexture)
 {
   CompositableHost::UseTextureHost(aTexture);
   mFrontBuffer = aTexture;
   if (mFrontBuffer) {
     mFrontBuffer->Updated();
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -17,43 +17,37 @@
 #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
 #include "nsAString.h"
 #include "nsRefPtr.h"                   // for nsRefPtr
 #include "nsPrintfCString.h"            // for nsPrintfCString
 #include "mozilla/layers/PTextureParent.h"
 #include "mozilla/unused.h"
 #include <limits>
-#include "SharedSurface.h"
-#include "SharedSurfaceEGL.h"
-#include "SharedSurfaceGL.h"
 #include "../opengl/CompositorOGL.h"
 #include "gfxUtils.h"
 
 #ifdef MOZ_ENABLE_D3D10_LAYER
 #include "../d3d11/CompositorD3D11.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 #include "../opengl/GrallocTextureClient.h"
 #include "../opengl/GrallocTextureHost.h"
-#include "SharedSurfaceGralloc.h"
 #endif
 
 #ifdef MOZ_X11
 #include "mozilla/layers/X11TextureHost.h"
 #endif
 
 #ifdef XP_MACOSX
-#include "SharedSurfaceIO.h"
 #include "../opengl/MacIOSurfaceTextureHostOGL.h"
 #endif
 
 #ifdef XP_WIN
-#include "SharedSurfaceANGLE.h"
 #include "mozilla/layers/TextureDIB.h"
 #endif
 
 #if 0
 #define RECYCLE_LOG(...) printf_stderr(__VA_ARGS__)
 #else
 #define RECYCLE_LOG(...) do { } while (0)
 #endif
@@ -91,16 +85,18 @@ public:
 
   void ClearTextureHost();
 
   CompositableParentManager* mCompositableManager;
   RefPtr<TextureHost> mWaitForClientRecycle;
   RefPtr<TextureHost> mTextureHost;
 };
 
+////////////////////////////////////////////////////////////////////////////////
+
 // static
 PTextureParent*
 TextureHost::CreateIPDLActor(CompositableParentManager* aManager,
                              const SurfaceDescriptor& aSharedData,
                              TextureFlags aFlags)
 {
   if (aSharedData.type() == SurfaceDescriptor::TSurfaceDescriptorMemory &&
       !aManager->IsSameProcess())
@@ -182,19 +178,16 @@ TextureHost::Create(const SurfaceDescrip
     case SurfaceDescriptor::TSurfaceDescriptorDIB:
       return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
 
     case SurfaceDescriptor::TEGLImageDescriptor:
     case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:
     case SurfaceDescriptor::TSurfaceTextureDescriptor:
       return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
 
-    case SurfaceDescriptor::TSharedSurfaceDescriptor:
-      return new SharedSurfaceTextureHost(aFlags, aDesc.get_SharedSurfaceDescriptor());
-
     case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
       if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) {
         return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
       } else {
         return CreateTextureHostBasic(aDesc, aDeallocator, aFlags);
       }
 
 #ifdef MOZ_X11
@@ -832,157 +825,10 @@ TextureParent::RecvRecycleTexture(const 
     return true;
   }
   mTextureHost->RecycleTexture(aTextureFlags);
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static RefPtr<TextureSource>
-SharedSurfaceToTexSource(gl::SharedSurface* abstractSurf, Compositor* compositor)
-{
-  MOZ_ASSERT(abstractSurf);
-  MOZ_ASSERT(abstractSurf->mType != gl::SharedSurfaceType::Basic);
-  MOZ_ASSERT(abstractSurf->mType != gl::SharedSurfaceType::Gralloc);
-
-  if (!compositor) {
-    return nullptr;
-  }
-
-  gfx::SurfaceFormat format = abstractSurf->mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
-                                                      : gfx::SurfaceFormat::R8G8B8X8;
-
-  RefPtr<TextureSource> texSource;
-  switch (abstractSurf->mType) {
-#ifdef XP_WIN
-    case gl::SharedSurfaceType::EGLSurfaceANGLE: {
-      auto surf = gl::SharedSurface_ANGLEShareHandle::Cast(abstractSurf);
-
-      MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_D3D11);
-      CompositorD3D11* compositorD3D11 = static_cast<CompositorD3D11*>(compositor);
-      RefPtr<ID3D11Texture2D> tex = surf->GetConsumerTexture();
-
-      if (!tex) {
-        NS_WARNING("Failed to open shared resource.");
-        break;
-      }
-      texSource = new DataTextureSourceD3D11(format, compositorD3D11, tex);
-      break;
-    }
-#endif
-    case gl::SharedSurfaceType::GLTextureShare: {
-      auto surf = gl::SharedSurface_GLTexture::Cast(abstractSurf);
-
-      MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
-      CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor);
-      gl::GLContext* gl = compositorOGL->gl();
-
-      GLenum target = surf->ConsTextureTarget();
-      GLuint tex = surf->ConsTexture(gl);
-      texSource = new GLTextureSource(compositorOGL, tex, target,
-                                      surf->mSize, format,
-                                      true/*externally owned*/);
-      break;
-    }
-    case gl::SharedSurfaceType::EGLImageShare: {
-      auto surf = gl::SharedSurface_EGLImage::Cast(abstractSurf);
-
-      MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
-      CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor);
-      gl::GLContext* gl = compositorOGL->gl();
-      MOZ_ASSERT(gl->IsCurrent());
-
-      GLenum target = 0;
-      GLuint tex = 0;
-      surf->AcquireConsumerTexture(gl, &tex, &target);
-
-      texSource = new GLTextureSource(compositorOGL, tex, target,
-                                      surf->mSize, format,
-                                      true/*externally owned*/);
-      break;
-    }
-#ifdef XP_MACOSX
-    case gl::SharedSurfaceType::IOSurface: {
-      auto surf = gl::SharedSurface_IOSurface::Cast(abstractSurf);
-      MacIOSurface* ioSurf = surf->GetIOSurface();
-
-      MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
-      CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor);
-
-      texSource = new MacIOSurfaceTextureSourceOGL(compositorOGL, ioSurf);
-      break;
-    }
-#endif
-    default:
-      break;
-  }
-
-  MOZ_ASSERT(texSource.get(), "TextureSource creation failed.");
-  return texSource;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// SharedSurfaceTextureHost
-
-SharedSurfaceTextureHost::SharedSurfaceTextureHost(TextureFlags aFlags,
-                                                   const SharedSurfaceDescriptor& aDesc)
-  : TextureHost(aFlags)
-  , mIsLocked(false)
-  , mSurf((gl::SharedSurface*)aDesc.surf())
-  , mCompositor(nullptr)
-{
-  MOZ_ASSERT(mSurf);
-}
-
-gfx::SurfaceFormat
-SharedSurfaceTextureHost::GetFormat() const
-{
-  MOZ_ASSERT(mTexSource);
-  return mTexSource->GetFormat();
-}
-
-gfx::IntSize
-SharedSurfaceTextureHost::GetSize() const
-{
-  MOZ_ASSERT(mTexSource);
-  return mTexSource->GetSize();
-}
-
-void
-SharedSurfaceTextureHost::EnsureTexSource()
-{
-  MOZ_ASSERT(mIsLocked);
-
-  if (mTexSource)
-    return;
-
-  mTexSource = SharedSurfaceToTexSource(mSurf, mCompositor);
-  MOZ_ASSERT(mTexSource);
-}
-
-bool
-SharedSurfaceTextureHost::Lock()
-{
-  MOZ_ASSERT(!mIsLocked);
-
-  mSurf->ConsumerAcquire();
-
-  mIsLocked = true;
-
-  EnsureTexSource();
-
-  return true;
-}
-
-void
-SharedSurfaceTextureHost::Unlock()
-{
-  MOZ_ASSERT(mIsLocked);
-  mSurf->ConsumerRelease();
-  mIsLocked = false;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-
 } // namespace
 } // namespace
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -26,29 +26,25 @@
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 #include "nscore.h"                     // for nsACString
 #include "mozilla/layers/AtomicRefCountedWithFinalize.h"
 #include "mozilla/gfx/Rect.h"
 
 namespace mozilla {
-namespace gl {
-class SharedSurface;
-}
 namespace ipc {
 class Shmem;
 }
 
 namespace layers {
 
 class Compositor;
 class CompositableParentManager;
 class SurfaceDescriptor;
-class SharedSurfaceDescriptor;
 class ISurfaceAllocator;
 class TextureHostOGL;
 class TextureSourceOGL;
 class TextureSourceD3D9;
 class TextureSourceD3D11;
 class TextureSourceBasic;
 class DataTextureSource;
 class PTextureParent;
@@ -657,74 +653,16 @@ public:
   virtual size_t GetBufferSize() override;
 
   virtual const char *Name() override { return "MemoryTextureHost"; }
 
 protected:
   uint8_t* mBuffer;
 };
 
-/**
- * A TextureHost for SharedSurfaces
- */
-class SharedSurfaceTextureHost : public TextureHost
-{
-public:
-  SharedSurfaceTextureHost(TextureFlags aFlags,
-                           const SharedSurfaceDescriptor& aDesc);
-
-  virtual ~SharedSurfaceTextureHost() {
-    MOZ_ASSERT(!mIsLocked);
-  }
-
-  virtual void DeallocateDeviceData() override {};
-
-  virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() override {
-    return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
-  }
-
-  virtual void SetCompositor(Compositor* aCompositor) override {
-    MOZ_ASSERT(!mIsLocked);
-
-    if (aCompositor == mCompositor)
-      return;
-
-    mTexSource = nullptr;
-    mCompositor = aCompositor;
-  }
-
-public:
-
-  virtual bool Lock() override;
-  virtual void Unlock() override;
-
-  virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override {
-    MOZ_ASSERT(mIsLocked);
-    MOZ_ASSERT(mTexSource);
-    aTexture = mTexSource;
-    return !!aTexture;
-  }
-
-  virtual gfx::SurfaceFormat GetFormat() const override;
-
-  virtual gfx::IntSize GetSize() const override;
-
-#ifdef MOZ_LAYERS_HAVE_LOG
-  virtual const char* Name() override { return "SharedSurfaceTextureHost"; }
-#endif
-
-protected:
-  void EnsureTexSource();
-
-  bool mIsLocked;
-  gl::SharedSurface* const mSurf;
-  RefPtr<Compositor> mCompositor;
-  RefPtr<TextureSource> mTexSource;
-};
-
 class MOZ_STACK_CLASS AutoLockTextureHost
 {
 public:
   explicit AutoLockTextureHost(TextureHost* aTexture)
     : mTexture(aTexture)
   {
     mLocked = mTexture ? mTexture->Lock() : false;
   }
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -346,34 +346,34 @@ void ImageBridgeChild::DispatchReleaseIm
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseImageClientNow, aClient));
 }
 
 static void ReleaseTextureClientNow(TextureClient* aClient)
 {
   MOZ_ASSERT(InImageBridgeChildThread());
-  aClient->Release();
+  RELEASE_MANUALLY(aClient);
 }
 
 // static
 void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient)
 {
   if (!aClient) {
     return;
   }
 
   if (!IsCreated()) {
     // TextureClient::Release should normally happen in the ImageBridgeChild
     // thread because it usually generate some IPDL messages.
     // However, if we take this branch it means that the ImageBridgeChild
     // has already shut down, along with the TextureChild, which means no
     // message will be sent and it is safe to run this code from any thread.
     MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
-    aClient->Release();
+    RELEASE_MANUALLY(aClient);
     return;
   }
 
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseTextureClientNow, aClient));
 }
 
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -184,29 +184,29 @@ bool ImageBridgeParent::RecvWillStop()
     tex->DeallocateDeviceData();
   }
   return true;
 }
 
 static void
 ReleaseImageBridgeParent(ImageBridgeParent* aImageBridgeParent)
 {
-  aImageBridgeParent->Release();
+  RELEASE_MANUALLY(aImageBridgeParent);
 }
 
 bool ImageBridgeParent::RecvStop()
 {
   // This message just serves as synchronization between the
   // child and parent threads during shutdown.
 
   // There is one thing that we need to do here: temporarily addref, so that
   // the handling of this sync message can't race with the destruction of
   // the ImageBridgeParent, which would trigger the dreaded "mismatched CxxStackFrames"
   // assertion of MessageChannel.
-  AddRef();
+  ADDREF_MANUALLY(this);
   MessageLoop::current()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseImageBridgeParent, this));
   return true;
 }
 
 static  uint64_t GenImageContainerID() {
   static uint64_t sNextImageID = 1;
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -155,22 +155,22 @@ protected:
 
   bool Attach(ShadowLayerParent* aLayerParent,
               CompositableHost* aCompositable,
               bool aIsAsyncVideo);
 
   void AddIPDLReference() {
     MOZ_ASSERT(mIPCOpen == false);
     mIPCOpen = true;
-    AddRef();
+    ADDREF_MANUALLY(this);
   }
   void ReleaseIPDLReference() {
     MOZ_ASSERT(mIPCOpen == true);
     mIPCOpen = false;
-    Release();
+    RELEASE_MANUALLY(this);
   }
   friend class CompositorParent;
   friend class CrossProcessCompositorParent;
   friend class layout::RenderFrameParent;
 
 private:
   nsRefPtr<LayerManagerComposite> mLayerManager;
   ShadowLayersManager* mShadowLayersManager;
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -54,17 +54,17 @@ struct SurfaceDescriptorDXGIYCbCr {
   WindowsHandle handleCb;
   WindowsHandle handleCr;
   IntSize size;
   IntSize sizeY;
   IntSize sizeCbCr;
 };
 
 struct SurfaceDescriptorMacIOSurface {
-  uint32_t surface;
+  uint32_t surfaceId;
   double scaleFactor;
   bool isOpaque;
 };
 
 struct SurfaceTextureDescriptor {
   uintptr_t surfTex;
   IntSize size;
 };
@@ -81,46 +81,41 @@ struct NewSurfaceDescriptorGralloc {
    * android::GraphicBuffer has a size information. But there are cases
    * that GraphicBuffer's size and actual video's size are different.
    * Extra size member is necessary. See Bug 850566.
    */
   IntSize size;
   bool isOpaque;
 };
 
-struct SharedSurfaceDescriptor {
-  uintptr_t surf;
-};
-
 /**
  * Used for shmem-backed YCbCr and (flavors of) RGBA textures
  */
 struct SurfaceDescriptorShmem {
   Shmem data;
   SurfaceFormat format;
 };
 
 /**
  * Used for "raw memory"-backed YCbCr and (flavors of) RGBA textures
  */
- struct SurfaceDescriptorMemory {
+struct SurfaceDescriptorMemory {
   uintptr_t data;
   SurfaceFormat format;
 };
 
 union SurfaceDescriptor {
   SurfaceDescriptorShmem;
   SurfaceDescriptorMemory;
   SurfaceDescriptorD3D9;
   SurfaceDescriptorDIB;
   SurfaceDescriptorD3D10;
   SurfaceDescriptorDXGIYCbCr;
   SurfaceDescriptorX11;
   SurfaceTextureDescriptor;
   EGLImageDescriptor;
   SurfaceDescriptorMacIOSurface;
   NewSurfaceDescriptorGralloc;
-  SharedSurfaceDescriptor;
   null_t;
 };
 
 } // namespace
 } // namespace
--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
@@ -32,17 +32,20 @@ SharedPlanarYCbCrImage::SharedPlanarYCbC
   MOZ_COUNT_CTOR(SharedPlanarYCbCrImage);
 }
 
 SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
   MOZ_COUNT_DTOR(SharedPlanarYCbCrImage);
 
   if (mCompositable->GetAsyncID() != 0 &&
       !InImageBridgeChildThread()) {
-    ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().take());
+    ADDREF_MANUALLY(mTextureClient);
+    ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
+    mTextureClient = nullptr;
+
     ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take());
   }
 }
 
 size_t
 SharedPlanarYCbCrImage::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   // NB: Explicitly skipping mTextureClient, the memory is already reported
--- a/gfx/layers/ipc/SharedRGBImage.cpp
+++ b/gfx/layers/ipc/SharedRGBImage.cpp
@@ -64,17 +64,20 @@ SharedRGBImage::SharedRGBImage(ImageClie
 }
 
 SharedRGBImage::~SharedRGBImage()
 {
   MOZ_COUNT_DTOR(SharedRGBImage);
 
   if (mCompositable->GetAsyncID() != 0 &&
       !InImageBridgeChildThread()) {
-    ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().take());
+    ADDREF_MANUALLY(mTextureClient);
+    ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
+    mTextureClient = nullptr;
+
     ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take());
   }
 }
 
 bool
 SharedRGBImage::Allocate(gfx::IntSize aSize, gfx::SurfaceFormat aFormat)
 {
   mSize = aSize;
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -113,16 +113,17 @@ EXPORTS.mozilla.layers += [
     'basic/TextureHostBasic.h',
     'client/CanvasClient.h',
     'client/CompositableClient.h',
     'client/ContentClient.h',
     'client/ImageClient.h',
     'client/TextureClient.h',
     'client/TextureClientPool.h',
     'client/TextureClientRecycleAllocator.h',
+    'client/TextureClientSharedSurface.h',
     'client/TiledContentClient.h',
     'composite/AsyncCompositionManager.h',
     'composite/CanvasLayerComposite.h',
     'composite/ColorLayerComposite.h',
     'composite/ContainerLayerComposite.h',
     'composite/ContentHost.h',
     'composite/ImageHost.h',
     'composite/ImageLayerComposite.h',
@@ -264,16 +265,17 @@ UNIFIED_SOURCES += [
     'client/ClientPaintedLayer.cpp',
     'client/ClientTiledPaintedLayer.cpp',
     'client/CompositableClient.cpp',
     'client/ContentClient.cpp',
     'client/ImageClient.cpp',
     'client/TextureClient.cpp',
     'client/TextureClientPool.cpp',
     'client/TextureClientRecycleAllocator.cpp',
+    'client/TextureClientSharedSurface.cpp',
     'client/TiledContentClient.cpp',
     'composite/AsyncCompositionManager.cpp',
     'composite/CanvasLayerComposite.cpp',
     'composite/ColorLayerComposite.cpp',
     'composite/CompositableHost.cpp',
     'composite/ContainerLayerComposite.cpp',
     'composite/ContentHost.cpp',
     'composite/FPSCounter.cpp',
--- a/gfx/layers/opengl/GrallocTextureClient.h
+++ b/gfx/layers/opengl/GrallocTextureClient.h
@@ -14,16 +14,20 @@
 #include <ui/GraphicBuffer.h>
 
 
 namespace android {
 class MediaBuffer;
 };
 
 namespace mozilla {
+namespace gl {
+class SharedSurface;
+}
+
 namespace layers {
 
 /**
  * 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
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -9,17 +9,17 @@
 
 namespace mozilla {
 namespace layers {
 
 MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(TextureFlags aFlags,
                                                        const SurfaceDescriptorMacIOSurface& aDescriptor)
   : TextureHost(aFlags)
 {
-  mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
+  mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(),
                                          aDescriptor.scaleFactor(),
                                          !aDescriptor.isOpaque());
 }
 
 bool
 MacIOSurfaceTextureHostOGL::Lock()
 {
   if (!mCompositor || !mSurface) {
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -10,32 +10,34 @@
 #include "GLLibraryEGL.h"               // for GLLibraryEGL
 #include "GLUploadHelpers.h"
 #include "GLReadTexImageHelper.h"
 #include "gfx2DGlue.h"                  // for ContentForFormat, etc
 #include "gfxReusableSurfaceWrapper.h"  // for gfxReusableSurfaceWrapper
 #include "mozilla/gfx/2D.h"             // for DataSourceSurface
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Logging.h"        // for gfxCriticalError
-#ifdef MOZ_WIDGET_GONK
-# include "GrallocImages.h"  // for GrallocImage
-# include "EGLImageHelpers.h"
-#endif
 #include "mozilla/layers/ISurfaceAllocator.h"
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
 #include "mozilla/layers/GrallocTextureHost.h"
 #include "nsRegion.h"                   // for nsIntRegion
 #include "AndroidSurfaceTexture.h"
 #include "GfxTexturesReporter.h"        // for GfxTexturesReporter
 #include "GLBlitTextureImageHelper.h"
+#include "GeckoProfiler.h"
+
+#ifdef MOZ_WIDGET_GONK
+# include "GrallocImages.h"  // for GrallocImage
+# include "EGLImageHelpers.h"
+#endif
+
 #ifdef XP_MACOSX
-#include "SharedSurfaceIO.h"
 #include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
 #endif
-#include "GeckoProfiler.h"
+
 
 using namespace mozilla::gl;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 class Compositor;
@@ -584,36 +586,37 @@ EGLImageTextureSource::EGLImageTextureSo
                                              gfx::IntSize aSize)
   : mCompositor(aCompositor)
   , mImage(aImage)
   , mFormat(aFormat)
   , mTextureTarget(aTarget)
   , mWrapMode(aWrapMode)
   , mSize(aSize)
 {
+  MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D ||
+             mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL);
 }
 
 void
 EGLImageTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
 {
   if (!gl()) {
     NS_WARNING("Trying to bind a texture without a GLContext");
     return;
   }
 
   MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl()),
              "EGLImage not supported or disabled in runtime");
 
-  GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit);
+  GLuint tex = mCompositor->GetTemporaryTexture(mTextureTarget, aTextureUnit);
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(mTextureTarget, tex);
 
-  MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D);
-  gl()->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage);
+  gl()->fEGLImageTargetTexture2D(mTextureTarget, mImage);
 
   ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
 }
 
 void
 EGLImageTextureSource::SetCompositor(Compositor* aCompositor)
 {
   MOZ_ASSERT(aCompositor);
@@ -645,44 +648,45 @@ EGLImageTextureHost::EGLImageTextureHost
                                          EGLImage aImage,
                                          EGLSync aSync,
                                          gfx::IntSize aSize)
   : TextureHost(aFlags)
   , mImage(aImage)
   , mSync(aSync)
   , mSize(aSize)
   , mCompositor(nullptr)
-{
-}
+{}
 
 EGLImageTextureHost::~EGLImageTextureHost()
-{
-}
+{}
 
 gl::GLContext*
 EGLImageTextureHost::gl() const
 {
   return mCompositor ? mCompositor->gl() : nullptr;
 }
 
 bool
 EGLImageTextureHost::Lock()
 {
   if (!mCompositor) {
     return false;
   }
 
   EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
+
   if (status != LOCAL_EGL_CONDITION_SATISFIED) {
+    MOZ_ASSERT(status != 0,
+               "ClientWaitSync generated an error. Has mSync already been destroyed?");
     return false;
   }
 
   if (!mTextureSource) {
     gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
-    GLenum target = LOCAL_GL_TEXTURE_2D;
+    GLenum target = LOCAL_GL_TEXTURE_EXTERNAL;
     GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
     mTextureSource = new EGLImageTextureSource(mCompositor,
                                                mImage,
                                                format,
                                                target,
                                                wrapMode,
                                                mSize);
   }