Bug 973892 - Make TextureClient::GetAsDrawTarget work with canvas. r=bas
authorNicolas Silva <nical@mozilla.com>
Mon, 17 Mar 2014 22:35:20 +0100
changeset 173963 5b26312bcf46a40562a2ae1600f652969ece4958
parent 173962 dc2225034769b79699a0349aeb594dd4f9a0b157
child 173964 d58e8a7d933d3a74ceebda987ea760320e6a7306
push id26438
push userphilringnalda@gmail.com
push dateTue, 18 Mar 2014 05:39:07 +0000
treeherdermozilla-central@89275f0ae29f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs973892
milestone31.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 973892 - Make TextureClient::GetAsDrawTarget work with canvas. r=bas
gfx/gl/SharedSurfaceGralloc.cpp
gfx/layers/GrallocImages.cpp
gfx/layers/ImageContainer.cpp
gfx/layers/ImageDataSerializer.cpp
gfx/layers/ImageDataSerializer.h
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CompositableClient.cpp
gfx/layers/client/CompositableClient.h
gfx/layers/client/ContentClient.cpp
gfx/layers/client/ImageClient.cpp
gfx/layers/client/SimpleTextureClientPool.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/client/TextureClientPool.cpp
gfx/layers/opengl/GrallocTextureClient.cpp
gfx/layers/opengl/GrallocTextureClient.h
gfx/tests/gtest/TestTextures.cpp
gfx/thebes/gfxPlatform.h
--- a/gfx/gl/SharedSurfaceGralloc.cpp
+++ b/gfx/gl/SharedSurfaceGralloc.cpp
@@ -69,16 +69,17 @@ SharedSurface_Gralloc::Create(GLContext*
 
     gfxImageFormat format
       = gfxPlatform::GetPlatform()->OptimalFormatForContent(type);
 
     RefPtr<GrallocTextureClientOGL> grallocTC =
       new GrallocTextureClientOGL(
           allocator,
           gfx::ImageFormatToSurfaceFormat(format),
+          gfx::BackendType::NONE, // we don't need to use it with a DrawTarget
           TEXTURE_FLAGS_DEFAULT);
 
     if (!grallocTC->AllocateForGLRendering(size)) {
       return nullptr;
     }
 
     sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer();
 
--- a/gfx/layers/GrallocImages.cpp
+++ b/gfx/layers/GrallocImages.cpp
@@ -410,16 +410,16 @@ GrallocImage::GetTextureClient(Composita
       return nullptr;
     }
     const SurfaceDescriptorGralloc& desc = sd.get_SurfaceDescriptorGralloc();
     TextureFlags flags = desc.external() ? TEXTURE_DEALLOCATE_CLIENT : 0;
     if (desc.isRBSwapped()) {
       flags |= TEXTURE_RB_SWAPPED;
     }
     GrallocBufferActor* actor = static_cast<GrallocBufferActor*>(desc.bufferChild());
-    mTextureClient = new GrallocTextureClientOGL(actor, mSize, flags);
+    mTextureClient = new GrallocTextureClientOGL(actor, mSize, gfx::BackendType::NONE, flags);
     mTextureClient->SetGraphicBufferLocked(mGraphicBufferLocked);
   }
   return mTextureClient;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -666,18 +666,20 @@ CairoImage::GetTextureClient(Compositabl
   RefPtr<TextureClient> textureClient = mTextureClients.Get(forwarder->GetSerial());
   if (textureClient) {
     return textureClient;
   }
 
   RefPtr<SourceSurface> surface = GetAsSourceSurface();
   MOZ_ASSERT(surface);
 
+  // gfx::BackendType::NONE means default to content backend
   textureClient = aClient->CreateTextureClientForDrawing(surface->GetFormat(),
                                                          TEXTURE_FLAGS_DEFAULT,
+                                                         gfx::BackendType::NONE,
                                                          surface->GetSize());
   MOZ_ASSERT(textureClient->AsTextureClientDrawTarget());
   if (!textureClient->AsTextureClientDrawTarget()->AllocateForSurface(surface->GetSize()) ||
       !textureClient->Lock(OPEN_WRITE_ONLY)) {
     return nullptr;
   }
 
   {
--- a/gfx/layers/ImageDataSerializer.cpp
+++ b/gfx/layers/ImageDataSerializer.cpp
@@ -135,23 +135,22 @@ ImageDataSerializerBase::GetAsThebesSurf
   IntSize size = GetSize();
   return new gfxImageSurface(GetData(),
                              gfxIntSize(size.width, size.height),
                              GetStride(),
                              SurfaceFormatToImageFormat(GetFormat()));
 }
 
 TemporaryRef<DrawTarget>
-ImageDataSerializerBase::GetAsDrawTarget()
+ImageDataSerializerBase::GetAsDrawTarget(gfx::BackendType aBackend)
 {
   MOZ_ASSERT(IsValid());
-  return gfxPlatform::GetPlatform()->CreateDrawTargetForData(GetData(),
-                                                             GetSize(),
-                                                             GetStride(),
-                                                             GetFormat());
+  return gfx::Factory::CreateDrawTargetForData(aBackend,
+                                               GetData(), GetSize(),
+                                               GetStride(), GetFormat());
 }
 
 TemporaryRef<gfx::DataSourceSurface>
 ImageDataSerializerBase::GetAsSurface()
 {
   MOZ_ASSERT(IsValid());
   return Factory::CreateWrappingDataSourceSurface(GetData(),
                                                   GetStride(),
--- a/gfx/layers/ImageDataSerializer.h
+++ b/gfx/layers/ImageDataSerializer.h
@@ -32,17 +32,17 @@ public:
   bool IsValid() const { return mIsValid; }
 
   uint8_t* GetData();
   uint32_t GetStride() const;
   gfx::IntSize GetSize() const;
   gfx::SurfaceFormat GetFormat() const;
   TemporaryRef<gfx::DataSourceSurface> GetAsSurface();
   TemporaryRef<gfxImageSurface> GetAsThebesSurface();
-  TemporaryRef<gfx::DrawTarget> GetAsDrawTarget();
+  TemporaryRef<gfx::DrawTarget> GetAsDrawTarget(gfx::BackendType aBackend);
 
   static uint32_t ComputeMinBufferSize(gfx::IntSize aSize,
                                        gfx::SurfaceFormat aFormat);
 
 protected:
 
   ImageDataSerializerBase(uint8_t* aData, size_t aDataSize)
     : mData(aData)
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -60,17 +60,19 @@ CanvasClient2D::Update(gfx::IntSize aSiz
   bool bufferCreated = false;
   if (!mBuffer) {
     bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE);
     gfxContentType contentType = isOpaque
                                                 ? gfxContentType::COLOR
                                                 : gfxContentType::COLOR_ALPHA;
     gfxImageFormat format
       = gfxPlatform::GetPlatform()->OptimalFormatForContent(contentType);
-    mBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format));
+    mBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format),
+                                        TEXTURE_FLAGS_DEFAULT,
+                                        gfxPlatform::GetPlatform()->GetPreferredCanvasBackend());
     MOZ_ASSERT(mBuffer->AsTextureClientSurface());
     mBuffer->AsTextureClientSurface()->AllocateForSurface(aSize);
 
     bufferCreated = true;
   }
 
   if (!mBuffer->Lock(OPEN_WRITE_ONLY)) {
     return;
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -164,29 +164,33 @@ CompositableClient::CreateDeprecatedText
              "Created the wrong texture client?");
   result->SetFlags(GetTextureInfo().mTextureFlags);
 
   return result.forget();
 }
 
 TemporaryRef<BufferTextureClient>
 CompositableClient::CreateBufferTextureClient(SurfaceFormat aFormat,
-                                              TextureFlags aTextureFlags)
+                                              TextureFlags aTextureFlags,
+                                              gfx::BackendType aMoz2DBackend)
 {
   return TextureClient::CreateBufferTextureClient(GetForwarder(), aFormat,
-                                                  aTextureFlags | mTextureFlags);
+                                                  aTextureFlags | mTextureFlags,
+                                                  aMoz2DBackend);
 }
 
 TemporaryRef<TextureClient>
 CompositableClient::CreateTextureClientForDrawing(SurfaceFormat aFormat,
                                                   TextureFlags aTextureFlags,
+                                                  gfx::BackendType aMoz2DBackend,
                                                   const IntSize& aSizeHint)
 {
   return TextureClient::CreateTextureClientForDrawing(GetForwarder(), aFormat,
                                                       aTextureFlags | mTextureFlags,
+                                                      aMoz2DBackend,
                                                       aSizeHint);
 }
 
 bool
 CompositableClient::AddTextureClient(TextureClient* aClient)
 {
   return aClient->InitIPDLActor(mForwarder);
 }
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -82,23 +82,25 @@ public:
   LayersBackend GetCompositorBackendType() const;
 
   TemporaryRef<DeprecatedTextureClient>
   CreateDeprecatedTextureClient(DeprecatedTextureClientType aDeprecatedTextureClientType,
                                 gfxContentType aContentType = gfxContentType::SENTINEL);
 
   TemporaryRef<BufferTextureClient>
   CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
-                            TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
+                            TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT,
+                            gfx::BackendType aMoz2dBackend = gfx::BackendType::NONE);
 
   // If we return a non-null TextureClient, then AsTextureClientDrawTarget will
   // always be non-null.
   TemporaryRef<TextureClient>
   CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat,
                                 TextureFlags aTextureFlags,
+                                gfx::BackendType aMoz2dBackend,
                                 const gfx::IntSize& aSizeHint);
 
   virtual void SetDescriptorFromReply(TextureIdentifier aTextureId,
                                       const SurfaceDescriptor& aDescriptor)
   {
     MOZ_CRASH("If you want to call this, you should have implemented it");
   }
 
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -163,26 +163,29 @@ ContentClientRemoteBuffer::EndPaint()
     mTextureClientOnWhite->Unlock();
   }
 }
 
 bool
 ContentClientRemoteBuffer::CreateAndAllocateTextureClient(RefPtr<TextureClient>& aClient,
                                                           TextureFlags aFlags)
 {
+  // gfx::BackendType::NONE means fallback to the content backend
   aClient = CreateTextureClientForDrawing(mSurfaceFormat,
                                           mTextureInfo.mTextureFlags | aFlags,
+                                          gfx::BackendType::NONE,
                                           mSize);
   if (!aClient) {
     return false;
   }
 
   if (!aClient->AsTextureClientDrawTarget()->AllocateForSurface(mSize, ALLOC_CLEAR_BUFFER)) {
     aClient = CreateTextureClientForDrawing(mSurfaceFormat,
                 mTextureInfo.mTextureFlags | TEXTURE_ALLOC_FALLBACK | aFlags,
+                gfx::BackendType::NONE,
                 mSize);
     if (!aClient) {
       return false;
     }
     if (!aClient->AsTextureClientDrawTarget()->AllocateForSurface(mSize, ALLOC_CLEAR_BUFFER)) {
       NS_WARNING("Could not allocate texture client");
       aClient = nullptr;
       return false;
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -235,17 +235,17 @@ ImageClientSingle::UpdateImageInternal(I
       mFrontBuffer = nullptr;
     }
 
     bool bufferCreated = false;
     if (!mFrontBuffer) {
       gfxImageFormat format
         = gfxPlatform::GetPlatform()->OptimalFormatForContent(gfx::ContentForFormat(surface->GetFormat()));
       mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format),
-                                                   mTextureFlags, size);
+                                                   mTextureFlags, gfx::BackendType::NONE, size);
       MOZ_ASSERT(mFrontBuffer->AsTextureClientDrawTarget());
       if (!mFrontBuffer->AsTextureClientDrawTarget()->AllocateForSurface(size)) {
         mFrontBuffer = nullptr;
         return false;
       }
 
       bufferCreated = true;
     }
--- a/gfx/layers/client/SimpleTextureClientPool.cpp
+++ b/gfx/layers/client/SimpleTextureClientPool.cpp
@@ -65,19 +65,21 @@ SimpleTextureClientPool::GetTextureClien
   if (mAvailableTextureClients.size()) {
     textureClient = mAvailableTextureClients.top();
     mAvailableTextureClients.pop();
     RECYCLE_LOG("%s Skip allocate (%i left), returning %p\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), mAvailableTextureClients.size(), textureClient.get());
 
   } else {
     // No unused clients in the pool, create one
     if (gfxPrefs::ForceShmemTiles()) {
-      textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator, mFormat, TEXTURE_IMMEDIATE_UPLOAD | TEXTURE_RECYCLE);
+      textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator,
+        mFormat, TEXTURE_IMMEDIATE_UPLOAD | TEXTURE_RECYCLE, gfx::BackendType::NONE);
     } else {
-      textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator, mFormat, TEXTURE_FLAGS_DEFAULT | TEXTURE_RECYCLE, mSize);
+      textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator,
+        mFormat, TEXTURE_FLAGS_DEFAULT | TEXTURE_RECYCLE, gfx::BackendType::NONE, mSize);
     }
     if (!textureClient->AsTextureClientDrawTarget()->AllocateForSurface(mSize, ALLOC_DEFAULT)) {
       NS_WARNING("TextureClient::AllocateForSurface failed!");
     }
     RECYCLE_LOG("%s Must allocate (0 left), returning %p\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), textureClient.get());
   }
 
   if (aAutoRecycle) {
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -274,43 +274,54 @@ DisableGralloc(SurfaceFormat aFormat)
 }
 #endif
 
 // static
 TemporaryRef<TextureClient>
 TextureClient::CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator,
                                              SurfaceFormat aFormat,
                                              TextureFlags aTextureFlags,
+                                             gfx::BackendType aMoz2DBackend,
                                              const gfx::IntSize& aSizeHint)
 {
+  if (aMoz2DBackend == gfx::BackendType::NONE) {
+    aMoz2DBackend = gfxPlatform::GetPlatform()->GetContentBackend();
+  }
+
   RefPtr<TextureClient> result;
 
 #ifdef XP_WIN
   LayersBackend parentBackend = aAllocator->GetCompositorBackendType();
-  if (parentBackend == LayersBackend::LAYERS_D3D11 && gfxWindowsPlatform::GetPlatform()->GetD2DDevice() &&
+  if (parentBackend == LayersBackend::LAYERS_D3D11 &&
+      (aMoz2DBackend == gfx::BackendType::DIRECT2D ||
+        aMoz2DBackend == gfx::BackendType::DIRECT2D1_1) &&
+      gfxWindowsPlatform::GetPlatform()->GetD2DDevice() &&
+
       !(aTextureFlags & TEXTURE_ALLOC_FALLBACK)) {
     result = new TextureClientD3D11(aFormat, aTextureFlags);
   }
   if (parentBackend == LayersBackend::LAYERS_D3D9 &&
+      aMoz2DBackend == gfx::BackendType::CAIRO &&
       aAllocator->IsSameProcess() &&
       !(aTextureFlags & TEXTURE_ALLOC_FALLBACK)) {
     if (!gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
       result = new DIBTextureClientD3D9(aFormat, aTextureFlags);
     } else {
       result = new CairoTextureClientD3D9(aFormat, aTextureFlags);
     }
   }
 #endif
 
 #ifdef MOZ_X11
   LayersBackend parentBackend = aAllocator->GetCompositorBackendType();
   gfxSurfaceType type =
     gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType();
 
   if (parentBackend == LayersBackend::LAYERS_BASIC &&
+      aMoz2DBackend == gfx::BackendType::CAIRO &&
       type == gfxSurfaceType::Xlib &&
       !(aTextureFlags & TEXTURE_ALLOC_FALLBACK))
   {
     result = new TextureClientX11(aFormat, aTextureFlags);
   }
 #ifdef GL_PROVIDER_GLX
 #if 0
   // Bug 977963: Disabled for black layers
@@ -327,43 +338,47 @@ TextureClient::CreateTextureClientForDra
 #endif
 
 #ifdef MOZ_WIDGET_GONK
   if (!DisableGralloc(aFormat)) {
     // Don't allow Gralloc texture clients to exceed the maximum texture size.
     // BufferTextureClients have code to handle tiling the surface client-side.
     int32_t maxTextureSize = aAllocator->GetMaxTextureSize();
     if (aSizeHint.width <= maxTextureSize && aSizeHint.height <= maxTextureSize) {
-      result = new GrallocTextureClientOGL(aAllocator, aFormat, aTextureFlags);
+      result = new GrallocTextureClientOGL(aAllocator, aFormat, aMoz2DBackend,
+                                           aTextureFlags);
     }
   }
 #endif
 
   // Can't do any better than a buffer texture client.
   if (!result) {
-    result = CreateBufferTextureClient(aAllocator, aFormat, aTextureFlags);
+    result = CreateBufferTextureClient(aAllocator, aFormat, aTextureFlags, aMoz2DBackend);
   }
 
   MOZ_ASSERT(!result || result->AsTextureClientDrawTarget(),
              "Not a TextureClientDrawTarget?");
   return result;
 }
 
 // static
 TemporaryRef<BufferTextureClient>
 TextureClient::CreateBufferTextureClient(ISurfaceAllocator* aAllocator,
                                          SurfaceFormat aFormat,
-                                         TextureFlags aTextureFlags)
+                                         TextureFlags aTextureFlags,
+                                         gfx::BackendType aMoz2DBackend)
 {
   if (gfxPlatform::GetPlatform()->PreferMemoryOverShmem()) {
     RefPtr<BufferTextureClient> result = new MemoryTextureClient(aAllocator, aFormat,
+                                                                 aMoz2DBackend,
                                                                  aTextureFlags);
     return result.forget();
   }
   RefPtr<BufferTextureClient> result = new ShmemTextureClient(aAllocator, aFormat,
+                                                              aMoz2DBackend,
                                                               aTextureFlags);
   return result.forget();
 }
 
 
 class ShmemTextureClientData : public TextureClientData
 {
 public:
@@ -557,18 +572,19 @@ size_t
 ShmemTextureClient::GetBufferSize() const
 {
   MOZ_ASSERT(IsValid());
   return mShmem.Size<uint8_t>();
 }
 
 ShmemTextureClient::ShmemTextureClient(ISurfaceAllocator* aAllocator,
                                        gfx::SurfaceFormat aFormat,
+                                       gfx::BackendType aMoz2DBackend,
                                        TextureFlags aFlags)
-  : BufferTextureClient(aAllocator, aFormat, aFlags)
+  : BufferTextureClient(aAllocator, aFormat, aMoz2DBackend, aFlags)
   , mAllocated(false)
 {
   MOZ_COUNT_CTOR(ShmemTextureClient);
 }
 
 ShmemTextureClient::~ShmemTextureClient()
 {
   MOZ_COUNT_DTOR(ShmemTextureClient);
@@ -603,18 +619,19 @@ MemoryTextureClient::Allocate(uint32_t a
   }
   GfxMemoryImageReporter::DidAlloc(mBuffer);
   mBufSize = aSize;
   return true;
 }
 
 MemoryTextureClient::MemoryTextureClient(ISurfaceAllocator* aAllocator,
                                          gfx::SurfaceFormat aFormat,
+                                         gfx::BackendType aMoz2DBackend,
                                          TextureFlags aFlags)
-  : BufferTextureClient(aAllocator, aFormat, aFlags)
+  : BufferTextureClient(aAllocator, aFormat, aMoz2DBackend, aFlags)
   , mBuffer(nullptr)
   , mBufSize(0)
 {
   MOZ_COUNT_CTOR(MemoryTextureClient);
 }
 
 MemoryTextureClient::~MemoryTextureClient()
 {
@@ -624,20 +641,23 @@ MemoryTextureClient::~MemoryTextureClien
     // leak.
     GfxMemoryImageReporter::WillFree(mBuffer);
     delete mBuffer;
   }
 }
 
 BufferTextureClient::BufferTextureClient(ISurfaceAllocator* aAllocator,
                                          gfx::SurfaceFormat aFormat,
+                                         gfx::BackendType aMoz2DBackend,
                                          TextureFlags aFlags)
   : TextureClient(aFlags)
   , mAllocator(aAllocator)
   , mFormat(aFormat)
+  , mBackend(aMoz2DBackend)
+  , mOpenMode(0)
   , mUsingFallbackDrawTarget(false)
   , mLocked(false)
 {}
 
 BufferTextureClient::~BufferTextureClient()
 {}
 
 ISurfaceAllocator*
@@ -736,25 +756,25 @@ BufferTextureClient::GetAsDrawTarget()
   }
 
   ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
   if (!serializer.IsValid()) {
     return nullptr;
   }
 
   MOZ_ASSERT(mUsingFallbackDrawTarget == false);
-  mDrawTarget = serializer.GetAsDrawTarget();
+  mDrawTarget = serializer.GetAsDrawTarget(mBackend);
   if (mDrawTarget) {
     return mDrawTarget;
   }
 
   // fallback path, probably because the Moz2D backend can't create a
   // DrawTarget around raw memory. This is going to be slow :(
-  mDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
-    serializer.GetSize(), serializer.GetFormat());
+  mDrawTarget = gfx::Factory::CreateDrawTarget(mBackend, serializer.GetSize(),
+                                               serializer.GetFormat());
   if (!mDrawTarget) {
     return nullptr;
   }
 
   mUsingFallbackDrawTarget = true;
   if (mOpenMode & OPEN_READ) {
     RefPtr<DataSourceSurface> surface = serializer.GetAsSurface();
     IntRect rect(0, 0, surface->GetSize().width, surface->GetSize().height);
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -197,22 +197,24 @@ class TextureClient
 {
 public:
   TextureClient(TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
   virtual ~TextureClient();
 
   static TemporaryRef<BufferTextureClient>
   CreateBufferTextureClient(ISurfaceAllocator* aAllocator,
                             gfx::SurfaceFormat aFormat,
-                            TextureFlags aTextureFlags);
+                            TextureFlags aTextureFlags,
+                            gfx::BackendType aMoz2dBackend);
 
   static TemporaryRef<TextureClient>
   CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator,
                                 gfx::SurfaceFormat aFormat,
                                 TextureFlags aTextureFlags,
+                                gfx::BackendType aMoz2dBackend,
                                 const gfx::IntSize& aSizeHint);
 
   virtual TextureClientSurface* AsTextureClientSurface() { return nullptr; }
   virtual TextureClientDrawTarget* AsTextureClientDrawTarget() { return nullptr; }
   virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; }
 
   /**
    * Locks the shared data, allowing the caller to get access to it.
@@ -388,17 +390,17 @@ protected:
  */
 class BufferTextureClient : public TextureClient
                           , public TextureClientSurface
                           , public TextureClientYCbCr
                           , public TextureClientDrawTarget
 {
 public:
   BufferTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
-                      TextureFlags aFlags);
+                      gfx::BackendType aBackend, TextureFlags aFlags);
 
   virtual ~BufferTextureClient();
 
   virtual bool IsAllocated() const = 0;
 
   virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
 
   virtual uint8_t* GetBuffer() const = 0;
@@ -452,30 +454,31 @@ public:
 
   ISurfaceAllocator* GetAllocator() const;
 
 protected:
   RefPtr<gfx::DrawTarget> mDrawTarget;
   RefPtr<ISurfaceAllocator> mAllocator;
   gfx::SurfaceFormat mFormat;
   gfx::IntSize mSize;
+  gfx::BackendType mBackend;
   OpenMode mOpenMode;
   bool mUsingFallbackDrawTarget;
   bool mLocked;
 };
 
 /**
  * TextureClient that wraps shared memory.
  * the corresponding texture on the host side is ShmemTextureHost.
  */
 class ShmemTextureClient : public BufferTextureClient
 {
 public:
   ShmemTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
-                     TextureFlags aFlags);
+                     gfx::BackendType aBackend, TextureFlags aFlags);
 
   ~ShmemTextureClient();
 
   virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
 
   virtual bool Allocate(uint32_t aSize) MOZ_OVERRIDE;
 
   virtual uint8_t* GetBuffer() const MOZ_OVERRIDE;
@@ -499,17 +502,17 @@ protected:
  * TextureClient that wraps raw memory.
  * The corresponding texture on the host side is MemoryTextureHost.
  * Can obviously not be used in a cross process setup.
  */
 class MemoryTextureClient : public BufferTextureClient
 {
 public:
   MemoryTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
-                      TextureFlags aFlags);
+                      gfx::BackendType aBackend, TextureFlags aFlags);
 
   ~MemoryTextureClient();
 
   virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
 
   virtual bool Allocate(uint32_t aSize) MOZ_OVERRIDE;
 
   virtual uint8_t* GetBuffer() const MOZ_OVERRIDE { return mBuffer; }
--- a/gfx/layers/client/TextureClientPool.cpp
+++ b/gfx/layers/client/TextureClientPool.cpp
@@ -44,19 +44,22 @@ TextureClientPool::GetTextureClient()
   }
 
   // We're increasing the number of outstanding TextureClients without reusing a
   // client, we may need to free a deferred-return TextureClient.
   ShrinkToMaximumSize();
 
   // No unused clients in the pool, create one
   if (gfxPrefs::ForceShmemTiles()) {
-    textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator, mFormat, TEXTURE_IMMEDIATE_UPLOAD);
+    // gfx::BackendType::NONE means use the content backend
+    textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator,
+      mFormat, TEXTURE_IMMEDIATE_UPLOAD, gfx::BackendType::NONE);
   } else {
-    textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator, mFormat, TEXTURE_IMMEDIATE_UPLOAD, mSize);
+    textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator,
+      mFormat, TEXTURE_IMMEDIATE_UPLOAD, gfx::BackendType::NONE, mSize);
   }
   textureClient->AsTextureClientDrawTarget()->AllocateForSurface(mSize, ALLOC_DEFAULT);
 
   return textureClient;
 }
 
 void
 TextureClientPool::ReturnTextureClient(TextureClient *aClient)
--- a/gfx/layers/opengl/GrallocTextureClient.cpp
+++ b/gfx/layers/opengl/GrallocTextureClient.cpp
@@ -87,28 +87,30 @@ GrallocTextureClientOGL::DropTextureData
     mGrallocActor = nullptr;
     mGraphicBuffer = nullptr;
     return result;
   }
 }
 
 GrallocTextureClientOGL::GrallocTextureClientOGL(GrallocBufferActor* aActor,
                                                  gfx::IntSize aSize,
+                                                 gfx::BackendType aMoz2dBackend,
                                                  TextureFlags aFlags)
-: BufferTextureClient(nullptr, gfx::SurfaceFormat::UNKNOWN, aFlags)
+: BufferTextureClient(nullptr, gfx::SurfaceFormat::UNKNOWN, aMoz2dBackend, aFlags)
 , mMappedBuffer(nullptr)
 {
   InitWith(aActor, aSize);
   MOZ_COUNT_CTOR(GrallocTextureClientOGL);
 }
 
 GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
                                                  gfx::SurfaceFormat aFormat,
+                                                 gfx::BackendType aMoz2dBackend,
                                                  TextureFlags aFlags)
-: BufferTextureClient(aAllocator, aFormat, aFlags)
+: BufferTextureClient(aAllocator, aFormat, aMoz2dBackend, aFlags)
 , mMappedBuffer(nullptr)
 {
   MOZ_COUNT_CTOR(GrallocTextureClientOGL);
 }
 
 GrallocTextureClientOGL::~GrallocTextureClientOGL()
 {
   MOZ_COUNT_DTOR(GrallocTextureClientOGL);
--- a/gfx/layers/opengl/GrallocTextureClient.h
+++ b/gfx/layers/opengl/GrallocTextureClient.h
@@ -31,19 +31,21 @@ class GraphicBufferLocked;
  *
  * This is only used in Firefox OS
  */
 class GrallocTextureClientOGL : public BufferTextureClient
 {
 public:
   GrallocTextureClientOGL(GrallocBufferActor* aActor,
                           gfx::IntSize aSize,
+                          gfx::BackendType aMoz2dBackend,
                           TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
   GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
                           gfx::SurfaceFormat aFormat,
+                          gfx::BackendType aMoz2dBackend,
                           TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
 
   ~GrallocTextureClientOGL();
 
   virtual bool Lock(OpenMode aMode) MOZ_OVERRIDE;
 
   virtual void Unlock() MOZ_OVERRIDE;
 
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -214,16 +214,17 @@ TEST(Layers, TextureSerialization) {
   for (int f = 0; f < 3; ++f) {
     RefPtr<gfxImageSurface> surface = new gfxImageSurface(gfxIntSize(400,300), formats[f]);
     SetupSurface(surface.get());
     AssertSurfacesEqual(surface, surface);
 
     RefPtr<TextureClient> client
       = new MemoryTextureClient(nullptr,
                                 mozilla::gfx::ImageFormatToSurfaceFormat(surface->Format()),
+                                gfx::BackendType::CAIRO,
                                 TEXTURE_DEALLOCATE_CLIENT);
 
     TestTextureClientSurface(client, surface);
 
     // XXX - Test more texture client types.
   }
 }
 
@@ -250,14 +251,15 @@ TEST(Layers, TextureYCbCrSerialization) 
   clientData.mCrSkip = 0;
   clientData.mCrSkip = 0;
   clientData.mPicX = 0;
   clientData.mPicX = 0;
 
   RefPtr<TextureClient> client
     = new MemoryTextureClient(nullptr,
                               mozilla::gfx::SurfaceFormat::YUV,
+                              gfx::BackendType::CAIRO,
                               TEXTURE_DEALLOCATE_CLIENT);
 
   TestTextureClientYCbCr(client, clientData);
 
   // XXX - Test more texture client types.
 }
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -288,16 +288,20 @@ public:
 
     void GetAzureBackendInfo(mozilla::widget::InfoObject &aObj) {
       aObj.DefineProperty("AzureCanvasBackend", GetBackendName(mPreferredCanvasBackend));
       aObj.DefineProperty("AzureSkiaAccelerated", UseAcceleratedSkiaCanvas());
       aObj.DefineProperty("AzureFallbackCanvasBackend", GetBackendName(mFallbackCanvasBackend));
       aObj.DefineProperty("AzureContentBackend", GetBackendName(mContentBackend));
     }
 
+    mozilla::gfx::BackendType GetContentBackend() {
+      return mContentBackend;
+    }
+
     mozilla::gfx::BackendType GetPreferredCanvasBackend() {
       return mPreferredCanvasBackend;
     }
 
     /*
      * Font bits
      */
 
@@ -646,20 +650,16 @@ protected:
      */
     static mozilla::gfx::BackendType GetBackendPref(const char* aBackendPrefName,
                                                     uint32_t &aBackendBitmask);
     /**
      * Decode the backend enumberation from a string.
      */
     static mozilla::gfx::BackendType BackendTypeForName(const nsCString& aName);
 
-    mozilla::gfx::BackendType GetContentBackend() {
-      return mContentBackend;
-    }
-
     static mozilla::TemporaryRef<mozilla::gfx::ScaledFont>
       GetScaledFontForFontWithCairoSkia(mozilla::gfx::DrawTarget* aTarget, gfxFont* aFont);
 
     int8_t  mAllowDownloadableFonts;
     int8_t  mGraphiteShapingEnabled;
     int8_t  mOpenTypeSVGEnabled;
 
     int8_t  mBidiNumeralOption;