Bug 1864652 - Expose settings for Global Privacy Control. r=geckoview-reviewers,ohall...
[gecko.git] / gfx / config / gfxConfigManager.cpp
blob6ae75c03d9e5d44064c954a53f3a62c7cfaf2714
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 mWrForcePartialPresent =
39 StaticPrefs::gfx_webrender_force_partial_present_AtStartup();
40 mWrPartialPresent =
41 StaticPrefs::gfx_webrender_max_partial_present_rects_AtStartup() > 0;
42 EmplaceUserPref(StaticPrefs::GetPrefName_gfx_webrender_program_binary_disk(),
43 mWrShaderCache);
44 mWrOptimizedShaders =
45 StaticPrefs::gfx_webrender_use_optimized_shaders_AtStartup();
46 mWrScissoredCacheClearsEnabled =
47 StaticPrefs::gfx_webrender_scissored_cache_clears_enabled_AtStartup();
48 mWrScissoredCacheClearsForceEnabled = StaticPrefs::
49 gfx_webrender_scissored_cache_clears_force_enabled_AtStartup();
50 #ifdef XP_WIN
51 mWrForceAngle = StaticPrefs::gfx_webrender_force_angle_AtStartup();
52 mWrForceAngleNoGPUProcess = StaticPrefs::
53 gfx_webrender_enabled_no_gpu_process_with_angle_win_AtStartup();
54 mWrDCompWinEnabled =
55 Preferences::GetBool("gfx.webrender.dcomp-win.enabled", false);
56 #endif
58 mWrEnvForceEnabled = gfxPlatform::WebRenderEnvvarEnabled();
60 #ifdef XP_WIN
61 DeviceManagerDx::Get()->CheckHardwareStretchingSupport(mHwStretchingSupport);
62 mScaledResolution = HasScaledResolution();
63 mIsWin11OrLater = IsWin11OrLater();
64 mWrCompositorDCompRequired = true;
65 #else
66 ++mHwStretchingSupport.mBoth;
67 #endif
69 #ifdef MOZ_WIDGET_GTK
70 mDisableHwCompositingNoWr = true;
71 #endif
73 #ifdef NIGHTLY_BUILD
74 mIsNightly = true;
75 #endif
76 #ifdef EARLY_BETA_OR_EARLIER
77 mIsEarlyBetaOrEarlier = true;
78 #endif
79 mSafeMode = gfxPlatform::InSafeMode();
81 mGfxInfo = components::GfxInfo::Service();
83 mFeatureWr = &gfxConfig::GetFeature(Feature::WEBRENDER);
84 mFeatureWrCompositor = &gfxConfig::GetFeature(Feature::WEBRENDER_COMPOSITOR);
85 mFeatureWrAngle = &gfxConfig::GetFeature(Feature::WEBRENDER_ANGLE);
86 mFeatureWrDComp = &gfxConfig::GetFeature(Feature::WEBRENDER_DCOMP_PRESENT);
87 mFeatureWrPartial = &gfxConfig::GetFeature(Feature::WEBRENDER_PARTIAL);
88 mFeatureWrShaderCache =
89 &gfxConfig::GetFeature(Feature::WEBRENDER_SHADER_CACHE);
90 mFeatureWrOptimizedShaders =
91 &gfxConfig::GetFeature(Feature::WEBRENDER_OPTIMIZED_SHADERS);
92 mFeatureWrScissoredCacheClears =
93 &gfxConfig::GetFeature(Feature::WEBRENDER_SCISSORED_CACHE_CLEARS);
95 mFeatureHwCompositing = &gfxConfig::GetFeature(Feature::HW_COMPOSITING);
96 #ifdef XP_WIN
97 mFeatureD3D11HwAngle = &gfxConfig::GetFeature(Feature::D3D11_HW_ANGLE);
98 mFeatureD3D11Compositing = &gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
99 #endif
100 mFeatureGPUProcess = &gfxConfig::GetFeature(Feature::GPU_PROCESS);
103 void gfxConfigManager::EmplaceUserPref(const char* aPrefName,
104 Maybe<bool>& aValue) {
105 if (Preferences::HasUserValue(aPrefName)) {
106 aValue.emplace(Preferences::GetBool(aPrefName, false));
110 void gfxConfigManager::ConfigureFromBlocklist(long aFeature,
111 FeatureState* aFeatureState) {
112 MOZ_ASSERT(aFeatureState);
114 nsCString blockId;
115 int32_t status;
116 if (!NS_SUCCEEDED(mGfxInfo->GetFeatureStatus(aFeature, blockId, &status))) {
117 aFeatureState->Disable(FeatureStatus::BlockedNoGfxInfo, "gfxInfo is broken",
118 "FEATURE_FAILURE_NO_GFX_INFO"_ns);
119 return;
122 switch (status) {
123 case nsIGfxInfo::FEATURE_STATUS_OK:
124 case nsIGfxInfo::FEATURE_ALLOW_ALWAYS:
125 break;
126 case nsIGfxInfo::FEATURE_ALLOW_QUALIFIED:
127 MOZ_ASSERT_UNREACHABLE("Allowing only qualified, but needs experiment?");
128 break;
129 case nsIGfxInfo::FEATURE_DENIED:
130 aFeatureState->Disable(FeatureStatus::Denied, "Not on allowlist",
131 blockId);
132 break;
133 default:
134 aFeatureState->Disable(FeatureStatus::Blocklisted,
135 "Blocklisted by gfxInfo", blockId);
136 break;
140 void gfxConfigManager::ConfigureWebRender() {
141 MOZ_ASSERT(XRE_IsParentProcess());
142 MOZ_ASSERT(mFeatureWr);
143 MOZ_ASSERT(mFeatureWrCompositor);
144 MOZ_ASSERT(mFeatureWrAngle);
145 MOZ_ASSERT(mFeatureWrDComp);
146 MOZ_ASSERT(mFeatureWrPartial);
147 MOZ_ASSERT(mFeatureWrShaderCache);
148 MOZ_ASSERT(mFeatureWrOptimizedShaders);
149 MOZ_ASSERT(mFeatureWrScissoredCacheClears);
150 MOZ_ASSERT(mFeatureHwCompositing);
151 MOZ_ASSERT(mFeatureGPUProcess);
153 // Initialize WebRender native compositor usage
154 mFeatureWrCompositor->SetDefaultFromPref("gfx.webrender.compositor", true,
155 false, mWrCompositorEnabled);
157 if (mWrCompositorForceEnabled) {
158 mFeatureWrCompositor->UserForceEnable("Force enabled by pref");
161 ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR,
162 mFeatureWrCompositor);
164 // Disable native compositor when hardware stretching is not supported. It is
165 // for avoiding a problem like Bug 1618370.
166 // XXX Is there a better check for Bug 1618370?
167 if (!mHwStretchingSupport.IsFullySupported() && mScaledResolution) {
168 nsPrintfCString failureId(
169 "FEATURE_FAILURE_NO_HARDWARE_STRETCHING_B%uW%uF%uN%uE%u",
170 mHwStretchingSupport.mBoth, mHwStretchingSupport.mWindowOnly,
171 mHwStretchingSupport.mFullScreenOnly, mHwStretchingSupport.mNone,
172 mHwStretchingSupport.mError);
173 mFeatureWrCompositor->Disable(FeatureStatus::Unavailable,
174 "No hardware stretching support", failureId);
177 mFeatureWr->EnableByDefault();
179 // envvar works everywhere; note that we need this for testing in CI.
180 // Prior to bug 1523788, the `prefEnabled` check was only done on Nightly,
181 // so as to prevent random users from easily enabling WebRender on
182 // unqualified hardware in beta/release.
183 if (mWrSoftwareForceEnabled) {
184 mFeatureWr->UserDisable("User force-enabled software WR",
185 "FEATURE_FAILURE_USER_FORCE_ENABLED_SW_WR"_ns);
186 } else if (mWrEnvForceEnabled) {
187 mFeatureWr->UserForceEnable("Force enabled by envvar");
188 } else if (mWrForceEnabled) {
189 mFeatureWr->UserForceEnable("Force enabled by pref");
192 ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER, mFeatureWr);
194 // HW_COMPOSITING being disabled implies interfacing with the GPU might break
195 if (!mFeatureHwCompositing->IsEnabled()) {
196 mFeatureWr->ForceDisable(FeatureStatus::UnavailableNoHwCompositing,
197 "Hardware compositing is disabled",
198 "FEATURE_FAILURE_WEBRENDER_NEED_HWCOMP"_ns);
201 if (mSafeMode) {
202 mFeatureWr->ForceDisable(FeatureStatus::UnavailableInSafeMode,
203 "Safe-mode is enabled",
204 "FEATURE_FAILURE_SAFE_MODE"_ns);
207 mFeatureWrAngle->EnableByDefault();
208 if (mFeatureD3D11HwAngle) {
209 if (mWrForceAngle) {
210 if (!mFeatureD3D11HwAngle->IsEnabled()) {
211 mFeatureWrAngle->ForceDisable(FeatureStatus::UnavailableNoAngle,
212 "ANGLE is disabled",
213 mFeatureD3D11HwAngle->GetFailureId());
214 } else if (!mFeatureGPUProcess->IsEnabled() &&
215 !mWrForceAngleNoGPUProcess) {
216 // WebRender with ANGLE relies on the GPU process when on Windows
217 mFeatureWrAngle->ForceDisable(
218 FeatureStatus::UnavailableNoGpuProcess, "GPU Process is disabled",
219 "FEATURE_FAILURE_GPU_PROCESS_DISABLED"_ns);
221 } else {
222 mFeatureWrAngle->Disable(FeatureStatus::Disabled, "ANGLE is not forced",
223 "FEATURE_FAILURE_ANGLE_NOT_FORCED"_ns);
225 } else {
226 mFeatureWrAngle->Disable(FeatureStatus::Unavailable, "OS not supported",
227 "FEATURE_FAILURE_OS_NOT_SUPPORTED"_ns);
230 if (mWrForceAngle && mFeatureWr->IsEnabled() &&
231 !mFeatureWrAngle->IsEnabled()) {
232 // Ensure we disable WebRender if ANGLE is unavailable and it is required.
233 mFeatureWr->ForceDisable(FeatureStatus::UnavailableNoAngle,
234 "ANGLE is disabled",
235 mFeatureWrAngle->GetFailureId());
238 if (!mFeatureWr->IsEnabled() && mDisableHwCompositingNoWr) {
239 if (mFeatureHwCompositing->IsEnabled()) {
240 // Hardware compositing should be disabled by default if we aren't using
241 // WebRender. We had to check if it is enabled at all, because it may
242 // already have been forced disabled (e.g. safe mode, headless). It may
243 // still be forced on by the user, and if so, this should have no effect.
244 mFeatureHwCompositing->Disable(FeatureStatus::Blocked,
245 "Acceleration blocked by platform", ""_ns);
248 if (!mFeatureHwCompositing->IsEnabled() &&
249 mFeatureGPUProcess->IsEnabled() && !mGPUProcessAllowSoftware) {
250 // We have neither WebRender nor OpenGL, we don't allow the GPU process
251 // for basic compositor, and it wasn't disabled already.
252 mFeatureGPUProcess->Disable(FeatureStatus::Unavailable,
253 "Hardware compositing is unavailable.",
254 ""_ns);
258 mFeatureWrDComp->EnableByDefault();
259 if (!mWrDCompWinEnabled) {
260 mFeatureWrDComp->UserDisable("User disabled via pref",
261 "FEATURE_FAILURE_DCOMP_PREF_DISABLED"_ns);
264 if (!mFeatureGPUProcess->IsEnabled()) {
265 mFeatureWrDComp->Disable(FeatureStatus::Unavailable, "Requires GPU process",
266 "FEATURE_FAILURE_NO_GPU_PROCESS"_ns);
269 if (!mIsWin11OrLater) {
270 // Disable DirectComposition for NVIDIA users on Windows 10 with high/mixed
271 // refresh rate monitors due to rendering artifacts. (See bug 1638709.)
272 nsAutoString adapterVendorID;
273 mGfxInfo->GetAdapterVendorID(adapterVendorID);
274 if (adapterVendorID == u"0x10de") {
275 bool mixed = false;
276 int32_t maxRefreshRate = mGfxInfo->GetMaxRefreshRate(&mixed);
277 if (maxRefreshRate > 60 && mixed) {
278 mFeatureWrDComp->Disable(FeatureStatus::Blocked,
279 "Monitor refresh rate too high/mixed",
280 "NVIDIA_REFRESH_RATE_MIXED"_ns);
285 mFeatureWrDComp->MaybeSetFailed(
286 mFeatureWr->IsEnabled(), FeatureStatus::Unavailable, "Requires WebRender",
287 "FEATURE_FAILURE_DCOMP_NOT_WR"_ns);
288 mFeatureWrDComp->MaybeSetFailed(mFeatureWrAngle->IsEnabled(),
289 FeatureStatus::Unavailable, "Requires ANGLE",
290 "FEATURE_FAILURE_DCOMP_NOT_ANGLE"_ns);
292 if (!mFeatureWrDComp->IsEnabled() && mWrCompositorDCompRequired) {
293 mFeatureWrCompositor->ForceDisable(FeatureStatus::Unavailable,
294 "No DirectComposition usage",
295 mFeatureWrDComp->GetFailureId());
298 // Initialize WebRender partial present config.
299 // Partial present is used only when WebRender compositor is not used.
300 mFeatureWrPartial->SetDefault(mWrPartialPresent, FeatureStatus::Disabled,
301 "User disabled via pref");
302 if (mWrForcePartialPresent) {
303 mFeatureWrPartial->UserForceEnable("Force enabled by pref");
306 ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER_PARTIAL_PRESENT,
307 mFeatureWrPartial);
309 mFeatureWrShaderCache->SetDefaultFromPref(
310 StaticPrefs::GetPrefName_gfx_webrender_program_binary_disk(), true,
311 StaticPrefs::GetPrefDefault_gfx_webrender_program_binary_disk(),
312 mWrShaderCache);
313 ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER_SHADER_CACHE,
314 mFeatureWrShaderCache);
315 if (!mFeatureWr->IsEnabled()) {
316 mFeatureWrShaderCache->ForceDisable(FeatureStatus::Unavailable,
317 "WebRender disabled",
318 "FEATURE_FAILURE_WR_DISABLED"_ns);
321 mFeatureWrOptimizedShaders->EnableByDefault();
322 if (!mWrOptimizedShaders) {
323 mFeatureWrOptimizedShaders->UserDisable("User disabled via pref",
324 "FEATURE_FAILURE_PREF_DISABLED"_ns);
326 ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER_OPTIMIZED_SHADERS,
327 mFeatureWrOptimizedShaders);
328 if (!mFeatureWr->IsEnabled()) {
329 mFeatureWrOptimizedShaders->ForceDisable(FeatureStatus::Unavailable,
330 "WebRender disabled",
331 "FEATURE_FAILURE_WR_DISABLED"_ns);
334 mFeatureWrScissoredCacheClears->SetDefault(mWrScissoredCacheClearsEnabled,
335 FeatureStatus::Disabled,
336 "User disabled via pref");
337 if (mWrScissoredCacheClearsForceEnabled) {
338 mFeatureWrScissoredCacheClears->UserForceEnable("Force enabled by pref");
340 ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER_SCISSORED_CACHE_CLEARS,
341 mFeatureWrScissoredCacheClears);
344 } // namespace gfx
345 } // namespace mozilla