Bug 1265824 - pass the texture direct mapping info to all texture creating functions. draft
authorDoug Thayer <dothayer@mozilla.com>
Wed, 02 May 2018 18:30:54 -0700
changeset 798383 b366fc0e9b5b1a69660ec87ff1339c0cb5584063
parent 798382 7714b8b7447017839daa5e6f5a9a0b02bcea8b74
child 798384 c8a5402efcd3001e695b715364eb97628361e08f
push id110743
push userbmo:dothayer@mozilla.com
push dateTue, 22 May 2018 19:24:40 +0000
bugs1265824
milestone62.0a1
Bug 1265824 - pass the texture direct mapping info to all texture creating functions.
gfx/layers/BufferTexture.cpp
gfx/layers/BufferTexture.h
gfx/layers/TextureDIB.cpp
gfx/layers/basic/TextureClientX11.cpp
gfx/layers/basic/TextureClientX11.h
gfx/layers/client/ContentClient.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/client/TextureClientPool.cpp
gfx/layers/client/TextureClientPool.h
gfx/layers/d3d11/TextureD3D11.cpp
gfx/layers/d3d11/TextureD3D11.h
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
gfx/tests/gtest/TestTextures.cpp
gfx/tests/gtest/TextureHelper.h
--- a/gfx/layers/BufferTexture.cpp
+++ b/gfx/layers/BufferTexture.cpp
@@ -23,21 +23,23 @@ namespace layers {
 class MemoryTextureData : public BufferTextureData
 {
 public:
   static MemoryTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                                    gfx::BackendType aMoz2DBackend,
                                    LayersBackend aLayersBackend,
                                    TextureFlags aFlags,
                                    TextureAllocationFlags aAllocFlags,
-                                   LayersIPCChannel* aAllocator);
+                                   LayersIPCChannel* aAllocator,
+                                   bool aSupportsTextireDirectMapping);
 
   virtual TextureData*
   CreateSimilar(LayersIPCChannel* aAllocator,
                 LayersBackend aLayersBackend,
+                bool aSupportsTextureDirectMapping,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
 
   virtual void Deallocate(LayersIPCChannel*) override;
 
   MemoryTextureData(const BufferDescriptor& aDesc,
@@ -63,21 +65,23 @@ protected:
 class ShmemTextureData : public BufferTextureData
 {
 public:
   static ShmemTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                                   gfx::BackendType aMoz2DBackend,
                                   LayersBackend aLayersBackend,
                                   TextureFlags aFlags,
                                   TextureAllocationFlags aAllocFlags,
-                                  LayersIPCChannel* aAllocator);
+                                  LayersIPCChannel* aAllocator,
+                                  bool aSupportsTextireDirectMapping);
 
   virtual TextureData*
   CreateSimilar(LayersIPCChannel* aAllocator,
                 LayersBackend aLayersBackend,
+                bool aSupportsTextureDirectMapping,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
 
   virtual void Deallocate(LayersIPCChannel* aAllocator) override;
 
   ShmemTextureData(const BufferDescriptor& aDesc,
@@ -100,38 +104,46 @@ static bool UsingX11Compositor()
 {
 #ifdef MOZ_WIDGET_GTK
   return gfx::gfxVars::UseXRender();
 #endif
   return false;
 }
 
 bool ComputeHasIntermediateBuffer(gfx::SurfaceFormat aFormat,
-                                  LayersBackend aLayersBackend)
+                                  LayersBackend aLayersBackend,
+                                  bool aSupportsTextureDirectMapping)
 {
+  if (aSupportsTextureDirectMapping) {
+    return false;
+  }
+
   return aLayersBackend != LayersBackend::LAYERS_BASIC
       || UsingX11Compositor()
       || aFormat == gfx::SurfaceFormat::UNKNOWN;
 }
 
 BufferTextureData*
 BufferTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                           gfx::BackendType aMoz2DBackend,
                           LayersBackend aLayersBackend, TextureFlags aFlags,
                           TextureAllocationFlags aAllocFlags,
-                          LayersIPCChannel* aAllocator)
+                          LayersIPCChannel* aAllocator,
+                          bool aSupportsTextureDirectMapping)
 {
   if (!aAllocator || aAllocator->IsSameProcess()) {
     return MemoryTextureData::Create(aSize, aFormat, aMoz2DBackend,
                                      aLayersBackend, aFlags,
-                                     aAllocFlags, aAllocator);
+                                     aAllocFlags, aAllocator,
+                                     aSupportsTextureDirectMapping);
   } else {
     return ShmemTextureData::Create(aSize, aFormat, aMoz2DBackend,
                                     aLayersBackend, aFlags,
-                                    aAllocFlags, aAllocator);
+                                    aAllocFlags, aAllocator,
+                                    aSupportsTextureDirectMapping);
   }
 }
 
 BufferTextureData*
 BufferTextureData::CreateInternal(LayersIPCChannel* aAllocator,
                                   const BufferDescriptor& aDesc,
                                   gfx::BackendType aMoz2DBackend,
                                   int32_t aBufferSize,
@@ -163,17 +175,18 @@ BufferTextureData::CreateForYCbCrWithBuf
                                                 uint32_t aBitDepth,
                                                 TextureFlags aTextureFlags)
 {
   if (aBufferSize == 0 || !gfx::Factory::CheckBufferSize(aBufferSize)) {
     return nullptr;
   }
 
   bool hasIntermediateBuffer = aAllocator ? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
-                                                                         aAllocator->GetCompositorBackendType())
+                                                                         aAllocator->GetCompositorBackendType(),
+                                                                         aAllocator->SupportsTextureDirectMapping())
                                           : true;
 
   // Initialize the metadata with something, even if it will have to be rewritten
   // afterwards since we don't know the dimensions of the texture at this point.
   BufferDescriptor desc = YCbCrDescriptor(gfx::IntSize(), 0, gfx::IntSize(), 0,
                                           0, 0, 0, StereoMode::MONO,
                                           aYUVColorSpace,
                                           aBitDepth,
@@ -205,17 +218,18 @@ BufferTextureData::CreateForYCbCr(KnowsC
   uint32_t crOffset;
   ImageDataSerializer::ComputeYCbCrOffsets(aYStride, aYSize.height,
                                            aCbCrStride, aCbCrSize.height,
                                            yOffset, cbOffset, crOffset);
 
   bool hasIntermediateBuffer =
     aAllocator
       ? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
-                                     aAllocator->GetCompositorBackendType())
+                                     aAllocator->GetCompositorBackendType(),
+                                     aAllocator->SupportsTextureDirectMapping())
       : true;
 
   YCbCrDescriptor descriptor = YCbCrDescriptor(aYSize, aYStride,
                                                aCbCrSize, aCbCrStride,
                                                yOffset, cbOffset, crOffset,
                                                aStereoMode,
                                                aYUVColorSpace,
                                                aBitDepth,
@@ -500,17 +514,18 @@ InitBuffer(uint8_t* buf, size_t bufSize,
   return true;
 }
 
 MemoryTextureData*
 MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                           gfx::BackendType aMoz2DBackend,
                           LayersBackend aLayersBackend, TextureFlags aFlags,
                           TextureAllocationFlags aAllocFlags,
-                          LayersIPCChannel* aAllocator)
+                          LayersIPCChannel* aAllocator,
+                          bool aSupportsTextureDirectMapping)
 {
   // Should have used CreateForYCbCr.
   MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);
 
   if (aSize.width <= 0 || aSize.height <= 0) {
     gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
     return nullptr;
   }
@@ -520,17 +535,19 @@ MemoryTextureData::Create(gfx::IntSize a
     return nullptr;
   }
 
   uint8_t* buf = new (fallible) uint8_t[bufSize];
   if (!InitBuffer(buf, bufSize, aFormat, aAllocFlags, false)) {
     return nullptr;
   }
 
-  bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(aFormat, aLayersBackend);
+  bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(aFormat,
+                                                            aLayersBackend,
+                                                            aSupportsTextureDirectMapping);
 
   GfxMemoryImageReporter::DidAlloc(buf);
 
   BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasIntermediateBuffer);
 
   return new MemoryTextureData(descriptor, aMoz2DBackend, buf, bufSize);
 }
 
@@ -541,21 +558,23 @@ MemoryTextureData::Deallocate(LayersIPCC
   GfxMemoryImageReporter::WillFree(mBuffer);
   delete [] mBuffer;
   mBuffer = nullptr;
 }
 
 TextureData*
 MemoryTextureData::CreateSimilar(LayersIPCChannel* aAllocator,
                                  LayersBackend aLayersBackend,
+                                 bool aSupportsTextureDirectMapping,
                                  TextureFlags aFlags,
                                  TextureAllocationFlags aAllocFlags) const
 {
   return MemoryTextureData::Create(GetSize(), GetFormat(), mMoz2DBackend,
-                                   aLayersBackend, aFlags, aAllocFlags, aAllocator);
+                                   aLayersBackend, aFlags, aAllocFlags, aAllocator,
+                                   aSupportsTextureDirectMapping);
 }
 
 bool
 ShmemTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
 {
   MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
   if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
     return false;
@@ -566,17 +585,18 @@ ShmemTextureData::Serialize(SurfaceDescr
   return true;
 }
 
 ShmemTextureData*
 ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                          gfx::BackendType aMoz2DBackend,
                          LayersBackend aLayersBackend, TextureFlags aFlags,
                          TextureAllocationFlags aAllocFlags,
-                         LayersIPCChannel* aAllocator)
+                         LayersIPCChannel* aAllocator,
+                         bool aSupportsTextureDirectMapping)
 {
   MOZ_ASSERT(aAllocator);
   // Should have used CreateForYCbCr.
   MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);
 
   if (!aAllocator) {
     return nullptr;
   }
@@ -596,33 +616,37 @@ ShmemTextureData::Create(gfx::IntSize aS
     return nullptr;
   }
 
   uint8_t* buf = shm.get<uint8_t>();
   if (!InitBuffer(buf, bufSize, aFormat, aAllocFlags, true)) {
     return nullptr;
   }
 
-  bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(aFormat, aLayersBackend);
+  bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(aFormat,
+                                                            aLayersBackend,
+                                                            aSupportsTextureDirectMapping);
 
   BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasIntermediateBuffer);
 
   return new ShmemTextureData(descriptor, aMoz2DBackend, shm);
 
   return nullptr;
 }
 
 TextureData*
 ShmemTextureData::CreateSimilar(LayersIPCChannel* aAllocator,
                                 LayersBackend aLayersBackend,
+                                bool aSupportsTextureDirectMapping,
                                 TextureFlags aFlags,
                                 TextureAllocationFlags aAllocFlags) const
 {
   return ShmemTextureData::Create(GetSize(), GetFormat(), mMoz2DBackend,
-                                  aLayersBackend, aFlags, aAllocFlags, aAllocator);
+                                  aLayersBackend, aFlags, aAllocFlags, aAllocator,
+                                  aSupportsTextureDirectMapping);
 }
 
 void
 ShmemTextureData::Deallocate(LayersIPCChannel* aAllocator)
 {
   aAllocator->DeallocShmem(mShmem);
 }
 
--- a/gfx/layers/BufferTexture.h
+++ b/gfx/layers/BufferTexture.h
@@ -12,27 +12,29 @@
 #include "mozilla/gfx/Types.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/RefPtr.h"
 
 namespace mozilla {
 namespace layers {
 
 bool ComputeHasIntermediateBuffer(gfx::SurfaceFormat aFormat,
-                                  LayersBackend aLayersBackend);
+                                  LayersBackend aLayersBackend,
+                                  bool aSupportsTextureDirectMapping);
 
 class BufferTextureData : public TextureData
 {
 public:
   static BufferTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                                    gfx::BackendType aMoz2DBackend,
                                    LayersBackend aLayersBackend,
                                    TextureFlags aFlags,
                                    TextureAllocationFlags aAllocFlags,
-                                   LayersIPCChannel* aAllocator);
+                                   LayersIPCChannel* aAllocator,
+                                   bool aSupportsTextureDirectMapping);
 
   static BufferTextureData* CreateForYCbCr(KnowsCompositor* aAllocator,
                                            gfx::IntSize aYSize,
                                            uint32_t aYStride,
                                            gfx::IntSize aCbCrSize,
                                            uint32_t aCbCrStride,
                                            StereoMode aStereoMode,
                                            YUVColorSpace aYUVColorSpace,
--- a/gfx/layers/TextureDIB.cpp
+++ b/gfx/layers/TextureDIB.cpp
@@ -24,16 +24,17 @@ namespace layers {
 class MemoryDIBTextureData : public DIBTextureData
 {
 public:
   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
 
   virtual TextureData*
   CreateSimilar(LayersIPCChannel* aAllocator,
                 LayersBackend aLayersBackend,
+                bool SupportsTextureDirectMapping = false,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
   static
   DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
 
@@ -218,16 +219,17 @@ MemoryDIBTextureData::UpdateFromSurface(
 
   srcSurf->Unmap();
   return true;
 }
 
 TextureData*
 ShmemDIBTextureData::CreateSimilar(LayersIPCChannel* aAllocator,
                                    LayersBackend aLayersBackend,
+                                   bool SupportsTextureDirectMapping,
                                    TextureFlags aFlags,
                                    TextureAllocationFlags aAllocFlags) const
 {
   if (!aAllocator) {
     return nullptr;
   }
   return ShmemDIBTextureData::Create(mSize, mFormat, aAllocator);
 }
--- a/gfx/layers/basic/TextureClientX11.cpp
+++ b/gfx/layers/basic/TextureClientX11.cpp
@@ -110,16 +110,17 @@ void
 X11TextureData::Deallocate(LayersIPCChannel*)
 {
   mSurface = nullptr;
 }
 
 TextureData*
 X11TextureData::CreateSimilar(LayersIPCChannel* aAllocator,
                               LayersBackend aLayersBackend,
+                              bool SupportsTextureDirectMapping,
                               TextureFlags aFlags,
                               TextureAllocationFlags aAllocFlags) const
 {
   return X11TextureData::Create(mSize, mFormat, aFlags, aAllocator);
 }
 
 X11TextureData*
 X11TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
--- a/gfx/layers/basic/TextureClientX11.h
+++ b/gfx/layers/basic/TextureClientX11.h
@@ -30,16 +30,17 @@ public:
 
   virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
 
   virtual void Deallocate(LayersIPCChannel*) override;
 
   virtual TextureData*
   CreateSimilar(LayersIPCChannel* aAllocator,
                 LayersBackend aLayersBackend,
+                bool SupportsTextureDirectMapping = false,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
 protected:
   X11TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                  bool aClientDeallocation, bool aIsCrossProcess,
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -759,16 +759,17 @@ ContentClientRemoteBuffer::CreateBufferI
   if (!textureClient || !AddTextureClient(textureClient)) {
     return nullptr;
   }
 
   RefPtr<TextureClient> textureClientOnWhite;
   if (aFlags & TextureFlags::COMPONENT_ALPHA) {
     textureClientOnWhite = textureClient->CreateSimilar(
       mForwarder->GetCompositorBackendType(),
+      mForwarder->SupportsTextureDirectMapping(),
       aFlags | ExtraTextureFlags(),
       TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE
     );
     if (!textureClientOnWhite || !AddTextureClient(textureClientOnWhite)) {
       return nullptr;
     }
     // We don't enable the readlock for the white buffer since we always
     // use them together and waiting on the lock for the black
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -657,27 +657,34 @@ TextureClient::UpdateFromSurface(gfx::So
       return;
     }
   }
   NS_WARNING("TextureClient::UpdateFromSurface failed");
 }
 
 
 already_AddRefed<TextureClient>
-TextureClient::CreateSimilar(LayersBackend aLayersBackend, TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
+TextureClient::CreateSimilar(LayersBackend aLayersBackend,
+                             bool aSupportsTextureDirectMapping,
+                             TextureFlags aFlags,
+                             TextureAllocationFlags aAllocFlags) const
 {
   MOZ_ASSERT(IsValid());
 
   MOZ_ASSERT(!mIsLocked);
   if (mIsLocked) {
     return nullptr;
   }
 
   LockActor();
-  TextureData* data = mData->CreateSimilar(mAllocator, aLayersBackend, aFlags, aAllocFlags);
+  TextureData* data = mData->CreateSimilar(mAllocator,
+                                           aLayersBackend,
+                                           aSupportsTextureDirectMapping,
+                                           aFlags,
+                                           aAllocFlags);
   UnlockActor();
 
   if (!data) {
     return nullptr;
   }
 
   return MakeAndAddRef<TextureClient>(data, aFlags, mAllocator);
 }
@@ -1060,28 +1067,30 @@ TextureClient::CreateForDrawing(KnowsCom
                                 BackendSelector aSelector,
                                 TextureFlags aTextureFlags,
                                 TextureAllocationFlags aAllocFlags)
 {
   LayersBackend layersBackend = aAllocator->GetCompositorBackendType();
   return TextureClient::CreateForDrawing(aAllocator->GetTextureForwarder(),
                                          aFormat, aSize,
                                          layersBackend,
+                                         aAllocator->SupportsTextureDirectMapping(),
                                          aAllocator->GetMaxTextureSize(),
                                          aSelector,
                                          aTextureFlags,
                                          aAllocFlags);
 }
 
 // static
 already_AddRefed<TextureClient>
 TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
                                 gfx::SurfaceFormat aFormat,
                                 gfx::IntSize aSize,
                                 LayersBackend aLayersBackend,
+                                bool aSupportsTextureDirectMapping,
                                 int32_t aMaxTextureSize,
                                 BackendSelector aSelector,
                                 TextureFlags aTextureFlags,
                                 TextureAllocationFlags aAllocFlags)
 {
   gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(aLayersBackend, aSelector);
 
   // also test the validity of aAllocator
@@ -1152,16 +1161,17 @@ TextureClient::CreateForDrawing(TextureF
 
   if (data) {
     return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
   }
 
   // Can't do any better than a buffer texture client.
   return TextureClient::CreateForRawBufferAccess(aAllocator, aFormat, aSize,
                                                  moz2DBackend, aLayersBackend,
+                                                 aSupportsTextureDirectMapping,
                                                  aTextureFlags, aAllocFlags);
 }
 
 // static
 already_AddRefed<TextureClient>
 TextureClient::CreateFromSurface(KnowsCompositor* aAllocator,
                                  gfx::SourceSurface* aSurface,
                                  BackendSelector aSelector,
@@ -1228,26 +1238,28 @@ TextureClient::CreateForRawBufferAccess(
                                         gfx::IntSize aSize,
                                         gfx::BackendType aMoz2DBackend,
                                         TextureFlags aTextureFlags,
                                         TextureAllocationFlags aAllocFlags)
 {
   return CreateForRawBufferAccess(aAllocator->GetTextureForwarder(),
                                   aFormat, aSize, aMoz2DBackend,
                                   aAllocator->GetCompositorBackendType(),
+                                  aAllocator->SupportsTextureDirectMapping(),
                                   aTextureFlags, aAllocFlags);
 }
 
 // static
 already_AddRefed<TextureClient>
 TextureClient::CreateForRawBufferAccess(LayersIPCChannel* aAllocator,
                                         gfx::SurfaceFormat aFormat,
                                         gfx::IntSize aSize,
                                         gfx::BackendType aMoz2DBackend,
                                         LayersBackend aLayersBackend,
+                                        bool aSupportsTextureDirectMapping,
                                         TextureFlags aTextureFlags,
                                         TextureAllocationFlags aAllocFlags)
 {
   // also test the validity of aAllocator
   if (!aAllocator || !aAllocator->IPCOpen()) {
     return nullptr;
   }
 
@@ -1269,17 +1281,18 @@ TextureClient::CreateForRawBufferAccess(
   // force the buffer to be Skia.
   NS_WARNING_ASSERTION(aMoz2DBackend == gfx::BackendType::SKIA ||
                        aMoz2DBackend == gfx::BackendType::DIRECT2D ||
                        aMoz2DBackend == gfx::BackendType::DIRECT2D1_1,
                        "Unsupported TextureClient backend type");
 
   TextureData* texData = BufferTextureData::Create(aSize, aFormat, gfx::BackendType::SKIA,
                                                    aLayersBackend, aTextureFlags,
-                                                   aAllocFlags, aAllocator);
+                                                   aAllocFlags, aAllocator,
+                                                   aSupportsTextureDirectMapping);
   if (!texData) {
     return nullptr;
   }
 
   return MakeAndAddRef<TextureClient>(texData, aTextureFlags, aAllocator);
 }
 
 // static
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -273,16 +273,17 @@ public:
   virtual bool Serialize(SurfaceDescriptor& aDescriptor) = 0;
   virtual void GetSubDescriptor(GPUVideoSubDescriptor* aOutDesc) { }
 
   virtual void OnForwardedToHost() {}
 
   virtual TextureData*
   CreateSimilar(LayersIPCChannel* aAllocator,
                 LayersBackend aLayersBackend,
+                bool aSupportsTextureDirectMapping = false,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const { return nullptr; }
 
   virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) { return false; };
 
   virtual bool ReadBack(TextureReadbackSink* aReadbackSink) { return false; }
 
   virtual void SyncWithObject(SyncObjectClient* aSyncObject) {};
@@ -383,16 +384,17 @@ public:
                                size_t aSize,
                                YUVColorSpace aYUVColorSpace,
                                uint32_t aBitDepth,
                                TextureFlags aTextureFlags);
 
   // Creates and allocates a TextureClient of the same type.
   already_AddRefed<TextureClient>
   CreateSimilar(LayersBackend aLayersBackend = LayersBackend::LAYERS_NONE,
+                bool aSupportsTextureDirectMapping = false,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const;
 
   /**
    * Locks the shared data, allowing the caller to get access to it.
    *
    * Please always lock/unlock when accessing the shared data.
    * If Lock() returns false, you should not attempt to access the shared data.
@@ -661,27 +663,29 @@ private:
   // per-process instead of per ShadowLayerForwarder, but everyone else should
   // use the public functions instead.
   friend class TextureClientPool;
   static already_AddRefed<TextureClient>
   CreateForDrawing(TextureForwarder* aAllocator,
                    gfx::SurfaceFormat aFormat,
                    gfx::IntSize aSize,
                    LayersBackend aLayersBackend,
+                   bool aSupportsTextureDirectMapping,
                    int32_t aMaxTextureSize,
                    BackendSelector aSelector,
                    TextureFlags aTextureFlags,
                    TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);
 
   static already_AddRefed<TextureClient>
   CreateForRawBufferAccess(LayersIPCChannel* aAllocator,
                            gfx::SurfaceFormat aFormat,
                            gfx::IntSize aSize,
                            gfx::BackendType aMoz2dBackend,
                            LayersBackend aLayersBackend,
+                           bool aSupportsTextureDirectMapping,
                            TextureFlags aTextureFlags,
                            TextureAllocationFlags flags = ALLOC_DEFAULT);
 
   void EnableReadLock();
   void EnableBlockingReadLock();
 
   /**
    * Called once, during the destruction of the Texture, on the thread in which
--- a/gfx/layers/client/TextureClientPool.cpp
+++ b/gfx/layers/client/TextureClientPool.cpp
@@ -34,16 +34,17 @@ ShrinkCallback(nsITimer *aTimer, void *a
 // at an inopportune time (e.g. mid-animation).
 static void
 ClearCallback(nsITimer *aTimer, void *aClosure)
 {
   static_cast<TextureClientPool*>(aClosure)->Clear();
 }
 
 TextureClientPool::TextureClientPool(LayersBackend aLayersBackend,
+                                     bool aSupportsTextureDirectMapping,
                                      int32_t aMaxTextureSize,
                                      gfx::SurfaceFormat aFormat,
                                      gfx::IntSize aSize,
                                      TextureFlags aFlags,
                                      uint32_t aShrinkTimeoutMsec,
                                      uint32_t aClearTimeoutMsec,
                                      uint32_t aInitialPoolSize,
                                      uint32_t aPoolUnusedSize,
@@ -55,16 +56,17 @@ TextureClientPool::TextureClientPool(Lay
   , mFlags(aFlags)
   , mShrinkTimeoutMsec(aShrinkTimeoutMsec)
   , mClearTimeoutMsec(aClearTimeoutMsec)
   , mInitialPoolSize(aInitialPoolSize)
   , mPoolUnusedSize(aPoolUnusedSize)
   , mOutstandingClients(0)
   , mSurfaceAllocator(aAllocator)
   , mDestroyed(false)
+  , mSupportsTextureDirectMapping(aSupportsTextureDirectMapping)
 {
   TCP_LOG("TexturePool %p created with maximum unused texture clients %u\n",
       this, mInitialPoolSize);
   mShrinkTimer = NS_NewTimer();
   mClearTimer = NS_NewTimer();
   if (aFormat == gfx::SurfaceFormat::UNKNOWN) {
     gfxWarning() << "Creating texture pool for SurfaceFormat::UNKNOWN format";
   }
@@ -152,22 +154,24 @@ TextureClientPool::AllocateTextureClient
   RefPtr<TextureClient> newClient;
   if (gfxPrefs::ForceShmemTiles()) {
     // gfx::BackendType::NONE means use the content backend
     newClient =
       TextureClient::CreateForRawBufferAccess(mSurfaceAllocator,
                                               mFormat, mSize,
                                               gfx::BackendType::NONE,
                                               mBackend,
+                                              mSupportsTextureDirectMapping,
                                               mFlags, ALLOC_DEFAULT);
   } else {
     newClient =
       TextureClient::CreateForDrawing(mSurfaceAllocator,
                                       mFormat, mSize,
                                       mBackend,
+                                      mSupportsTextureDirectMapping,
                                       mMaxTextureSize,
                                       BackendSelector::Content,
                                       mFlags);
   }
 
   if (newClient) {
     mTextureClients.push(newClient);
   }
--- a/gfx/layers/client/TextureClientPool.h
+++ b/gfx/layers/client/TextureClientPool.h
@@ -41,16 +41,17 @@ public:
 };
 
 class TextureClientPool final : public TextureClientAllocator
 {
   virtual ~TextureClientPool();
 
 public:
   TextureClientPool(LayersBackend aBackend,
+                    bool aSupportsTextureDirectMapping,
                     int32_t aMaxTextureSize,
                     gfx::SurfaceFormat aFormat,
                     gfx::IntSize aSize,
                     TextureFlags aFlags,
                     uint32_t aShrinkTimeoutMsec,
                     uint32_t aClearTimeoutMsec,
                     uint32_t aInitialPoolSize,
                     uint32_t aPoolUnusedSize,
@@ -165,14 +166,16 @@ private:
   RefPtr<nsITimer> mClearTimer;
   // This mSurfaceAllocator owns us, so no need to hold a ref to it
   TextureForwarder* mSurfaceAllocator;
 
   // Keep track of whether this pool has been destroyed or not. If it has,
   // we won't accept returns of TextureClients anymore, and the refcounting
   // should take care of their destruction.
   bool mDestroyed;
+
+  bool mSupportsTextureDirectMapping;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_TEXTURECLIENTPOOL_H */
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -597,16 +597,17 @@ CreateD3D11TextureClientWithDevice(IntSi
     return nullptr;
   }
   return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
 }
 
 TextureData*
 D3D11TextureData::CreateSimilar(LayersIPCChannel* aAllocator,
                                 LayersBackend aLayersBackend,
+                                bool SupportsTextureDirectMapping,
                                 TextureFlags aFlags,
                                 TextureAllocationFlags aAllocFlags) const
 {
   return D3D11TextureData::Create(mSize, mFormat, aAllocFlags);
 }
 
 void
 D3D11TextureData::GetDXGIResource(IDXGIResource** aOutResource)
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -89,16 +89,17 @@ public:
 
   virtual void Unlock() override;
 
   virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
 
   virtual TextureData*
   CreateSimilar(LayersIPCChannel* aAllocator,
                 LayersBackend aLayersBackend,
+                bool SupportsTextureDirectMapping,
                 TextureFlags aFlags,
                 TextureAllocationFlags aAllocFlags) const override;
 
   virtual void SyncWithObject(SyncObjectClient* aSyncObject) override;
 
   ID3D11Texture2D* GetD3D11Texture() { return mTexture; }
 
   virtual void Deallocate(LayersIPCChannel* aAllocator) override;
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -930,16 +930,17 @@ CompositorBridgeChild::GetTexturePool(Kn
         mTexturePools[i]->GetFormat() == aFormat &&
         mTexturePools[i]->GetFlags() == aFlags) {
       return mTexturePools[i];
     }
   }
 
   mTexturePools.AppendElement(
       new TextureClientPool(aAllocator->GetCompositorBackendType(),
+                            aAllocator->SupportsTextureDirectMapping(),
                             aAllocator->GetMaxTextureSize(),
                             aFormat,
                             gfx::gfxVars::TileSize(),
                             aFlags,
                             gfxPrefs::LayersTilePoolShrinkTimeout(),
                             gfxPrefs::LayersTilePoolClearTimeout(),
                             gfxPrefs::LayersTileInitialPoolSize(),
                             gfxPrefs::LayersTilePoolUnusedSize(),
--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
@@ -111,17 +111,18 @@ SharedPlanarYCbCrImage::AdoptData(const 
 
   uint8_t *base = GetBuffer();
   uint32_t yOffset = aData.mYChannel - base;
   uint32_t cbOffset = aData.mCbChannel - base;
   uint32_t crOffset = aData.mCrChannel - base;
 
   auto fwd = mCompositable->GetForwarder();
   bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(
-    gfx::SurfaceFormat::YUV, fwd->GetCompositorBackendType());
+    gfx::SurfaceFormat::YUV, fwd->GetCompositorBackendType(),
+    fwd->SupportsTextureDirectMapping());
 
   static_cast<BufferTextureData*>(mTextureClient->GetInternalData())
     ->SetDesciptor(YCbCrDescriptor(aData.mYSize,
                                    aData.mYStride,
                                    aData.mCbCrSize,
                                    aData.mCbCrStride,
                                    yOffset,
                                    cbOffset,
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -228,17 +228,17 @@ TEST(Layers, TextureSerialization) {
   for (int f = 0; f < 3; ++f) {
     RefPtr<gfxImageSurface> surface = new gfxImageSurface(IntSize(400,300), formats[f]);
     SetupSurface(surface.get());
     AssertSurfacesEqual(surface, surface);
 
     auto texData = BufferTextureData::Create(surface->GetSize(),
       gfx::ImageFormatToSurfaceFormat(surface->Format()),
       gfx::BackendType::CAIRO, LayersBackend::LAYERS_NONE,
-      TextureFlags::DEALLOCATE_CLIENT, ALLOC_DEFAULT, nullptr
+      TextureFlags::DEALLOCATE_CLIENT, ALLOC_DEFAULT, nullptr, false
     );
     ASSERT_TRUE(!!texData);
 
     RefPtr<TextureClient> client = new TextureClient(
       texData, TextureFlags::DEALLOCATE_CLIENT, nullptr
     );
 
     TestTextureClientSurface(client, surface);
--- a/gfx/tests/gtest/TextureHelper.h
+++ b/gfx/tests/gtest/TextureHelper.h
@@ -120,17 +120,17 @@ CreateTextureClientWithBackend(LayersBac
     // Create DIBTextureData.
     data = DIBTextureData::Create(size, format, nullptr);
   }
 #endif
 
   if (!data && aLayersBackend == LayersBackend::LAYERS_BASIC) {
     // Create BufferTextureData.
     data = BufferTextureData::Create(size, format, moz2DBackend, aLayersBackend,
-                                     textureFlags, allocFlags, nullptr);
+                                     textureFlags, allocFlags, nullptr, false);
   }
 
   if (data) {
     return MakeAndAddRef<TextureClient>(data, textureFlags, nullptr);
   }
 
   return nullptr;
 }