Bug 973892 - part 2) Specify the moz2d backend when creating a TextureClient. r=Bas
☠☠ backed out by 995cfd42e045 ☠ ☠
authorNicolas Silva <nical@mozilla.com>
Wed, 19 Feb 2014 18:17:49 +0100
changeset 169895 2784838dbc94b2a2155bab798888e89353cdcd42
parent 169894 6364146ddb194ab29bf85da34684d790bb033f52
child 169896 bb77326af1337a4eb7377fd894162e459f4c49a1
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersBas
bugs973892
milestone30.0a1
Bug 973892 - part 2) Specify the moz2d backend when creating a TextureClient. r=Bas
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CanvasClient.h
gfx/layers/client/CompositableClient.cpp
gfx/layers/client/CompositableClient.h
gfx/layers/client/ImageClient.cpp
gfx/layers/client/ImageClient.h
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/tests/gtest/TestTextures.cpp
--- 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;
@@ -95,20 +97,22 @@ CanvasClient2D::Update(gfx::IntSize aSiz
 
   if (updated) {
     GetForwarder()->UpdatedTexture(this, mBuffer, nullptr);
     GetForwarder()->UseTexture(this, mBuffer);
   }
 }
 
 TemporaryRef<BufferTextureClient>
-CanvasClient2D::CreateBufferTextureClient(gfx::SurfaceFormat aFormat, TextureFlags aFlags)
+CanvasClient2D::CreateBufferTextureClient(gfx::SurfaceFormat aFormat, TextureFlags aFlags,
+                                          gfx::BackendType aMoz2DBackend)
 {
   return CompositableClient::CreateBufferTextureClient(aFormat,
-                                                       mTextureInfo.mTextureFlags | aFlags);
+                                                       mTextureInfo.mTextureFlags | aFlags,
+                                                       aMoz2DBackend);
 }
 
 CanvasClientSurfaceStream::CanvasClientSurfaceStream(CompositableForwarder* aLayerForwarder,
                                                      TextureFlags aFlags)
   : CanvasClient(aLayerForwarder, aFlags)
 {
 }
 
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -85,17 +85,18 @@ public:
   virtual bool AddTextureClient(TextureClient* aTexture) MOZ_OVERRIDE
   {
     MOZ_ASSERT((mTextureInfo.mTextureFlags & aTexture->GetFlags()) == mTextureInfo.mTextureFlags);
     return CompositableClient::AddTextureClient(aTexture);
   }
 
   virtual TemporaryRef<BufferTextureClient>
   CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
-                            TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT) MOZ_OVERRIDE;
+                            TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT,
+                            gfx::BackendType aMoz2DBackend = gfx::BackendType::NONE) MOZ_OVERRIDE;
 
   virtual void OnDetach() MOZ_OVERRIDE
   {
     mBuffer = nullptr;
   }
 
 private:
   RefPtr<TextureClient> mBuffer;
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -174,33 +174,38 @@ 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)
 {
 // XXX - Once bug 908196 is fixed, we can use gralloc textures here which will
 // improve performances of videos using SharedPlanarYCbCrImage on b2g.
 //#ifdef MOZ_WIDGET_GONK
 //  {
 //    RefPtr<BufferTextureClient> result = new GrallocTextureClientOGL(this,
 //                                                                     aFormat,
 //                                                                     aTextureFlags);
 //    return result.forget();
 //  }
 //#endif
   if (gfxPlatform::GetPlatform()->PreferMemoryOverShmem()) {
-    RefPtr<BufferTextureClient> result = new MemoryTextureClient(this, aFormat, aTextureFlags);
+    RefPtr<BufferTextureClient> result = new MemoryTextureClient(this, aFormat,
+                                                                 aMoz2DBackend,
+                                                                 aTextureFlags);
     return result.forget();
   }
-  RefPtr<BufferTextureClient> result = new ShmemTextureClient(this, aFormat, aTextureFlags);
+  RefPtr<BufferTextureClient> result = new ShmemTextureClient(this, aFormat,
+                                                              aMoz2DBackend,
+                                                              aTextureFlags);
   return result.forget();
 }
 
 #ifdef MOZ_WIDGET_GONK
 static bool
 DisableGralloc(SurfaceFormat aFormat)
 {
   if (aFormat == gfx::SurfaceFormat::A8) {
@@ -229,50 +234,61 @@ DisableGralloc(SurfaceFormat aFormat)
 #else
   return false;
 #endif
 }
 #endif
 
 TemporaryRef<TextureClient>
 CompositableClient::CreateTextureClientForDrawing(SurfaceFormat aFormat,
-                                                  TextureFlags aTextureFlags)
+                                                  TextureFlags aTextureFlags,
+                                                  gfx::BackendType aMoz2DBackend)
 {
+  if (aMoz2DBackend == gfx::BackendType::NONE) {
+    aMoz2DBackend = gfxPlatform::GetPlatform()->GetContentBackend();
+  }
+
   RefPtr<TextureClient> result;
 
 #ifdef XP_WIN
   LayersBackend parentBackend = GetForwarder()->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 &&
       !GetForwarder()->ForwardsToDifferentProcess() &&
       !(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 = GetForwarder()->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 (parentBackend == LayersBackend::LAYERS_OPENGL &&
+      aMoz2DBackend == gfx::BackendType::CAIRO &&
       type == gfxSurfaceType::Xlib &&
       !(aTextureFlags & TEXTURE_ALLOC_FALLBACK) &&
       aFormat != SurfaceFormat::A8 &&
       gl::sGLXLibrary.UseTextureFromPixmap())
   {
     result = new TextureClientX11(aFormat, aTextureFlags);
   }
 #endif
@@ -281,17 +297,17 @@ CompositableClient::CreateTextureClientF
 #ifdef MOZ_WIDGET_GONK
   if (!DisableGralloc(aFormat)) {
     result = new GrallocTextureClientOGL(this, aFormat, aTextureFlags);
   }
 #endif
 
   // Can't do any better than a buffer texture client.
   if (!result) {
-    result = CreateBufferTextureClient(aFormat, aTextureFlags);
+    result = CreateBufferTextureClient(aFormat, aTextureFlags, aMoz2DBackend);
   }
 
   MOZ_ASSERT(!result || result->AsTextureClientDrawTarget(),
              "Not a TextureClientDrawTarget?");
   return result;
 }
 
 bool
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -79,25 +79,32 @@ public:
   virtual TextureInfo GetTextureInfo() const = 0;
 
   LayersBackend GetCompositorBackendType() const;
 
   TemporaryRef<DeprecatedTextureClient>
   CreateDeprecatedTextureClient(DeprecatedTextureClientType aDeprecatedTextureClientType,
                                 gfxContentType aContentType = gfxContentType::SENTINEL);
 
+  // Creates a TextureClient that can be mapped in memory and access through a
+  // raw pointer.
+  // Generally it is best to use CreateTextureClientForDrawing and draw into
+  // the texture through Moz2D.
   virtual 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.
+  // If aBackend is NONE, default to the content backend type.
   TemporaryRef<TextureClient>
   CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat,
-                                TextureFlags aTextureFlags);
+                                TextureFlags aTextureFlags,
+                                gfx::BackendType aMoz2DBackend = gfx::BackendType::NONE);
 
   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/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -306,19 +306,21 @@ ImageClientBuffered::UpdateImage(ImageCo
 bool
 ImageClientSingle::AddTextureClient(TextureClient* aTexture)
 {
   MOZ_ASSERT((mTextureFlags & aTexture->GetFlags()) == mTextureFlags);
   return CompositableClient::AddTextureClient(aTexture);
 }
 
 TemporaryRef<BufferTextureClient>
-ImageClientSingle::CreateBufferTextureClient(gfx::SurfaceFormat aFormat, TextureFlags aFlags)
+ImageClientSingle::CreateBufferTextureClient(gfx::SurfaceFormat aFormat, TextureFlags aFlags,
+                                             gfx::BackendType aMoz2DBackend)
 {
-  return CompositableClient::CreateBufferTextureClient(aFormat, mTextureFlags | aFlags);
+  return CompositableClient::CreateBufferTextureClient(aFormat, mTextureFlags | aFlags,
+                                                        aMoz2DBackend);
 }
 
 void
 ImageClientSingle::OnDetach()
 {
   mFrontBuffer = nullptr;
 }
 
--- a/gfx/layers/client/ImageClient.h
+++ b/gfx/layers/client/ImageClient.h
@@ -87,17 +87,18 @@ public:
   virtual bool UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags);
 
   virtual void OnDetach() MOZ_OVERRIDE;
 
   virtual bool AddTextureClient(TextureClient* aTexture) MOZ_OVERRIDE;
 
   virtual TemporaryRef<BufferTextureClient>
   CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
-                            TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT) MOZ_OVERRIDE;
+                            TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT,
+                            gfx::BackendType aMoz2DBackend = gfx::BackendType::NONE) MOZ_OVERRIDE;
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE;
 
   virtual already_AddRefed<Image> CreateImage(ImageFormat aFormat) MOZ_OVERRIDE;
 
   virtual void FlushAllImages(bool aExceptFront) MOZ_OVERRIDE;
 
 protected:
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -360,18 +360,19 @@ size_t
 ShmemTextureClient::GetBufferSize() const
 {
   MOZ_ASSERT(IsValid());
   return mShmem.Size<uint8_t>();
 }
 
 ShmemTextureClient::ShmemTextureClient(CompositableClient* aCompositable,
                                        gfx::SurfaceFormat aFormat,
+                                       gfx::BackendType aBackend,
                                        TextureFlags aFlags)
-  : BufferTextureClient(aCompositable, aFormat, aFlags)
+  : BufferTextureClient(aCompositable, aFormat, aBackend, aFlags)
   , mAllocated(false)
 {
   MOZ_COUNT_CTOR(ShmemTextureClient);
 }
 
 ShmemTextureClient::~ShmemTextureClient()
 {
   MOZ_COUNT_DTOR(ShmemTextureClient);
@@ -406,18 +407,19 @@ MemoryTextureClient::Allocate(uint32_t a
   }
   GfxMemoryImageReporter::DidAlloc(mBuffer);
   mBufSize = aSize;
   return true;
 }
 
 MemoryTextureClient::MemoryTextureClient(CompositableClient* aCompositable,
                                          gfx::SurfaceFormat aFormat,
+                                         gfx::BackendType aBackend,
                                          TextureFlags aFlags)
-  : BufferTextureClient(aCompositable, aFormat, aFlags)
+  : BufferTextureClient(aCompositable, aFormat, aBackend, aFlags)
   , mBuffer(nullptr)
   , mBufSize(0)
 {
   MOZ_COUNT_CTOR(MemoryTextureClient);
 }
 
 MemoryTextureClient::~MemoryTextureClient()
 {
@@ -427,20 +429,22 @@ MemoryTextureClient::~MemoryTextureClien
     // leak.
     GfxMemoryImageReporter::WillFree(mBuffer);
     delete mBuffer;
   }
 }
 
 BufferTextureClient::BufferTextureClient(CompositableClient* aCompositable,
                                          gfx::SurfaceFormat aFormat,
+                                         gfx::BackendType aBackend,
                                          TextureFlags aFlags)
   : TextureClient(aFlags)
   , mCompositable(aCompositable)
   , mFormat(aFormat)
+  , mBackend(aBackend)
   , mUsingFallbackDrawTarget(false)
   , mLocked(false)
 {}
 
 BufferTextureClient::~BufferTextureClient()
 {}
 
 bool
@@ -533,25 +537,25 @@ BufferTextureClient::GetAsDrawTarget()
   }
 
   ImageDataSerializer serializer(GetBuffer());
   if (!serializer.IsValid()) {
     return nullptr;
   }
 
   MOZ_ASSERT(mUsingFallbackDrawTarget == false);
-  mDrawTarget = serializer.GetAsDrawTarget(gfxPlatform::GetPlatform()->GetContentBackend());
+  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
@@ -336,17 +336,17 @@ protected:
  */
 class BufferTextureClient : public TextureClient
                           , public TextureClientSurface
                           , public TextureClientYCbCr
                           , public TextureClientDrawTarget
 {
 public:
   BufferTextureClient(CompositableClient* aCompositable, 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;
@@ -396,30 +396,31 @@ public:
 
   virtual size_t GetBufferSize() const = 0;
 
 protected:
   RefPtr<gfx::DrawTarget> mDrawTarget;
   CompositableClient* mCompositable;
   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(CompositableClient* aCompositable, 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;
@@ -444,17 +445,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(CompositableClient* aCompositable, 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/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::NONE,
                                 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::NONE,
                               TEXTURE_DEALLOCATE_CLIENT);
 
   TestTextureClientYCbCr(client, clientData);
 
   // XXX - Test more texture client types.
 }