Bug 1312988 - Prevent D3D11 DXGI TextureSource to be used as a DataTextureSource. r=sotaro, a=jcristau
authorNicolas Silva <nsilva@mozilla.com>
Mon, 14 Nov 2016 10:09:31 +0100
changeset 352616 fb302a466f46b7798eb403756586fc51b7d2cd3e
parent 352615 8975dd79a7b36e82ea03fac0ab2266b24e18c155
child 352617 1ceec185789fca53a2eee3dba0da59ce34ff601c
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro, jcristau
bugs1312988
milestone52.0a2
Bug 1312988 - Prevent D3D11 DXGI TextureSource to be used as a DataTextureSource. r=sotaro, a=jcristau
gfx/layers/d3d11/TextureD3D11.cpp
gfx/layers/d3d11/TextureD3D11.h
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -156,29 +156,31 @@ DataTextureSourceD3D11::DataTextureSourc
                                                CompositorD3D11* aCompositor,
                                                TextureFlags aFlags)
   : mCompositor(aCompositor)
   , mFormat(aFormat)
   , mFlags(aFlags)
   , mCurrentTile(0)
   , mIsTiled(false)
   , mIterating(false)
+  , mAllowTextureUploads(true)
 {
   MOZ_COUNT_CTOR(DataTextureSourceD3D11);
 }
 
 DataTextureSourceD3D11::DataTextureSourceD3D11(SurfaceFormat aFormat,
                                                CompositorD3D11* aCompositor,
                                                ID3D11Texture2D* aTexture)
 : mCompositor(aCompositor)
 , mFormat(aFormat)
 , mFlags(TextureFlags::NO_FLAGS)
 , mCurrentTile(0)
 , mIsTiled(false)
 , mIterating(false)
+, mAllowTextureUploads(false)
 {
   MOZ_COUNT_CTOR(DataTextureSourceD3D11);
 
   mTexture = aTexture;
   D3D11_TEXTURE2D_DESC desc;
   aTexture->GetDesc(&desc);
 
   mSize = IntSize(desc.Width, desc.Height);
@@ -965,16 +967,21 @@ DataTextureSourceD3D11::Update(DataSourc
                                nsIntRegion* aDestRegion,
                                IntPoint* aSrcOffset)
 {
   // Incremental update with a source offset is only used on Mac so it is not
   // clear that we ever will need to support it for D3D.
   MOZ_ASSERT(!aSrcOffset);
   MOZ_ASSERT(aSurface);
 
+  MOZ_ASSERT(mAllowTextureUploads);
+  if (!mAllowTextureUploads) {
+    return false;
+  }
+
   HRESULT hr;
 
   if (!mCompositor || !mCompositor->GetDevice()) {
     return false;
   }
 
   uint32_t bpp = BytesPerPixel(aSurface->GetFormat());
   DXGI_FORMAT dxgiFormat = SurfaceFormatToDXGIFormat(aSurface->GetFormat());
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -200,19 +200,26 @@ protected:
  * it can be used without a TextureHost and is able to upload texture data
  * from a gfx::DataSourceSurface.
  */
 class DataTextureSourceD3D11 : public DataTextureSource
                              , public TextureSourceD3D11
                              , public BigImageIterator
 {
 public:
+  /// Constructor allowing the texture to perform texture uploads.
+  ///
+  /// The texture can be used as an actual DataTextureSource.
   DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor,
                          TextureFlags aFlags);
 
+  /// Constructor for textures created around DXGI shared handles, disallowing
+  /// texture uploads.
+  ///
+  /// The texture CANNOT be used as a DataTextureSource.
   DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor,
                          ID3D11Texture2D* aTexture);
 
   virtual ~DataTextureSourceD3D11();
 
   virtual const char* Name() const override { return "DataTextureSourceD3D11"; }
 
   // DataTextureSource
@@ -224,17 +231,18 @@ public:
   // TextureSource
 
   virtual TextureSourceD3D11* AsSourceD3D11() override { return this; }
 
   virtual ID3D11Texture2D* GetD3D11Texture() const override;
 
   virtual ID3D11ShaderResourceView* GetShaderResourceView() override;
 
-  virtual DataTextureSource* AsDataTextureSource() override { return this; }
+  // Returns nullptr if this texture was created by a DXGI TextureHost.
+  virtual DataTextureSource* AsDataTextureSource() override { return mAllowTextureUploads ? this : false; }
 
   virtual void DeallocateDeviceData() override { mTexture = nullptr; }
 
   virtual gfx::IntSize GetSize() const  override { return mSize; }
 
   virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
 
   virtual void SetCompositor(Compositor* aCompositor) override;
@@ -265,17 +273,23 @@ protected:
   std::vector< RefPtr<ID3D11Texture2D> > mTileTextures;
   std::vector< RefPtr<ID3D11ShaderResourceView> > mTileSRVs;
   RefPtr<CompositorD3D11> mCompositor;
   gfx::SurfaceFormat mFormat;
   TextureFlags mFlags;
   uint32_t mCurrentTile;
   bool mIsTiled;
   bool mIterating;
-
+  // Sadly, the code was originally organized so that this class is used both in
+  // the cases where we want to perform texture uploads through the DataTextureSource
+  // interface, and the cases where we wrap the texture around an existing DXGI
+  // handle in which case we should not use it as a DataTextureSource.
+  // This member differentiates the two scenarios. When it is false the texture
+  // "pretends" to not be a DataTextureSource.
+  bool mAllowTextureUploads;
 };
 
 already_AddRefed<TextureClient>
 CreateD3D11TextureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                                    TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
                                    ID3D11Device* aDevice,
                                    LayersIPCChannel* aAllocator);