Bug 1585278 - Add option of enabling performance debugging counters of DirectComposition r=nical,jrmuizel
authorsotaro <sotaro.ikeda.g@gmail.com>
Mon, 07 Oct 2019 20:09:17 +0000
changeset 496924 68dee1ec153d988611cc66113a72513358d4b58e
parent 496923 29ecd1185d1cd5cc87c835fb7666d095b9368ca2
child 496925 961e7c50c3e012756e0d94e0302661be17ac3bfa
push id114147
push userccoroiu@mozilla.com
push dateThu, 10 Oct 2019 09:56:56 +0000
treeherdermozilla-inbound@484a51c401ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical, jrmuizel
bugs1585278
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 1585278 - Add option of enabling performance debugging counters of DirectComposition r=nical,jrmuizel IDCompositionDevice is replaced by IDCompositionDevice2. It is necessary for IDCompositionDeviceDebug usage. And for using IDCompositionDevice2, _WIN32_WINNT and NTDDI_VERSION is updated from Windows 8 to Windows 8.1. Workaround MinGW build failure. Differential Revision: https://phabricator.services.mozilla.com/D47742
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/DeviceManagerDx.h
gfx/webrender_bindings/DCLayerTree.cpp
gfx/webrender_bindings/DCLayerTree.h
modules/libpref/init/StaticPrefList.yaml
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -22,18 +22,20 @@
 #include "mozilla/layers/DeviceAttachmentsD3D11.h"
 #include "mozilla/layers/MLGDeviceD3D11.h"
 #include "mozilla/layers/PaintThread.h"
 #include "nsExceptionHandler.h"
 #include "nsIGfxInfo.h"
 #include "nsPrintfCString.h"
 #include "nsString.h"
 
+#undef _WIN32_WINNT
+#define _WIN32_WINNT _WIN32_WINNT_WINBLUE
 #undef NTDDI_VERSION
-#define NTDDI_VERSION NTDDI_WIN8
+#define NTDDI_VERSION NTDDI_WINBLUE
 
 #include <d3d11.h>
 #include <dcomp.h>
 #include <ddraw.h>
 
 namespace mozilla {
 namespace gfx {
 
@@ -42,19 +44,18 @@ using namespace mozilla::layers;
 
 StaticAutoPtr<DeviceManagerDx> DeviceManagerDx::sInstance;
 
 // We don't have access to the D3D11CreateDevice type in gfxWindowsPlatform.h,
 // since it doesn't include d3d11.h, so we use a static here. It should only
 // be used within InitializeD3D11.
 decltype(D3D11CreateDevice)* sD3D11CreateDeviceFn = nullptr;
 
-typedef HRESULT(WINAPI* PFN_DCOMPOSITION_CREATE_DEVICE)(
-    IDXGIDevice* dxgiDevice, REFIID iid, void** dcompositionDevice);
-PFN_DCOMPOSITION_CREATE_DEVICE sDcompCreateDeviceFn = nullptr;
+// It should only be used within CreateDirectCompositionDevice.
+decltype(DCompositionCreateDevice2)* sDcompCreateDevice2Fn = nullptr;
 
 // We don't have access to the DirectDrawCreateEx type in gfxWindowsPlatform.h,
 // since it doesn't include ddraw.h, so we use a static here. It should only
 // be used within InitializeDirectDrawConfig.
 decltype(DirectDrawCreateEx)* sDirectDrawCreateExFn = nullptr;
 
 /* static */
 void DeviceManagerDx::Init() { sInstance = new DeviceManagerDx(); }
@@ -105,28 +106,28 @@ bool DeviceManagerDx::LoadD3D11() {
 }
 
 bool DeviceManagerDx::LoadDcomp() {
   MOZ_ASSERT(gfxConfig::GetFeature(Feature::D3D11_COMPOSITING).IsEnabled());
   MOZ_ASSERT(gfxVars::UseWebRender());
   MOZ_ASSERT(gfxVars::UseWebRenderANGLE());
   MOZ_ASSERT(gfxVars::UseWebRenderDCompWin());
 
-  if (sDcompCreateDeviceFn) {
+  if (sDcompCreateDevice2Fn) {
     return true;
   }
 
   nsModuleHandle module(LoadLibrarySystem32(L"dcomp.dll"));
   if (!module) {
     return false;
   }
 
-  sDcompCreateDeviceFn = reinterpret_cast<PFN_DCOMPOSITION_CREATE_DEVICE>(
-      ::GetProcAddress(module, "DCompositionCreateDevice"));
-  if (!sDcompCreateDeviceFn) {
+  sDcompCreateDevice2Fn = (decltype(DCompositionCreateDevice2)*)GetProcAddress(
+      module, "DCompositionCreateDevice2");
+  if (!sDcompCreateDevice2Fn) {
     return false;
   }
 
   mDcompModule.steal(module);
   return true;
 }
 
 void DeviceManagerDx::ReleaseD3D11() {
@@ -303,16 +304,19 @@ bool DeviceManagerDx::CreateCanvasDevice
   if (XRE_IsGPUProcess()) {
     Factory::SetDirect3D11Device(mCanvasDevice);
   }
 
   return true;
 }
 
 void DeviceManagerDx::CreateDirectCompositionDevice() {
+// Currently, MinGW build environment does not handle IDCompositionDesktopDevice
+// and IDCompositionDevice2
+#if !defined(__MINGW32__)
   if (!gfxVars::UseWebRenderDCompWin()) {
     return;
   }
 
   if (!mCompositorDevice) {
     return;
   }
 
@@ -322,29 +326,37 @@ void DeviceManagerDx::CreateDirectCompos
 
   RefPtr<IDXGIDevice> dxgiDevice;
   if (mCompositorDevice->QueryInterface(
           IID_PPV_ARGS((IDXGIDevice**)getter_AddRefs(dxgiDevice))) != S_OK) {
     return;
   }
 
   HRESULT hr;
-  RefPtr<IDCompositionDevice> compositionDevice;
+  RefPtr<IDCompositionDesktopDevice> desktopDevice;
   MOZ_SEH_TRY {
-    hr = sDcompCreateDeviceFn(
-        dxgiDevice,
-        IID_PPV_ARGS((IDCompositionDevice**)getter_AddRefs(compositionDevice)));
+    hr = sDcompCreateDevice2Fn(
+        dxgiDevice.get(),
+        IID_PPV_ARGS(
+            (IDCompositionDesktopDevice**)getter_AddRefs(desktopDevice)));
   }
   MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { return; }
 
   if (!SUCCEEDED(hr)) {
     return;
   }
 
+  RefPtr<IDCompositionDevice2> compositionDevice;
+  if (desktopDevice->QueryInterface(IID_PPV_ARGS(
+          (IDCompositionDevice2**)getter_AddRefs(compositionDevice))) != S_OK) {
+    return;
+  }
+
   mDirectCompositionDevice = compositionDevice;
+#endif
 }
 
 void DeviceManagerDx::ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus) {
   MOZ_ASSERT(!ProcessOwnsCompositor());
 
   mDeviceStatus = Some(aDeviceStatus);
 }
 
@@ -1126,20 +1138,23 @@ RefPtr<ID3D11Device> DeviceManagerDx::Ge
 RefPtr<ID3D11Device> DeviceManagerDx::GetCanvasDevice() {
   MutexAutoLock lock(mDeviceLock);
   if (!mCanvasDevice) {
     CreateCanvasDevice();
   }
   return mCanvasDevice;
 }
 
-RefPtr<IDCompositionDevice> DeviceManagerDx::GetDirectCompositionDevice() {
+// Currently, MinGW build environment does not handle IDCompositionDevice2
+#if !defined(__MINGW32__)
+RefPtr<IDCompositionDevice2> DeviceManagerDx::GetDirectCompositionDevice() {
   MutexAutoLock lock(mDeviceLock);
   return mDirectCompositionDevice;
 }
+#endif
 
 unsigned DeviceManagerDx::GetCompositorFeatureLevel() const {
   if (!mDeviceStatus) {
     return 0;
   }
   return mDeviceStatus->featureLevel();
 }
 
@@ -1211,17 +1226,22 @@ bool DeviceManagerDx::CanUseP016() {
     return false;
   }
   return mDeviceStatus->formatOptions().contains(
       D3D11Checks::VideoFormatOption::P016);
 }
 
 bool DeviceManagerDx::CanUseDComp() {
   MutexAutoLock lock(mDeviceLock);
+// Currently, MinGW build environment does not handle IDCompositionDevice2
+#if !defined(__MINGW32__)
   return !!mDirectCompositionDevice;
+#else
+  return false;
+#endif
 }
 
 void DeviceManagerDx::InitializeDirectDraw() {
   MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread());
 
   if (mDirectDraw) {
     // Already initialized.
     return;
--- a/gfx/thebes/DeviceManagerDx.h
+++ b/gfx/thebes/DeviceManagerDx.h
@@ -28,17 +28,17 @@
 // Win 8.0 SDK types we'll need when building using older sdks.
 #if !defined(D3D_FEATURE_LEVEL_11_1)  // defined in the 8.0 SDK only
 #  define D3D_FEATURE_LEVEL_11_1 static_cast<D3D_FEATURE_LEVEL>(0xb100)
 #  define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048
 #  define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
 #endif
 
 struct ID3D11Device;
-struct IDCompositionDevice;
+struct IDCompositionDevice2;
 struct IDirectDraw7;
 
 namespace mozilla {
 class ScopedGfxFeatureReporter;
 namespace layers {
 class DeviceAttachmentsD3D11;
 class MLGDevice;
 }  // namespace layers
@@ -54,17 +54,20 @@ class DeviceManagerDx final {
   DeviceManagerDx();
 
   static DeviceManagerDx* Get() { return sInstance; }
 
   RefPtr<ID3D11Device> GetCompositorDevice();
   RefPtr<ID3D11Device> GetContentDevice();
   RefPtr<ID3D11Device> GetCanvasDevice();
   RefPtr<ID3D11Device> GetImageDevice();
-  RefPtr<IDCompositionDevice> GetDirectCompositionDevice();
+// Currently, MinGW build environment does not handle IDCompositionDevice2
+#if !defined(__MINGW32__)
+  RefPtr<IDCompositionDevice2> GetDirectCompositionDevice();
+#endif
   RefPtr<ID3D11Device> GetVRDevice();
   RefPtr<ID3D11Device> CreateDecoderDevice();
   RefPtr<layers::MLGDevice> GetMLGDevice();
   IDirectDraw7* GetDirectDraw();
 
   unsigned GetCompositorFeatureLevel() const;
   bool TextureSharingWorks();
   bool IsWARP();
@@ -167,18 +170,19 @@ class DeviceManagerDx final {
   nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
   RefPtr<IDXGIAdapter1> mAdapter;
   RefPtr<ID3D11Device> mCompositorDevice;
   RefPtr<ID3D11Device> mContentDevice;
   RefPtr<ID3D11Device> mCanvasDevice;
   RefPtr<ID3D11Device> mImageDevice;
   RefPtr<ID3D11Device> mVRDevice;
   RefPtr<ID3D11Device> mDecoderDevice;
-  RefPtr<IDCompositionDevice> mDirectCompositionDevice;
-
+#if !defined(__MINGW32__)
+  RefPtr<IDCompositionDevice2> mDirectCompositionDevice;
+#endif
   RefPtr<layers::DeviceAttachmentsD3D11> mCompositorAttachments;
   RefPtr<layers::MLGDevice> mMLGDevice;
   bool mCompositorDeviceSupportsVideo;
 
   Maybe<D3D11DeviceStatus> mDeviceStatus;
 
   nsModuleHandle mDirectDrawDLL;
   RefPtr<IDirectDraw7> mDirectDraw;
--- a/gfx/webrender_bindings/DCLayerTree.cpp
+++ b/gfx/webrender_bindings/DCLayerTree.cpp
@@ -2,51 +2,69 @@
 /* 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"
+#include "mozilla/StaticPrefs_gfx.h"
 
+#undef _WIN32_WINNT
+#define _WIN32_WINNT _WIN32_WINNT_WINBLUE
 #undef NTDDI_VERSION
-#define NTDDI_VERSION NTDDI_WIN8
+#define NTDDI_VERSION NTDDI_WINBLUE
 
 #include <d3d11.h>
 #include <dcomp.h>
 #include <dxgi1_2.h>
 
 namespace mozilla {
 namespace wr {
 
+// Currently, MinGW build environment does not handle IDCompositionDesktopDevice
+// and IDCompositionDevice2
+#if !defined(__MINGW32__)
+
 /* static */
 UniquePtr<DCLayerTree> DCLayerTree::Create(HWND aHwnd) {
-  RefPtr<IDCompositionDevice> dCompDevice =
+  RefPtr<IDCompositionDevice2> 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)
+DCLayerTree::DCLayerTree(IDCompositionDevice2* aCompositionDevice)
     : mCompositionDevice(aCompositionDevice) {}
 
 DCLayerTree::~DCLayerTree() {}
 
 bool DCLayerTree::Initialize(HWND aHwnd) {
-  HRESULT hr = mCompositionDevice->CreateTargetForHwnd(
-      aHwnd, TRUE, getter_AddRefs(mCompositionTarget));
+  HRESULT hr;
+
+  RefPtr<IDCompositionDesktopDevice> desktopDevice;
+  hr = mCompositionDevice->QueryInterface(
+      (IDCompositionDesktopDevice**)getter_AddRefs(desktopDevice));
+  if (FAILED(hr)) {
+    gfxCriticalNote << "Failed to get IDCompositionDesktopDevice: "
+                    << gfx::hexa(hr);
+    return false;
+  }
+
+  hr = desktopDevice->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 << "Failed to create DCompositionVisual: " << gfx::hexa(hr);
@@ -55,16 +73,28 @@ bool DCLayerTree::Initialize(HWND aHwnd)
 
   hr =
       mCompositionDevice->CreateVisual(getter_AddRefs(mDefaultSwapChainVisual));
   if (FAILED(hr)) {
     gfxCriticalNote << "Failed to create DCompositionVisual: " << gfx::hexa(hr);
     return false;
   }
 
+  if (StaticPrefs::gfx_webrender_dcomp_win_debug_counter_enabled_AtStartup()) {
+    RefPtr<IDCompositionDeviceDebug> debugDevice;
+    hr = mCompositionDevice->QueryInterface(
+        (IDCompositionDeviceDebug**)getter_AddRefs(debugDevice));
+    if (SUCCEEDED(hr)) {
+      debugDevice->EnableDebugCounters();
+    } else {
+      gfxCriticalNote << "Failed to get IDCompositionDesktopDevice: "
+                      << gfx::hexa(hr);
+    }
+  }
+
   mCompositionTarget->SetRoot(mRootVisual);
   // Set interporation mode to Linear.
   // By default, a visual inherits the interpolation mode of the parent visual.
   // If no visuals set the interpolation mode, the default for the entire visual
   // tree is nearest neighbor interpolation.
   mRootVisual->SetBitmapInterpolationMode(
       DCOMPOSITION_BITMAP_INTERPOLATION_MODE_LINEAR);
   return true;
@@ -74,10 +104,11 @@ void DCLayerTree::SetDefaultSwapChain(ID
   mRootVisual->AddVisual(mDefaultSwapChainVisual, TRUE, nullptr);
   mDefaultSwapChainVisual->SetContent(aSwapChain);
   // Default SwapChain's visual does not need linear interporation.
   mDefaultSwapChainVisual->SetBitmapInterpolationMode(
       DCOMPOSITION_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
   mCompositionDevice->Commit();
 }
 
+#endif
 }  // namespace wr
 }  // namespace mozilla
--- a/gfx/webrender_bindings/DCLayerTree.h
+++ b/gfx/webrender_bindings/DCLayerTree.h
@@ -7,42 +7,52 @@
 #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 IDCompositionDevice2;
 struct IDCompositionTarget;
-struct IDCompositionVisual;
+struct IDCompositionVisual2;
 struct IDXGISwapChain1;
 
 namespace mozilla {
 
 namespace wr {
 
+// Currently, MinGW build environment does not handle IDCompositionDesktopDevice
+// and IDCompositionDevice2
+#if !defined(__MINGW32__)
 /**
  * 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);
+  explicit DCLayerTree(IDCompositionDevice2* aCompositionDevice);
   ~DCLayerTree();
 
   void SetDefaultSwapChain(IDXGISwapChain1* aSwapChain);
 
  protected:
   bool Initialize(HWND aHwnd);
 
-  RefPtr<IDCompositionDevice> mCompositionDevice;
+  RefPtr<IDCompositionDevice2> mCompositionDevice;
   RefPtr<IDCompositionTarget> mCompositionTarget;
-  RefPtr<IDCompositionVisual> mRootVisual;
-  RefPtr<IDCompositionVisual> mDefaultSwapChainVisual;
+  RefPtr<IDCompositionVisual2> mRootVisual;
+  RefPtr<IDCompositionVisual2> mDefaultSwapChainVisual;
 };
+#else
+class DCLayerTree {
+ public:
+  static UniquePtr<DCLayerTree> Create(HWND aHwnd) { return nullptr; }
+  void SetDefaultSwapChain(IDXGISwapChain1* aSwapChain) {}
+};
+#endif
 
 }  // namespace wr
 }  // namespace mozilla
 
 #endif
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -3537,16 +3537,26 @@
   # Keep this pref hidden on non-nightly builds to avoid people accidentally
   # turning it on.
 -   name: gfx.webrender.start-debug-server
     type: RelaxedAtomicBool
     value: false
     mirror: always
 #endif
 
+#ifdef XP_WIN
+  # Enables display of performance debugging counters when DirectComposition
+  # is used.
+  # Performance counters are displayed on the top-right corner of the screen.
+- name: gfx.webrender.dcomp-win.debug-counter.enabled
+  type: bool
+  value: false
+  mirror: once
+#endif
+
 # Use vsync events generated by hardware
 - name: gfx.work-around-driver-bugs
   type: bool
   value: true
   mirror: once
 
 - name: gfx.ycbcr.accurate-conversion
   type: RelaxedAtomicBool