Bug 1582371 - Add DCLayerTree class r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Thu, 19 Sep 2019 18:15:11 +0000
changeset 494131 941d1628e2937cf7081521f03d16d834f11f3d86
parent 494130 134ed13973c19948bc674fa21f0ac6d158ecb6b4
child 494132 435ebebfb638bfa98f519f93922544bacf6a37b5
push id36596
push userapavel@mozilla.com
push dateFri, 20 Sep 2019 09:45:58 +0000
treeherdermozilla-central@52cb15e3f794 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1582371
milestone71.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 1582371 - Add DCLayerTree class r=nical Preparation work for adding DirectComposition support. It does not add a new functionality. Differential Revision: https://phabricator.services.mozilla.com/D46429
gfx/webrender_bindings/DCLayerTree.cpp
gfx/webrender_bindings/DCLayerTree.h
gfx/webrender_bindings/RenderCompositorANGLE.cpp
gfx/webrender_bindings/RenderCompositorANGLE.h
gfx/webrender_bindings/moz.build
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/DCLayerTree.cpp
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DCLayerTree.h"
+
+#include "mozilla/gfx/DeviceManagerDx.h"
+
+#undef NTDDI_VERSION
+#define NTDDI_VERSION NTDDI_WIN8
+
+#include <d3d11.h>
+#include <dcomp.h>
+#include <dxgi1_2.h>
+
+namespace mozilla {
+namespace wr {
+
+/* static */
+UniquePtr<DCLayerTree> DCLayerTree::Create(HWND aHwnd) {
+  RefPtr<IDCompositionDevice> dCompDevice =
+      gfx::DeviceManagerDx::Get()->GetDirectCompositionDevice();
+  if (!dCompDevice) {
+    return nullptr;
+  }
+
+  auto layerTree = MakeUnique<DCLayerTree>(dCompDevice);
+  if (!layerTree->Initialize(aHwnd)) {
+    return nullptr;
+  }
+
+  return layerTree;
+}
+
+DCLayerTree::DCLayerTree(IDCompositionDevice* aCompositionDevice)
+    : mCompositionDevice(aCompositionDevice) {}
+
+DCLayerTree::~DCLayerTree() {}
+
+bool DCLayerTree::Initialize(HWND aHwnd) {
+  HRESULT hr = mCompositionDevice->CreateTargetForHwnd(
+      aHwnd, TRUE, getter_AddRefs(mCompositionTarget));
+  if (FAILED(hr)) {
+    gfxCriticalNote << "Could not create DCompositionTarget: " << gfx::hexa(hr);
+    return false;
+  }
+
+  hr = mCompositionDevice->CreateVisual(getter_AddRefs(mRootVisual));
+  if (FAILED(hr)) {
+    gfxCriticalNote << "Could not create DCompositionVisualt: "
+                    << gfx::hexa(hr);
+    return false;
+  }
+  return true;
+}
+
+void DCLayerTree::SetDefaultSwapChain(IDXGISwapChain1* aSwapChain) {
+  mRootVisual->SetContent(aSwapChain);
+  mCompositionTarget->SetRoot(mRootVisual);
+  mCompositionDevice->Commit();
+}
+
+}  // namespace wr
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/DCLayerTree.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_GFX_DCLAYER_TREE_H
+#define MOZILLA_GFX_DCLAYER_TREE_H
+
+#include <windows.h>
+
+#include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtr.h"
+
+struct IDCompositionDevice;
+struct IDCompositionTarget;
+struct IDCompositionVisual;
+struct IDXGISwapChain1;
+
+namespace mozilla {
+
+namespace wr {
+
+/**
+ * DCLayerTree manages direct composition layers.
+ * It does not manage gecko's layers::Layer.
+ */
+class DCLayerTree {
+ public:
+  static UniquePtr<DCLayerTree> Create(HWND aHwnd);
+  explicit DCLayerTree(IDCompositionDevice* aCompositionDevice);
+  ~DCLayerTree();
+
+  void SetDefaultSwapChain(IDXGISwapChain1* aSwapChain);
+
+ protected:
+  bool Initialize(HWND aHwnd);
+
+  RefPtr<IDCompositionDevice> mCompositionDevice;
+  RefPtr<IDCompositionTarget> mCompositionTarget;
+  RefPtr<IDCompositionVisual> mRootVisual;
+};
+
+}  // namespace wr
+}  // namespace mozilla
+
+#endif
--- a/gfx/webrender_bindings/RenderCompositorANGLE.cpp
+++ b/gfx/webrender_bindings/RenderCompositorANGLE.cpp
@@ -9,16 +9,17 @@
 #include "GLContext.h"
 #include "GLContextEGL.h"
 #include "GLContextProvider.h"
 #include "mozilla/gfx/DeviceManagerDx.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/layers/HelpersD3D11.h"
 #include "mozilla/layers/SyncObject.h"
+#include "mozilla/webrender/DCLayerTree.h"
 #include "mozilla/webrender/RenderThread.h"
 #include "mozilla/widget/CompositorWidget.h"
 #include "mozilla/widget/WinCompositorWidget.h"
 #include "mozilla/WindowsVersion.h"
 
 #undef NTDDI_VERSION
 #define NTDDI_VERSION NTDDI_WIN8
 
@@ -252,54 +253,29 @@ bool RenderCompositorANGLE::Initialize()
 }
 
 void RenderCompositorANGLE::CreateSwapChainForDCompIfPossible(
     IDXGIFactory2* aDXGIFactory2) {
   if (!aDXGIFactory2) {
     return;
   }
 
-  RefPtr<IDCompositionDevice> dCompDevice =
-      gfx::DeviceManagerDx::Get()->GetDirectCompositionDevice();
-  if (!dCompDevice) {
-    return;
-  }
-  MOZ_ASSERT(XRE_IsGPUProcess());
-
-  RefPtr<IDXGIDevice> dxgiDevice;
-  mDevice->QueryInterface((IDXGIDevice**)getter_AddRefs(dxgiDevice));
-
-  RefPtr<IDXGIFactory> dxgiFactory;
-  {
-    RefPtr<IDXGIAdapter> adapter;
-    dxgiDevice->GetAdapter(getter_AddRefs(adapter));
-    adapter->GetParent(
-        IID_PPV_ARGS((IDXGIFactory**)getter_AddRefs(dxgiFactory)));
-  }
-
   HWND hwnd = mWidget->AsWindows()->GetCompositorHwnd();
   if (!hwnd) {
     gfxCriticalNote << "Compositor window was not created ";
     return;
   }
 
-  HRESULT hr = dCompDevice->CreateTargetForHwnd(
-      hwnd, TRUE, getter_AddRefs(mCompositionTarget));
-  if (FAILED(hr)) {
-    gfxCriticalNote << "Could not create DCompositionTarget: " << gfx::hexa(hr);
+  mDCLayerTree = DCLayerTree::Create(hwnd);
+  if (!mDCLayerTree) {
     return;
   }
+  MOZ_ASSERT(XRE_IsGPUProcess());
 
-  hr = dCompDevice->CreateVisual(getter_AddRefs(mVisual));
-  if (FAILED(hr)) {
-    gfxCriticalNote << "Could not create DCompositionVisualt: "
-                    << gfx::hexa(hr);
-    return;
-  }
-
+  HRESULT hr;
   RefPtr<IDXGISwapChain1> swapChain1;
   bool useTripleBuffering = gfx::gfxVars::UseWebRenderTripleBufferingWin();
 
   DXGI_SWAP_CHAIN_DESC1 desc{};
   // DXGI does not like 0x0 swapchains. Swap chain creation failed when 0x0 was
   // set.
   desc.Width = 1;
   desc.Height = 1;
@@ -321,21 +297,21 @@ void RenderCompositorANGLE::CreateSwapCh
   desc.Flags = 0;
 
   hr = aDXGIFactory2->CreateSwapChainForComposition(mDevice, &desc, nullptr,
                                                     getter_AddRefs(swapChain1));
   if (SUCCEEDED(hr) && swapChain1) {
     DXGI_RGBA color = {1.0f, 1.0f, 1.0f, 1.0f};
     swapChain1->SetBackgroundColor(&color);
     mSwapChain = swapChain1;
-    mVisual->SetContent(swapChain1);
-    mCompositionTarget->SetRoot(mVisual);
-    mCompositionDevice = dCompDevice;
-    mCompositionDevice->Commit();
+    mDCLayerTree->SetDefaultSwapChain(swapChain1);
     mUseTripleBuffering = useTripleBuffering;
+  } else {
+    // Clear CLayerTree on falire
+    mDCLayerTree = nullptr;
   }
 }
 
 bool RenderCompositorANGLE::BeginFrame(layers::NativeLayer* aNativeLayer) {
   MOZ_RELEASE_ASSERT(!aNativeLayer, "Unexpected native layer on this platform");
   mWidget->AsWindows()->UpdateCompositorWndSizeIfNecessary();
 
   if (!ResizeBufferIfNeeded()) {
--- a/gfx/webrender_bindings/RenderCompositorANGLE.h
+++ b/gfx/webrender_bindings/RenderCompositorANGLE.h
@@ -12,29 +12,28 @@
 #include "GLTypes.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/webrender/RenderCompositor.h"
 #include "mozilla/webrender/RenderThread.h"
 
 struct ID3D11DeviceContext;
 struct ID3D11Device;
 struct ID3D11Query;
-struct IDCompositionDevice;
-struct IDCompositionTarget;
-struct IDCompositionVisual;
 struct IDXGIFactory2;
 struct IDXGISwapChain;
 
 namespace mozilla {
 namespace gl {
 class GLLibraryEGL;
 }  // namespace gl
 
 namespace wr {
 
+class DCLayerTree;
+
 class RenderCompositorANGLE : public RenderCompositor {
  public:
   static UniquePtr<RenderCompositor> Create(
       RefPtr<widget::CompositorWidget>&& aWidget);
 
   explicit RenderCompositorANGLE(RefPtr<widget::CompositorWidget>&& aWidget);
   virtual ~RenderCompositorANGLE();
   bool Initialize();
@@ -46,17 +45,17 @@ class RenderCompositorANGLE : public Ren
   bool Resume() override;
 
   gl::GLContext* gl() const override { return RenderThread::Get()->SharedGL(); }
 
   bool MakeCurrent() override;
 
   bool UseANGLE() const override { return true; }
 
-  bool UseDComp() const override { return !!mCompositionDevice; }
+  bool UseDComp() const override { return !!mDCLayerTree; }
 
   bool UseTripleBuffering() const override { return mUseTripleBuffering; }
 
   LayoutDeviceIntSize GetBufferSize() override;
 
   bool IsContextLost() override;
 
  protected:
@@ -74,19 +73,17 @@ class RenderCompositorANGLE : public Ren
   EGLSurface mEGLSurface;
 
   bool mUseTripleBuffering;
 
   RefPtr<ID3D11Device> mDevice;
   RefPtr<ID3D11DeviceContext> mCtx;
   RefPtr<IDXGISwapChain> mSwapChain;
 
-  RefPtr<IDCompositionDevice> mCompositionDevice;
-  RefPtr<IDCompositionTarget> mCompositionTarget;
-  RefPtr<IDCompositionVisual> mVisual;
+  UniquePtr<DCLayerTree> mDCLayerTree;
 
   std::queue<RefPtr<ID3D11Query>> mWaitForPresentQueries;
   RefPtr<ID3D11Query> mRecycledQuery;
 
   Maybe<LayoutDeviceIntSize> mBufferSize;
 };
 
 }  // namespace wr
--- a/gfx/webrender_bindings/moz.build
+++ b/gfx/webrender_bindings/moz.build
@@ -55,23 +55,25 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'andr
     UNIFIED_SOURCES += [
         'RenderAndroidSurfaceTextureHostOGL.cpp',
         'RenderCompositorEGL.cpp',
     ]
 
 if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
     DEFINES['MOZ_ENABLE_D3D10_LAYER'] = True
     EXPORTS.mozilla.webrender += [
+        'DCLayerTree.h',
         'RenderCompositorANGLE.h',
         'RenderD3D11TextureHostOGL.h',
     ]
     UNIFIED_SOURCES += [
         'RenderD3D11TextureHostOGL.cpp',
     ]
     SOURCES += [
+        'DCLayerTree.cpp',
         'RenderCompositorANGLE.cpp',
     ]
 
 if CONFIG['MOZ_WAYLAND']:
     EXPORTS.mozilla.webrender += [
         'RenderCompositorEGL.h',
     ]
     SOURCES += [