Bug 1728955: part 6) Log result of Windows' `OleSetClipboardResult`. r=masayuki
[gecko.git] / gfx / config / gfxConfigManager.cpp
blob735c462b66a64804174ed70e9b7209ad7617e31e
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/gfx/gfxConfigManager.h"
8 #include "mozilla/gfx/gfxVars.h"
9 #include "mozilla/Preferences.h"
10 #include "mozilla/Components.h"
11 #include "mozilla/StaticPrefs_gfx.h"
12 #include "mozilla/StaticPrefs_layers.h"
13 #include "gfxConfig.h"
14 #include "gfxPlatform.h"
15 #include "nsIGfxInfo.h"
16 #include "nsPrintfCString.h"
17 #include "nsXULAppAPI.h"
19 #ifdef XP_WIN
20 # include "mozilla/WindowsVersion.h"
21 # include "mozilla/gfx/DeviceManagerDx.h"
22 # include "mozilla/gfx/DisplayConfigWindows.h"
23 #endif
25 namespace mozilla {
26 namespace gfx {
28 void gfxConfigManager::Init() {
29 MOZ_ASSERT(XRE_IsParentProcess());
31 EmplaceUserPref("gfx.webrender.compositor", mWrCompositorEnabled);
32 mWrForceEnabled = gfxPlatform::WebRenderPrefEnabled();
33 mWrSoftwareForceEnabled = StaticPrefs::gfx_webrender_software_AtStartup();
34 mWrCompositorForceEnabled =
35 StaticPrefs::gfx_webrender_compositor_force_enabled_AtStartup();
36 mGPUProcessAllowSoftware =
37 StaticPrefs::layers_gpu_process_allow_software_AtStartup();
38 mWrPartialPresent =
39 StaticPrefs::gfx_webrender_max_partial_present_rects_AtStartup() > 0;
40 EmplaceUserPref(StaticPrefs::GetPrefName_gfx_webrender_program_binary_disk(),
41 mWrShaderCache);
42 mWrOptimizedShaders =
43 StaticPrefs::gfx_webrender_use_optimized_shaders_AtStartup();
44 #ifdef XP_WIN
45 mWrForceAngle = StaticPrefs::gfx_webrender_force_angle_AtStartup();
46 mWrForceAngleNoGPUProcess = StaticPrefs::
47 gfx_webrender_enabled_no_gpu_process_with_angle_win_AtStartup();
48 mWrDCompWinEnabled =
49 Preferences::GetBool("gfx.webrender.dcomp-win.enabled", false);
50 #endif
52 mWrEnvForceEnabled = gfxPlatform::WebRenderEnvvarEnabled();
54 #ifdef XP_WIN
55 DeviceManagerDx::Get()->CheckHardwareStretchingSupport(mHwStretchingSupport);
56 mScaledResolution = HasScaledResolution();
57 mIsWin10OrLater = IsWin10OrLater();
58 mWrCompositorDCompRequired = true;
59 #else
60 ++mHwStretchingSupport.mBoth;
61 #endif
63 #ifdef MOZ_WIDGET_GTK
64 mDisableHwCompositingNoWr = true;
65 #endif
67 #ifdef NIGHTLY_BUILD
68 mIsNightly = true;
69 #endif
70 #ifdef EARLY_BETA_OR_EARLIER
71 mIsEarlyBetaOrEarlier = true;
72 #endif
73 mSafeMode = gfxPlatform::InSafeMode();
75 mGfxInfo = components::GfxInfo::Service();
77 mFeatureWr = &gfxConfig::GetFeature(Feature::WEBRENDER);
78 mFeatureWrQualified = &gfxConfig::GetFeature(Feature::WEBRENDER_QUALIFIED);
79 mFeatureWrCompositor = &gfxConfig::GetFeature(Feature::WEBRENDER_COMPOSITOR);
80 mFeatureWrAngle = &gfxConfig::GetFeature(Feature::WEBRENDER_ANGLE);
81 mFeatureWrDComp = &gfxConfig::GetFeature(Feature::WEBRENDER_DCOMP_PRESENT);
82 mFeatureWrPartial = &gfxConfig::GetFeature(Feature::WEBRENDER_PARTIAL);
83 mFeatureWrShaderCache =
84 &gfxConfig::GetFeature(Feature::WEBRENDER_SHADER_CACHE);
85 mFeatureWrOptimizedShaders =
86 &gfxConfig::GetFeature(Feature::WEBRENDER_OPTIMIZED_SHADERS);
87 mFeatureWrSoftware = &gfxConfig::GetFeature(Feature::WEBRENDER_SOFTWARE);
89 mFeatureHwCompositing = &gfxConfig::GetFeature(Feature::HW_COMPOSITING);
90 #ifdef XP_WIN
91 mFeatureD3D11HwAngle = &gfxConfig::GetFeature(Feature::D3D11_HW_ANGLE);
92 mFeatureD3D11Compositing = &gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
93 #endif
94 mFeatureGPUProcess = &gfxConfig::GetFeature(Feature::GPU_PROCESS);
97 void gfxConfigManager::EmplaceUserPref(const char* aPrefName,
98 Maybe<bool>& aValue) {
99 if (Preferences::HasUserValue(aPrefName)) {
100 aValue.emplace(Preferences::GetBool(aPrefName, false));
104 void gfxConfigManager::ConfigureFromBlocklist(long aFeature,
105 FeatureState* aFeatureState) {
106 MOZ_ASSERT(aFeatureState);
108 nsCString blockId;
109 int32_t status;
110 if (!NS_SUCCEEDED(mGfxInfo->GetFeatureStatus(aFeature, blockId, &status))) {
111 aFeatureState->Disable(FeatureStatus::BlockedNoGfxInfo, "gfxInfo is broken",
112 "FEATURE_FAILURE_NO_GFX_INFO"_ns);
114 } else {
115 if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
116 aFeatureState->Disable(FeatureStatus::Blocklisted,
117 "Blocklisted by gfxInfo", blockId);
122 void gfxConfigManager::ConfigureWebRenderQualified() {
123 MOZ_ASSERT(mFeatureWrQualified);
124 MOZ_ASSERT(mFeatureWrCompositor);
126 mFeatureWrQualified->EnableByDefault();
128 nsCString failureId;
129 int32_t status;
130 if (NS_FAILED(mGfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBRENDER,
131 failureId, &status))) {
132 mFeatureWrQualified->Disable(FeatureStatus::BlockedNoGfxInfo,
133 "gfxInfo is broken",
134 "FEATURE_FAILURE_WR_NO_GFX_INFO"_ns);
135 return;
138 switch (status) {
139 case nsIGfxInfo::FEATURE_ALLOW_ALWAYS:
140 case nsIGfxInfo::FEATURE_ALLOW_QUALIFIED:
141 break;
142 case nsIGfxInfo::FEATURE_DENIED:
143 mFeatureWrQualified->Disable(FeatureStatus::Denied, "Not on allowlist",
144 failureId);
145 break;
146 default:
147 mFeatureWrQualified->Disable(FeatureStatus::Blocklisted,
148 "No qualified hardware", failureId);
149 break;
150 case nsIGfxInfo::FEATURE_STATUS_OK:
151 MOZ_ASSERT_UNREACHABLE("We should still be rolling out WebRender!");
152 mFeatureWrQualified->Disable(FeatureStatus::Blocked,
153 "Not controlled by rollout", failureId);
154 break;
158 void gfxConfigManager::ConfigureWebRender() {
159 MOZ_ASSERT(XRE_IsParentProcess());
160 MOZ_ASSERT(mFeatureWr);
161 MOZ_ASSERT(mFeatureWrQualified);
162 MOZ_ASSERT(mFeatureWrCompositor);
163 MOZ_ASSERT(mFeatureWrAngle);
164 MOZ_ASSERT(mFeatureWrDComp);
165 MOZ_ASSERT(mFeatureWrPartial);
166 MOZ_ASSERT(mFeatureWrShaderCache);
167 MOZ_ASSERT(mFeatureWrOptimizedShaders);
168 MOZ_ASSERT(mFeatureWrSoftware);
169 MOZ_ASSERT(mFeatureHwCompositing);
170 MOZ_ASSERT(mFeatureGPUProcess);
172 // Initialize WebRender native compositor usage
173 mFeatureWrCompositor->SetDefaultFromPref("gfx.webrender.compositor", true,
174 false, mWrCompositorEnabled);
176 if (mWrCompositorForceEnabled) {
177 mFeatureWrCompositor->UserForceEnable("Force enabled by pref");
180 ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR,
181 mFeatureWrCompositor);
183 // Disable native compositor when hardware stretching is not supported. It is
184 // for avoiding a problem like Bug 1618370.
185 // XXX Is there a better check for Bug 1618370?
186 if (!mHwStretchingSupport.IsFullySupported() && mScaledResolution) {
187 nsPrintfCString failureId(
188 "FEATURE_FAILURE_NO_HARDWARE_STRETCHING_B%uW%uF%uN%uE%u",
189 mHwStretchingSupport.mBoth, mHwStretchingSupport.mWindowOnly,
190 mHwStretchingSupport.mFullScreenOnly, mHwStretchingSupport.mNone,
191 mHwStretchingSupport.mError);
192 mFeatureWrCompositor->Disable(FeatureStatus::Unavailable,
193 "No hardware stretching support", failureId);
196 mFeatureWr->EnableByDefault();
197 mFeatureWrSoftware->EnableByDefault();
198 ConfigureWebRenderQualified();
200 // envvar works everywhere; note that we need this for testing in CI.
201 // Prior to bug 1523788, the `prefEnabled` check was only done on Nightly,
202 // so as to prevent random users from easily enabling WebRender on
203 // unqualified hardware in beta/release.
204 if (mWrSoftwareForceEnabled) {
205 MOZ_ASSERT(mFeatureWrSoftware->IsEnabled());
206 mFeatureWr->UserDisable("User force-enabled software WR",
207 "FEATURE_FAILURE_USER_FORCE_ENABLED_SW_WR"_ns);
208 } else if (mWrEnvForceEnabled) {
209 mFeatureWr->UserForceEnable("Force enabled by envvar");
210 } else if (mWrForceEnabled) {
211 mFeatureWr->UserForceEnable("Force enabled by pref");
214 if (!mFeatureWrQualified->IsEnabled()) {
215 // No qualified hardware. If we haven't allowed software fallback,
216 // then we need to disable WR.
217 mFeatureWr->Disable(FeatureStatus::Disabled, "Not qualified",
218 "FEATURE_FAILURE_NOT_QUALIFIED"_ns);
221 // HW_COMPOSITING being disabled implies interfacing with the GPU might break
222 if (!mFeatureHwCompositing->IsEnabled()) {
223 mFeatureWr->ForceDisable(FeatureStatus::UnavailableNoHwCompositing,
224 "Hardware compositing is disabled",
225 "FEATURE_FAILURE_WEBRENDER_NEED_HWCOMP"_ns);
228 if (mSafeMode) {
229 mFeatureWr->ForceDisable(FeatureStatus::UnavailableInSafeMode,
230 "Safe-mode is enabled",
231 "FEATURE_FAILURE_SAFE_MODE"_ns);
234 mFeatureWrAngle->EnableByDefault();
235 if (mFeatureD3D11HwAngle) {
236 if (mWrForceAngle) {
237 if (!mFeatureD3D11HwAngle->IsEnabled()) {
238 mFeatureWrAngle->ForceDisable(FeatureStatus::UnavailableNoAngle,
239 "ANGLE is disabled",
240 mFeatureD3D11HwAngle->GetFailureId());
241 } else if (!mFeatureGPUProcess->IsEnabled() &&
242 !mWrForceAngleNoGPUProcess) {
243 // WebRender with ANGLE relies on the GPU process when on Windows
244 mFeatureWrAngle->ForceDisable(
245 FeatureStatus::UnavailableNoGpuProcess, "GPU Process is disabled",
246 "FEATURE_FAILURE_GPU_PROCESS_DISABLED"_ns);
247 } else if (!mFeatureWr->IsEnabled() && !mFeatureWrSoftware->IsEnabled()) {
248 mFeatureWrAngle->ForceDisable(FeatureStatus::Unavailable,
249 "WebRender disabled",
250 "FEATURE_FAILURE_WR_DISABLED"_ns);
252 } else {
253 mFeatureWrAngle->Disable(FeatureStatus::Disabled, "ANGLE is not forced",
254 "FEATURE_FAILURE_ANGLE_NOT_FORCED"_ns);
256 } else {
257 mFeatureWrAngle->Disable(FeatureStatus::Unavailable, "OS not supported",
258 "FEATURE_FAILURE_OS_NOT_SUPPORTED"_ns);
261 if (mWrForceAngle && mFeatureWr->IsEnabled() &&
262 !mFeatureWrAngle->IsEnabled()) {
263 // Ensure we disable WebRender if ANGLE is unavailable and it is required.
264 mFeatureWr->ForceDisable(FeatureStatus::UnavailableNoAngle,
265 "ANGLE is disabled",
266 mFeatureWrAngle->GetFailureId());
269 if (!mFeatureWr->IsEnabled() && mDisableHwCompositingNoWr) {
270 if (mFeatureHwCompositing->IsEnabled()) {
271 // Hardware compositing should be disabled by default if we aren't using
272 // WebRender. We had to check if it is enabled at all, because it may
273 // already have been forced disabled (e.g. safe mode, headless). It may
274 // still be forced on by the user, and if so, this should have no effect.
275 mFeatureHwCompositing->Disable(FeatureStatus::Blocked,
276 "Acceleration blocked by platform", ""_ns);
279 if (!mFeatureHwCompositing->IsEnabled() &&
280 mFeatureGPUProcess->IsEnabled() && !mGPUProcessAllowSoftware) {
281 // We have neither WebRender nor OpenGL, we don't allow the GPU process
282 // for basic compositor, and it wasn't disabled already.
283 mFeatureGPUProcess->Disable(FeatureStatus::Unavailable,
284 "Hardware compositing is unavailable.",
285 ""_ns);
289 mFeatureWrDComp->EnableByDefault();
290 if (!mWrDCompWinEnabled) {
291 mFeatureWrDComp->UserDisable("User disabled via pref",
292 "FEATURE_FAILURE_DCOMP_PREF_DISABLED"_ns);
295 if (!mIsWin10OrLater) {
296 // XXX relax win version to windows 8.
297 mFeatureWrDComp->Disable(FeatureStatus::Unavailable,
298 "Requires Windows 10 or later",
299 "FEATURE_FAILURE_DCOMP_NOT_WIN10"_ns);
302 if (!mIsNightly) {
303 // Disable DirectComposition for NVIDIA users with high/mixed refresh rate
304 // monitors due to rendering artifacts.
305 nsAutoString adapterVendorID;
306 mGfxInfo->GetAdapterVendorID(adapterVendorID);
307 if (adapterVendorID == u"0x10de") {
308 bool mixed = false;
309 int32_t maxRefreshRate = mGfxInfo->GetMaxRefreshRate(&mixed);
310 if (maxRefreshRate > 60 && mixed) {
311 mFeatureWrDComp->Disable(FeatureStatus::Blocked,
312 "Monitor refresh rate too high/mixed",
313 "NVIDIA_REFRESH_RATE_MIXED"_ns);
318 mFeatureWrDComp->MaybeSetFailed(
319 mFeatureWr->IsEnabled(), FeatureStatus::Unavailable, "Requires WebRender",
320 "FEATURE_FAILURE_DCOMP_NOT_WR"_ns);
321 mFeatureWrDComp->MaybeSetFailed(mFeatureWrAngle->IsEnabled(),
322 FeatureStatus::Unavailable, "Requires ANGLE",
323 "FEATURE_FAILURE_DCOMP_NOT_ANGLE"_ns);
325 if (!mFeatureWrDComp->IsEnabled() && mWrCompositorDCompRequired) {
326 mFeatureWrCompositor->ForceDisable(FeatureStatus::Unavailable,
327 "No DirectComposition usage",
328 mFeatureWrDComp->GetFailureId());
331 // Initialize WebRender partial present config.
332 // Partial present is used only when WebRender compositor is not used.
333 if (mWrPartialPresent) {
334 if (mFeatureWr->IsEnabled() || mFeatureWrSoftware->IsEnabled()) {
335 mFeatureWrPartial->EnableByDefault();
337 nsString adapter;
338 mGfxInfo->GetAdapterDeviceID(adapter);
339 // Block partial present on some devices due to rendering issues.
340 // On Mali-Txxx due to bug 1680087 and bug 1707815.
341 // On Adreno 3xx GPUs due to bug 1695771.
342 if (adapter.Find("Mali-T", /*ignoreCase*/ true) >= 0 ||
343 adapter.Find("Adreno (TM) 3", /*ignoreCase*/ true) >= 0) {
344 mFeatureWrPartial->Disable(
345 FeatureStatus::Blocked, "Partial present blocked",
346 "FEATURE_FAILURE_PARTIAL_PRESENT_BLOCKED"_ns);
351 mFeatureWrShaderCache->SetDefaultFromPref(
352 StaticPrefs::GetPrefName_gfx_webrender_program_binary_disk(), true,
353 StaticPrefs::GetPrefDefault_gfx_webrender_program_binary_disk(),
354 mWrShaderCache);
355 ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER_SHADER_CACHE,
356 mFeatureWrShaderCache);
357 if (!mFeatureWr->IsEnabled()) {
358 mFeatureWrShaderCache->ForceDisable(FeatureStatus::Unavailable,
359 "WebRender disabled",
360 "FEATURE_FAILURE_WR_DISABLED"_ns);
363 mFeatureWrOptimizedShaders->EnableByDefault();
364 if (!mWrOptimizedShaders) {
365 mFeatureWrOptimizedShaders->UserDisable("User disabled via pref",
366 "FEATURE_FAILURE_PREF_DISABLED"_ns);
368 ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER_OPTIMIZED_SHADERS,
369 mFeatureWrOptimizedShaders);
370 if (!mFeatureWr->IsEnabled()) {
371 mFeatureWrOptimizedShaders->ForceDisable(FeatureStatus::Unavailable,
372 "WebRender disabled",
373 "FEATURE_FAILURE_WR_DISABLED"_ns);
377 } // namespace gfx
378 } // namespace mozilla