Bug 1630371 - Disable DirectComposition when we have a scaled resolution and no hardware stretching. r=aosmond a=RyanVM
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 16 Apr 2020 21:32:41 +0000
changeset 585581 834249a714905f667486fa5f7173afd81f7d261f
parent 585580 77837af32f02b0cbc178fb5d2a509dc07a28972c
child 585582 22b24959794480b47c0eb7c78ee70cf3188e40a9
push id13022
push userarchaeopteryx@coole-files.de
push dateSun, 19 Apr 2020 21:37:42 +0000
treeherdermozilla-beta@22b249597944 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaosmond, RyanVM
bugs1630371
milestone76.0
Bug 1630371 - Disable DirectComposition when we have a scaled resolution and no hardware stretching. r=aosmond a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D71220
gfx/thebes/DisplayConfigWindows.cpp
gfx/thebes/DisplayConfigWindows.h
gfx/thebes/gfxPlatform.cpp
gfx/thebes/moz.build
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/DisplayConfigWindows.cpp
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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 <iostream>
+#include <windows.h>
+#include <wingdi.h>
+#include <optional>
+#include <vector>
+
+#include "DisplayConfigWindows.h"
+
+namespace mozilla {
+namespace gfx {
+
+using namespace std;
+
+struct DisplayConfig {
+  vector<DISPLAYCONFIG_PATH_INFO> mPaths;
+  vector<DISPLAYCONFIG_MODE_INFO> mModes;
+};
+
+optional<DisplayConfig> GetDisplayConfig() {
+  LONG result;
+
+  UINT32 numPaths;
+  UINT32 numModes;
+  vector<DISPLAYCONFIG_PATH_INFO> paths;
+  vector<DISPLAYCONFIG_MODE_INFO> modes;
+  do {
+    result = GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &numPaths,
+                                         &numModes);
+    if (result != ERROR_SUCCESS) {
+      return {};
+    }
+    // allocate the recommended amount of space
+    paths.resize(numPaths);
+    modes.resize(numModes);
+
+    result = QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &numPaths, paths.data(),
+                                &numModes, modes.data(), NULL);
+    // try again if there wasn't enough space
+  } while (result == ERROR_INSUFFICIENT_BUFFER);
+
+  if (result != ERROR_SUCCESS) return {};
+
+  // shrink to fit the actual number of modes and paths returned
+  modes.resize(numModes);
+  paths.resize(numPaths);
+
+  return DisplayConfig{paths, modes};
+}
+
+bool HasScaledResolution() {
+  auto config = GetDisplayConfig();
+  if (config) {
+    for (auto& path : config->mPaths) {
+      auto& modes = config->mModes;
+      int targetModeIndex = path.targetInfo.modeInfoIdx;
+      int sourceModeIndex = path.sourceInfo.modeInfoIdx;
+
+      // Check if the source and target resolutions are different
+      if ((modes[targetModeIndex]
+               .targetMode.targetVideoSignalInfo.activeSize.cx !=
+           modes[sourceModeIndex].sourceMode.width) ||
+          (modes[targetModeIndex]
+               .targetMode.targetVideoSignalInfo.activeSize.cy !=
+           modes[sourceModeIndex].sourceMode.height)) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+}  // namespace gfx
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/DisplayConfigWindows.h
@@ -0,0 +1,17 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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_thebes_DisplayConfigWindows_h
+#define mozilla_gfx_thebes_DisplayConfigWindows_h
+
+namespace mozilla {
+namespace gfx {
+
+extern bool HasScaledResolution();
+
+}  // namespace gfx
+}  // namespace mozilla
+
+#endif  // mozilla_gfx_thebes_DisplayConfigWindows_h
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -59,16 +59,17 @@
 #endif
 
 #include "nsXULAppAPI.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 
 #if defined(XP_WIN)
 #  include "gfxWindowsPlatform.h"
+#  include "DisplayConfigWindows.h"
 #elif defined(XP_MACOSX)
 #  include "gfxPlatformMac.h"
 #  include "gfxQuartzSurface.h"
 #  include "nsCocoaFeatures.h"
 #elif defined(MOZ_WIDGET_GTK)
 #  include "gfxPlatformGtk.h"
 #elif defined(ANDROID)
 #  include "gfxAndroidPlatform.h"
@@ -3055,17 +3056,18 @@ void gfxPlatform::InitWebRenderConfig() 
     featureComp.Disable(
         FeatureStatus::Unavailable, "No DirectComposition usage",
         NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_DIRECTCOMPOSITION"));
   }
 
   // Disable native compositor when hardware stretching is not supported. It is
   // for avoiding a problem like Bug 1618370.
   // XXX Is there a better check for Bug 1618370?
-  if (!DeviceManagerDx::Get()->CheckHardwareStretchingSupport()) {
+  if (!DeviceManagerDx::Get()->CheckHardwareStretchingSupport() &&
+      HasScaledResolution()) {
     featureComp.Disable(
         FeatureStatus::Unavailable, "No hardware stretching support",
         NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_HARDWARE_STRETCHING"));
   }
 
 #endif
 
   if (!StaticPrefs::gfx_webrender_picture_caching()) {
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -150,16 +150,17 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wi
         'gfxWindowsPlatform.h',
         'gfxWindowsSurface.h',
     ]
     EXPORTS.mozilla.gfx += [
         'PrintTargetPDF.h',
         'PrintTargetWindows.h',
     ]
     SOURCES += [
+        'DisplayConfigWindows.cpp',
         'gfxDWriteCommon.cpp',
         'gfxDWriteFonts.cpp',
         'gfxGDIFont.cpp',
         'gfxGDIFontList.cpp',
         'gfxWindowsNativeDrawing.cpp',
         'gfxWindowsPlatform.cpp',
         'gfxWindowsSurface.cpp',
         'PrintTargetPDF.cpp',