mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
Bug 1632259 - Refactor WebRender configuration logic in gfxPlatform to be testable. r=jrmuizel
We have encountered issues when rolling out WebRender because the configuration logic is quite complicated. It would serve us well to have it in a form that we can easily test. This patch does said refactor, as well as adds an initial set of tests. Differential Revision: https://phabricator.services.mozilla.com/D72027
This commit is contained in:
parent
d0679695d6
commit
f5baf0eea6
163
gfx/config/WebRenderRollout.cpp
Normal file
163
gfx/config/WebRenderRollout.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
/* -*- 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 "WebRenderRollout.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
static const char* const WR_ROLLOUT_PREF = "gfx.webrender.all.qualified";
|
||||
static const bool WR_ROLLOUT_PREF_DEFAULTVALUE = true;
|
||||
static const char* const WR_ROLLOUT_DEFAULT_PREF =
|
||||
"gfx.webrender.all.qualified.default";
|
||||
static const bool WR_ROLLOUT_DEFAULT_PREF_DEFAULTVALUE = false;
|
||||
static const char* const WR_ROLLOUT_PREF_OVERRIDE =
|
||||
"gfx.webrender.all.qualified.gfxPref-default-override";
|
||||
static const char* const WR_ROLLOUT_HW_QUALIFIED_OVERRIDE =
|
||||
"gfx.webrender.all.qualified.hardware-override";
|
||||
static const char* const PROFILE_BEFORE_CHANGE_TOPIC = "profile-before-change";
|
||||
|
||||
// If the "gfx.webrender.all.qualified" pref is true we want to enable
|
||||
// WebRender for qualified hardware. This pref may be set by the Normandy
|
||||
// Preference Rollout feature. The Normandy pref rollout code sets default
|
||||
// values on rolled out prefs on every startup. Default pref values are not
|
||||
// persisted; they only exist in memory for that session. Gfx starts up
|
||||
// before Normandy does. So it's too early to observe the WR qualified pref
|
||||
// changed by Normandy rollout on gfx startup. So we add a shutdown observer to
|
||||
// save the default value on shutdown, and read the saved value on startup
|
||||
// instead.
|
||||
class WrRolloutPrefShutdownSaver final : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Observe(nsISupports*, const char* aTopic,
|
||||
const char16_t*) override {
|
||||
if (strcmp(PROFILE_BEFORE_CHANGE_TOPIC, aTopic) != 0) {
|
||||
// Not the observer we're looking for, move along.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
SaveRolloutPref();
|
||||
|
||||
// Shouldn't receive another notification, remove the observer.
|
||||
RefPtr<WrRolloutPrefShutdownSaver> kungFuDeathGrip(this);
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (NS_WARN_IF(!observerService)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
observerService->RemoveObserver(this, PROFILE_BEFORE_CHANGE_TOPIC);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void AddShutdownObserver() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (NS_WARN_IF(!observerService)) {
|
||||
return;
|
||||
}
|
||||
RefPtr<WrRolloutPrefShutdownSaver> wrRolloutSaver =
|
||||
new WrRolloutPrefShutdownSaver();
|
||||
observerService->AddObserver(wrRolloutSaver, PROFILE_BEFORE_CHANGE_TOPIC,
|
||||
false);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~WrRolloutPrefShutdownSaver() = default;
|
||||
|
||||
void SaveRolloutPref() {
|
||||
if (Preferences::HasUserValue(WR_ROLLOUT_PREF) ||
|
||||
Preferences::GetType(WR_ROLLOUT_PREF) == nsIPrefBranch::PREF_INVALID) {
|
||||
// Don't need to create a backup of default value, because either:
|
||||
// 1. the user or the WR SHIELD study has set a user pref value, or
|
||||
// 2. we've not had a default pref set by Normandy that needs to be saved
|
||||
// for reading before Normandy has started up.
|
||||
return;
|
||||
}
|
||||
|
||||
bool defaultValue =
|
||||
Preferences::GetBool(WR_ROLLOUT_PREF, false, PrefValueKind::Default);
|
||||
Preferences::SetBool(WR_ROLLOUT_DEFAULT_PREF, defaultValue);
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(WrRolloutPrefShutdownSaver, nsIObserver)
|
||||
|
||||
/* static */ void WebRenderRollout::Init() {
|
||||
WrRolloutPrefShutdownSaver::AddShutdownObserver();
|
||||
}
|
||||
|
||||
/* static */ Maybe<bool> WebRenderRollout::CalculateQualifiedOverride() {
|
||||
// This pref only ever gets set in test_pref_rollout_workaround, and in
|
||||
// that case we want to ignore the MOZ_WEBRENDER=0 that will be set by
|
||||
// the test harness so as to actually make the test work.
|
||||
if (!Preferences::HasUserValue(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE)) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(Preferences::GetBool(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE, false));
|
||||
}
|
||||
|
||||
// If the "gfx.webrender.all.qualified" pref is true we want to enable
|
||||
// WebRender for qualifying hardware. The Normandy pref rollout code sets
|
||||
// default values on rolled out prefs on every startup, but Gfx starts up
|
||||
// before Normandy does. So it's too early to observe the WR qualified pref
|
||||
// default value changed by Normandy rollout here yet. So we have a shutdown
|
||||
// observer to save the default value on shutdown, and read the saved default
|
||||
// value here instead, and emulate the behavior of the pref system, with
|
||||
// respect to default/user values of the rollout pref.
|
||||
/* static */ bool WebRenderRollout::CalculateQualified() {
|
||||
auto clearPrefOnExit = MakeScopeExit([]() {
|
||||
// Clear the mirror of the default value of the rollout pref on scope exit,
|
||||
// if we have one. This ensures the user doesn't mess with the pref.
|
||||
// If we need it again, we'll re-create it on shutdown.
|
||||
Preferences::ClearUser(WR_ROLLOUT_DEFAULT_PREF);
|
||||
});
|
||||
|
||||
if (!Preferences::HasUserValue(WR_ROLLOUT_PREF) &&
|
||||
Preferences::HasUserValue(WR_ROLLOUT_DEFAULT_PREF)) {
|
||||
// The user has not set a user pref, and we have a default value set by the
|
||||
// shutdown observer. Let's use this as it should be the value Normandy set
|
||||
// before startup. WR_ROLLOUT_DEFAULT_PREF should only be set on shutdown by
|
||||
// the shutdown observer.
|
||||
// Normandy runs *during* startup, but *after* this code here runs (hence
|
||||
// the need for the workaround).
|
||||
// To have a value stored in the WR_ROLLOUT_DEFAULT_PREF pref here, during
|
||||
// the previous run Normandy must have set a default value on the in-memory
|
||||
// pref, and on shutdown we stored the default value in this
|
||||
// WR_ROLLOUT_DEFAULT_PREF user pref. Then once the user restarts, we
|
||||
// observe this pref. Normandy is the only way a default (not user) value
|
||||
// can be set for this pref.
|
||||
return Preferences::GetBool(WR_ROLLOUT_DEFAULT_PREF,
|
||||
WR_ROLLOUT_DEFAULT_PREF_DEFAULTVALUE);
|
||||
}
|
||||
|
||||
// We don't have a user value for the rollout pref, and we don't have the
|
||||
// value of the rollout pref at last shutdown stored. So we should fallback
|
||||
// to using the default. *But* if we're running
|
||||
// under the Marionette pref rollout work-around test, we may want to override
|
||||
// the default value expressed here, so we can test the "default disabled;
|
||||
// rollout pref enabled" case.
|
||||
// Note that those preferences can't be defined in all.js nor
|
||||
// StaticPrefsList.h as they would create the pref, leading SaveRolloutPref()
|
||||
// above to abort early as the pref would have a valid type.
|
||||
// We also don't want those prefs to appear in about:config.
|
||||
if (Preferences::HasUserValue(WR_ROLLOUT_PREF_OVERRIDE)) {
|
||||
return Preferences::GetBool(WR_ROLLOUT_PREF_OVERRIDE);
|
||||
}
|
||||
return Preferences::GetBool(WR_ROLLOUT_PREF, WR_ROLLOUT_PREF_DEFAULTVALUE);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
27
gfx/config/WebRenderRollout.h
Normal file
27
gfx/config/WebRenderRollout.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* -*- 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_config_WebRenderRollout_h
|
||||
#define mozilla_gfx_config_WebRenderRollout_h
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class WebRenderRollout final {
|
||||
public:
|
||||
static void Init();
|
||||
static Maybe<bool> CalculateQualifiedOverride();
|
||||
static bool CalculateQualified();
|
||||
|
||||
WebRenderRollout() = delete;
|
||||
~WebRenderRollout() = delete;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_gfx_config_WebRenderRollout_h
|
346
gfx/config/gfxConfigManager.cpp
Normal file
346
gfx/config/gfxConfigManager.cpp
Normal file
@ -0,0 +1,346 @@
|
||||
/* -*- 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 "mozilla/gfx/gfxConfigManager.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/StaticPrefs_gfx.h"
|
||||
#include "mozilla/StaticPrefs_layers.h"
|
||||
#include "gfxConfig.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "nsIGfxInfo.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "WebRenderRollout.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include "mozilla/WindowsVersion.h"
|
||||
# include "mozilla/gfx/DeviceManagerDx.h"
|
||||
# include "mozilla/gfx/DisplayConfigWindows.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
void gfxConfigManager::Init() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
WebRenderRollout::Init();
|
||||
mWrQualifiedOverride = WebRenderRollout::CalculateQualifiedOverride();
|
||||
mWrQualified = WebRenderRollout::CalculateQualified();
|
||||
|
||||
EmplaceUserPref("gfx.webrender.compositor", mWrCompositorEnabled);
|
||||
mWrForceEnabled = gfxPlatform::WebRenderPrefEnabled();
|
||||
mWrForceDisabled = StaticPrefs::gfx_webrender_force_disabled_AtStartup();
|
||||
mWrCompositorForceEnabled =
|
||||
StaticPrefs::gfx_webrender_compositor_force_enabled_AtStartup();
|
||||
mGPUProcessAllowSoftware =
|
||||
StaticPrefs::layers_gpu_process_allow_software_AtStartup();
|
||||
mWrPictureCaching = StaticPrefs::gfx_webrender_picture_caching();
|
||||
mWrPartialPresent =
|
||||
StaticPrefs::gfx_webrender_max_partial_present_rects_AtStartup() > 0;
|
||||
#ifdef XP_WIN
|
||||
mWrForceAngle = StaticPrefs::gfx_webrender_force_angle_AtStartup();
|
||||
mWrForceAngleNoGPUProcess = StaticPrefs::
|
||||
gfx_webrender_enabled_no_gpu_process_with_angle_win_AtStartup();
|
||||
mWrDCompWinEnabled =
|
||||
Preferences::GetBool("gfx.webrender.dcomp-win.enabled", false);
|
||||
#endif
|
||||
|
||||
mWrEnvForceEnabled = gfxPlatform::WebRenderEnvvarEnabled();
|
||||
mWrEnvForceDisabled = gfxPlatform::WebRenderEnvvarDisabled();
|
||||
|
||||
#ifdef XP_WIN
|
||||
mHwStretchingSupport =
|
||||
DeviceManagerDx::Get()->CheckHardwareStretchingSupport();
|
||||
mScaledResolution = HasScaledResolution();
|
||||
mIsWin10OrLater = IsWin10OrLater();
|
||||
#else
|
||||
mHwStretchingSupport = true;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
mDisableHwCompositingNoWr = true;
|
||||
#endif
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
mIsNightly = true;
|
||||
#endif
|
||||
mSafeMode = gfxPlatform::InSafeMode();
|
||||
|
||||
mGfxInfo = services::GetGfxInfo();
|
||||
|
||||
mFeatureWr = &gfxConfig::GetFeature(Feature::WEBRENDER);
|
||||
mFeatureWrQualified = &gfxConfig::GetFeature(Feature::WEBRENDER_QUALIFIED);
|
||||
mFeatureWrCompositor = &gfxConfig::GetFeature(Feature::WEBRENDER_COMPOSITOR);
|
||||
mFeatureWrAngle = &gfxConfig::GetFeature(Feature::WEBRENDER_ANGLE);
|
||||
mFeatureWrDComp = &gfxConfig::GetFeature(Feature::WEBRENDER_DCOMP_PRESENT);
|
||||
mFeatureWrPartial = &gfxConfig::GetFeature(Feature::WEBRENDER_PARTIAL);
|
||||
|
||||
mFeatureHwCompositing = &gfxConfig::GetFeature(Feature::HW_COMPOSITING);
|
||||
#ifdef XP_WIN
|
||||
mFeatureD3D11HwAngle = &gfxConfig::GetFeature(Feature::D3D11_HW_ANGLE);
|
||||
#endif
|
||||
mFeatureGPUProcess = &gfxConfig::GetFeature(Feature::GPU_PROCESS);
|
||||
}
|
||||
|
||||
void gfxConfigManager::EmplaceUserPref(const char* aPrefName,
|
||||
Maybe<bool>& aValue) {
|
||||
if (Preferences::HasUserValue(aPrefName)) {
|
||||
aValue.emplace(Preferences::GetBool(aPrefName, false));
|
||||
}
|
||||
}
|
||||
|
||||
void gfxConfigManager::ConfigureFromBlocklist(long aFeature,
|
||||
FeatureState* aFeatureState) {
|
||||
MOZ_ASSERT(aFeatureState);
|
||||
|
||||
nsCString blockId;
|
||||
int32_t status;
|
||||
if (!NS_SUCCEEDED(mGfxInfo->GetFeatureStatus(aFeature, blockId, &status))) {
|
||||
aFeatureState->Disable(FeatureStatus::BlockedNoGfxInfo, "gfxInfo is broken",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_GFX_INFO"));
|
||||
|
||||
} else {
|
||||
if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
|
||||
aFeatureState->Disable(FeatureStatus::Blacklisted,
|
||||
"Blacklisted by gfxInfo", blockId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool gfxConfigManager::ConfigureWebRenderQualified() {
|
||||
MOZ_ASSERT(mFeatureWrQualified);
|
||||
MOZ_ASSERT(mFeatureWrCompositor);
|
||||
|
||||
bool guarded = true;
|
||||
mFeatureWrQualified->EnableByDefault();
|
||||
|
||||
if (mWrQualifiedOverride) {
|
||||
if (!*mWrQualifiedOverride) {
|
||||
mFeatureWrQualified->Disable(
|
||||
FeatureStatus::BlockedOverride, "HW qualification pref override",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_WR_QUALIFICATION_OVERRIDE"));
|
||||
}
|
||||
return guarded;
|
||||
}
|
||||
|
||||
nsCString failureId;
|
||||
int32_t status;
|
||||
if (NS_FAILED(mGfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBRENDER,
|
||||
failureId, &status))) {
|
||||
mFeatureWrQualified->Disable(
|
||||
FeatureStatus::BlockedNoGfxInfo, "gfxInfo is broken",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_WR_NO_GFX_INFO"));
|
||||
return guarded;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case nsIGfxInfo::FEATURE_ALLOW_ALWAYS:
|
||||
// We want to honour ALLOW_ALWAYS on beta and release, but on nightly,
|
||||
// we still want to perform experiments. A larger population is the most
|
||||
// useful, demote nightly to merely qualified.
|
||||
guarded = mIsNightly;
|
||||
break;
|
||||
case nsIGfxInfo::FEATURE_ALLOW_QUALIFIED:
|
||||
break;
|
||||
case nsIGfxInfo::FEATURE_DENIED:
|
||||
mFeatureWrQualified->Disable(FeatureStatus::Denied, "Not on allowlist",
|
||||
failureId);
|
||||
break;
|
||||
default:
|
||||
mFeatureWrQualified->Disable(FeatureStatus::Blacklisted,
|
||||
"No qualified hardware", failureId);
|
||||
break;
|
||||
case nsIGfxInfo::FEATURE_STATUS_OK:
|
||||
MOZ_ASSERT_UNREACHABLE("We should still be rolling out WebRender!");
|
||||
mFeatureWrQualified->Disable(FeatureStatus::Blocked,
|
||||
"Not controlled by rollout", failureId);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mIsNightly) {
|
||||
// Disable WebRender if we don't have DirectComposition
|
||||
nsAutoString adapterVendorID;
|
||||
mGfxInfo->GetAdapterVendorID(adapterVendorID);
|
||||
if (adapterVendorID == u"0x8086") {
|
||||
bool hasBattery = false;
|
||||
mGfxInfo->GetHasBattery(&hasBattery);
|
||||
if (hasBattery && !mFeatureWrCompositor->IsEnabled()) {
|
||||
mFeatureWrQualified->Disable(
|
||||
FeatureStatus::Blocked, "Battery Intel requires os compositor",
|
||||
NS_LITERAL_CSTRING("INTEL_BATTERY_REQUIRES_DCOMP"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return guarded;
|
||||
}
|
||||
|
||||
void gfxConfigManager::ConfigureWebRender() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(mFeatureWr);
|
||||
MOZ_ASSERT(mFeatureWrQualified);
|
||||
MOZ_ASSERT(mFeatureWrCompositor);
|
||||
MOZ_ASSERT(mFeatureWrAngle);
|
||||
MOZ_ASSERT(mFeatureWrDComp);
|
||||
MOZ_ASSERT(mFeatureWrPartial);
|
||||
MOZ_ASSERT(mFeatureHwCompositing);
|
||||
MOZ_ASSERT(mFeatureGPUProcess);
|
||||
|
||||
// Initialize WebRender native compositor usage
|
||||
mFeatureWrCompositor->SetDefaultFromPref("gfx.webrender.compositor", true,
|
||||
false, mWrCompositorEnabled);
|
||||
|
||||
if (mWrCompositorForceEnabled) {
|
||||
mFeatureWrCompositor->UserForceEnable("Force enabled by pref");
|
||||
}
|
||||
|
||||
ConfigureFromBlocklist(nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR,
|
||||
mFeatureWrCompositor);
|
||||
|
||||
// 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 (!mHwStretchingSupport && mScaledResolution) {
|
||||
mFeatureWrCompositor->Disable(
|
||||
FeatureStatus::Unavailable, "No hardware stretching support",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_HARDWARE_STRETCHING"));
|
||||
}
|
||||
|
||||
bool guardedByQualifiedPref = ConfigureWebRenderQualified();
|
||||
|
||||
mFeatureWr->DisableByDefault(
|
||||
FeatureStatus::OptIn, "WebRender is an opt-in feature",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_DEFAULT_OFF"));
|
||||
|
||||
// envvar works everywhere; note that we need this for testing in CI.
|
||||
// Prior to bug 1523788, the `prefEnabled` check was only done on Nightly,
|
||||
// so as to prevent random users from easily enabling WebRender on
|
||||
// unqualified hardware in beta/release.
|
||||
if (mWrEnvForceEnabled) {
|
||||
mFeatureWr->UserEnable("Force enabled by envvar");
|
||||
} else if (mWrForceEnabled) {
|
||||
mFeatureWr->UserEnable("Force enabled by pref");
|
||||
} else if (mFeatureWrQualified->IsEnabled()) {
|
||||
// If the HW is qualified, we enable if either the HW has been qualified
|
||||
// on the release channel (i.e. it's no longer guarded by the qualified
|
||||
// pref), or if the qualified pref is enabled.
|
||||
if (!guardedByQualifiedPref) {
|
||||
mFeatureWr->UserEnable("Qualified in release");
|
||||
} else if (mWrQualified) {
|
||||
mFeatureWr->UserEnable("Qualified enabled by pref");
|
||||
}
|
||||
}
|
||||
|
||||
// If the user set the pref to force-disable, let's do that. This will
|
||||
// override all the other enabling prefs (gfx.webrender.enabled,
|
||||
// gfx.webrender.all, and gfx.webrender.all.qualified).
|
||||
if (mWrForceDisabled ||
|
||||
(mWrEnvForceDisabled && mWrQualifiedOverride.isNothing())) {
|
||||
mFeatureWr->UserDisable(
|
||||
"User force-disabled WR",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_USER_FORCE_DISABLED"));
|
||||
}
|
||||
|
||||
// HW_COMPOSITING being disabled implies interfacing with the GPU might break
|
||||
if (!mFeatureHwCompositing->IsEnabled()) {
|
||||
mFeatureWr->ForceDisable(
|
||||
FeatureStatus::UnavailableNoHwCompositing,
|
||||
"Hardware compositing is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBRENDER_NEED_HWCOMP"));
|
||||
}
|
||||
|
||||
if (mSafeMode) {
|
||||
mFeatureWr->ForceDisable(FeatureStatus::UnavailableInSafeMode,
|
||||
"Safe-mode is enabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_SAFE_MODE"));
|
||||
}
|
||||
|
||||
mFeatureWrAngle->DisableByDefault(
|
||||
FeatureStatus::OptIn, "WebRender ANGLE is an opt-in feature",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_DEFAULT_OFF"));
|
||||
|
||||
if (mFeatureD3D11HwAngle && mWrForceAngle) {
|
||||
if (!mFeatureD3D11HwAngle->IsEnabled()) {
|
||||
mFeatureWr->ForceDisable(
|
||||
FeatureStatus::UnavailableNoAngle, "ANGLE is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_ANGLE_DISABLED"));
|
||||
} else if (!mFeatureGPUProcess->IsEnabled() &&
|
||||
(!mIsNightly || !mWrForceAngleNoGPUProcess)) {
|
||||
// WebRender with ANGLE relies on the GPU process when on Windows
|
||||
mFeatureWr->ForceDisable(
|
||||
FeatureStatus::UnavailableNoGpuProcess, "GPU Process is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_GPU_PROCESS_DISABLED"));
|
||||
} else if (mFeatureWr->IsEnabled()) {
|
||||
mFeatureWrAngle->UserEnable("Enabled");
|
||||
}
|
||||
}
|
||||
|
||||
if (!mFeatureWr->IsEnabled() && mDisableHwCompositingNoWr) {
|
||||
if (mFeatureHwCompositing->IsEnabled()) {
|
||||
// Hardware compositing should be disabled by default if we aren't using
|
||||
// WebRender. We had to check if it is enabled at all, because it may
|
||||
// already have been forced disabled (e.g. safe mode, headless). It may
|
||||
// still be forced on by the user, and if so, this should have no effect.
|
||||
mFeatureHwCompositing->Disable(FeatureStatus::Blocked,
|
||||
"Acceleration blocked by platform",
|
||||
EmptyCString());
|
||||
}
|
||||
|
||||
if (!mFeatureHwCompositing->IsEnabled() &&
|
||||
mFeatureGPUProcess->IsEnabled() && !mGPUProcessAllowSoftware) {
|
||||
// We have neither WebRender nor OpenGL, we don't allow the GPU process
|
||||
// for basic compositor, and it wasn't disabled already.
|
||||
mFeatureGPUProcess->Disable(FeatureStatus::Unavailable,
|
||||
"Hardware compositing is unavailable.",
|
||||
EmptyCString());
|
||||
}
|
||||
}
|
||||
|
||||
mFeatureWrDComp->DisableByDefault(
|
||||
FeatureStatus::OptIn, "WebRender DirectComposition is an opt-in feature",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_DEFAULT_OFF"));
|
||||
|
||||
if (mWrDCompWinEnabled) {
|
||||
// XXX relax win version to windows 8.
|
||||
if (mIsWin10OrLater && mFeatureWr->IsEnabled() &&
|
||||
mFeatureWrAngle->IsEnabled()) {
|
||||
mFeatureWrDComp->UserEnable("Enabled");
|
||||
}
|
||||
}
|
||||
|
||||
if (!mWrPictureCaching) {
|
||||
mFeatureWrCompositor->ForceDisable(
|
||||
FeatureStatus::Unavailable, "Picture caching is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_PICTURE_CACHING_DISABLED"));
|
||||
}
|
||||
|
||||
if (!mFeatureWrDComp->IsEnabled()) {
|
||||
mFeatureWrCompositor->ForceDisable(
|
||||
FeatureStatus::Unavailable, "No DirectComposition usage",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_DIRECTCOMPOSITION"));
|
||||
}
|
||||
|
||||
// Initialize WebRender partial present config.
|
||||
// Partial present is used only when WebRender compositor is not used.
|
||||
if (mWrPartialPresent) {
|
||||
if (mFeatureWr->IsEnabled()) {
|
||||
mFeatureWrPartial->EnableByDefault();
|
||||
if (mWrPictureCaching) {
|
||||
// Call UserEnable() only for reporting to Decision Log.
|
||||
// If feature is enabled by default. It is not reported to Decision Log.
|
||||
mFeatureWrPartial->UserEnable("Enabled");
|
||||
} else {
|
||||
mFeatureWrPartial->ForceDisable(
|
||||
FeatureStatus::Unavailable, "Picture caching is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_PICTURE_CACHING_DISABLED"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
103
gfx/config/gfxConfigManager.h
Normal file
103
gfx/config/gfxConfigManager.h
Normal file
@ -0,0 +1,103 @@
|
||||
/* -*- 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_config_gfxConfigManager_h
|
||||
#define mozilla_gfx_config_gfxConfigManager_h
|
||||
|
||||
#include "gfxFeature.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class gfxConfigManager {
|
||||
public:
|
||||
gfxConfigManager()
|
||||
: mFeatureWr(nullptr),
|
||||
mFeatureWrQualified(nullptr),
|
||||
mFeatureWrCompositor(nullptr),
|
||||
mFeatureWrAngle(nullptr),
|
||||
mFeatureWrDComp(nullptr),
|
||||
mFeatureWrPartial(nullptr),
|
||||
mFeatureHwCompositing(nullptr),
|
||||
mFeatureD3D11HwAngle(nullptr),
|
||||
mFeatureGPUProcess(nullptr),
|
||||
mWrForceEnabled(false),
|
||||
mWrForceDisabled(false),
|
||||
mWrCompositorForceEnabled(false),
|
||||
mWrQualified(false),
|
||||
mWrForceAngle(false),
|
||||
mWrForceAngleNoGPUProcess(false),
|
||||
mWrDCompWinEnabled(false),
|
||||
mWrPictureCaching(false),
|
||||
mWrPartialPresent(false),
|
||||
mGPUProcessAllowSoftware(false),
|
||||
mWrEnvForceEnabled(false),
|
||||
mWrEnvForceDisabled(false),
|
||||
mHwStretchingSupport(false),
|
||||
mScaledResolution(false),
|
||||
mDisableHwCompositingNoWr(false),
|
||||
mIsNightly(false),
|
||||
mSafeMode(false),
|
||||
mIsWin10OrLater(false) {}
|
||||
|
||||
void Init();
|
||||
|
||||
void ConfigureWebRender();
|
||||
void ConfigureFromBlocklist(long aFeature, FeatureState* aFeatureState);
|
||||
|
||||
protected:
|
||||
void EmplaceUserPref(const char* aPrefName, Maybe<bool>& aValue);
|
||||
bool ConfigureWebRenderQualified();
|
||||
|
||||
nsCOMPtr<nsIGfxInfo> mGfxInfo;
|
||||
|
||||
FeatureState* mFeatureWr;
|
||||
FeatureState* mFeatureWrQualified;
|
||||
FeatureState* mFeatureWrCompositor;
|
||||
FeatureState* mFeatureWrAngle;
|
||||
FeatureState* mFeatureWrDComp;
|
||||
FeatureState* mFeatureWrPartial;
|
||||
|
||||
FeatureState* mFeatureHwCompositing;
|
||||
FeatureState* mFeatureD3D11HwAngle;
|
||||
FeatureState* mFeatureGPUProcess;
|
||||
|
||||
/**
|
||||
* Prefs
|
||||
*/
|
||||
Maybe<bool> mWrCompositorEnabled;
|
||||
bool mWrForceEnabled;
|
||||
bool mWrForceDisabled;
|
||||
bool mWrCompositorForceEnabled;
|
||||
bool mWrQualified;
|
||||
Maybe<bool> mWrQualifiedOverride;
|
||||
bool mWrForceAngle;
|
||||
bool mWrForceAngleNoGPUProcess;
|
||||
bool mWrDCompWinEnabled;
|
||||
bool mWrPictureCaching;
|
||||
bool mWrPartialPresent;
|
||||
bool mGPUProcessAllowSoftware;
|
||||
|
||||
/**
|
||||
* Environment variables
|
||||
*/
|
||||
bool mWrEnvForceEnabled;
|
||||
bool mWrEnvForceDisabled;
|
||||
|
||||
/**
|
||||
* System support
|
||||
*/
|
||||
bool mHwStretchingSupport;
|
||||
bool mScaledResolution;
|
||||
bool mDisableHwCompositingNoWr;
|
||||
bool mIsNightly;
|
||||
bool mSafeMode;
|
||||
bool mIsWin10OrLater;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_gfx_config_gfxConfigParams_h
|
@ -49,15 +49,15 @@ bool FeatureState::SetDefault(bool aEnable, FeatureStatus aDisableStatus,
|
||||
}
|
||||
|
||||
void FeatureState::SetDefaultFromPref(const char* aPrefName, bool aIsEnablePref,
|
||||
bool aDefaultValue) {
|
||||
bool aDefaultValue,
|
||||
Maybe<bool> aUserValue) {
|
||||
bool baseValue =
|
||||
Preferences::GetBool(aPrefName, aDefaultValue, PrefValueKind::Default);
|
||||
SetDefault(baseValue == aIsEnablePref, FeatureStatus::Disabled,
|
||||
"Disabled by default");
|
||||
|
||||
if (Preferences::HasUserValue(aPrefName)) {
|
||||
bool userValue = Preferences::GetBool(aPrefName, aDefaultValue);
|
||||
if (userValue == aIsEnablePref) {
|
||||
if (aUserValue) {
|
||||
if (*aUserValue == aIsEnablePref) {
|
||||
nsCString message("Enabled via ");
|
||||
message.AppendASCII(aPrefName);
|
||||
UserEnable(message.get());
|
||||
@ -70,6 +70,16 @@ void FeatureState::SetDefaultFromPref(const char* aPrefName, bool aIsEnablePref,
|
||||
}
|
||||
}
|
||||
|
||||
void FeatureState::SetDefaultFromPref(const char* aPrefName, bool aIsEnablePref,
|
||||
bool aDefaultValue) {
|
||||
Maybe<bool> userValue;
|
||||
if (Preferences::HasUserValue(aPrefName)) {
|
||||
userValue.emplace(Preferences::GetBool(aPrefName, aDefaultValue));
|
||||
}
|
||||
|
||||
SetDefaultFromPref(aPrefName, aIsEnablePref, aDefaultValue, userValue);
|
||||
}
|
||||
|
||||
bool FeatureState::InitOrUpdate(bool aEnable, FeatureStatus aDisableStatus,
|
||||
const char* aDisableMessage) {
|
||||
if (!IsInitialized()) {
|
||||
|
@ -10,27 +10,30 @@
|
||||
#include <stdint.h>
|
||||
#include "gfxTelemetry.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
#define GFX_FEATURE_MAP(_) \
|
||||
/* Name, Type, Description */ \
|
||||
_(HW_COMPOSITING, Feature, "Compositing") \
|
||||
_(D3D11_COMPOSITING, Feature, "Direct3D11 Compositing") \
|
||||
_(OPENGL_COMPOSITING, Feature, "OpenGL Compositing") \
|
||||
_(DIRECT2D, Feature, "Direct2D") \
|
||||
_(D3D11_HW_ANGLE, Feature, "Direct3D11 hardware ANGLE") \
|
||||
_(DIRECT_DRAW, Feature, "DirectDraw") \
|
||||
_(GPU_PROCESS, Feature, "GPU Process") \
|
||||
_(WEBRENDER, Feature, "WebRender") \
|
||||
_(WEBRENDER_QUALIFIED, Feature, "WebRender qualified") \
|
||||
_(WEBRENDER_COMPOSITOR, Feature, "WebRender native compositor") \
|
||||
_(WEBRENDER_PARTIAL, Feature, "WebRender partial present") \
|
||||
_(OMTP, Feature, "Off Main Thread Painting") \
|
||||
_(ADVANCED_LAYERS, Feature, "Advanced Layers") \
|
||||
_(WEBGPU, Feature, "WebGPU") \
|
||||
#define GFX_FEATURE_MAP(_) \
|
||||
/* Name, Type, Description */ \
|
||||
_(HW_COMPOSITING, Feature, "Compositing") \
|
||||
_(D3D11_COMPOSITING, Feature, "Direct3D11 Compositing") \
|
||||
_(OPENGL_COMPOSITING, Feature, "OpenGL Compositing") \
|
||||
_(DIRECT2D, Feature, "Direct2D") \
|
||||
_(D3D11_HW_ANGLE, Feature, "Direct3D11 hardware ANGLE") \
|
||||
_(DIRECT_DRAW, Feature, "DirectDraw") \
|
||||
_(GPU_PROCESS, Feature, "GPU Process") \
|
||||
_(WEBRENDER, Feature, "WebRender") \
|
||||
_(WEBRENDER_QUALIFIED, Feature, "WebRender qualified") \
|
||||
_(WEBRENDER_COMPOSITOR, Feature, "WebRender native compositor") \
|
||||
_(WEBRENDER_PARTIAL, Feature, "WebRender partial present") \
|
||||
_(WEBRENDER_ANGLE, Feature, "WebRender ANGLE") \
|
||||
_(WEBRENDER_DCOMP_PRESENT, Feature, "WebRender DirectComposition") \
|
||||
_(OMTP, Feature, "Off Main Thread Painting") \
|
||||
_(ADVANCED_LAYERS, Feature, "Advanced Layers") \
|
||||
_(WEBGPU, Feature, "WebGPU") \
|
||||
/* Add new entries above this comment */
|
||||
|
||||
enum class Feature : uint32_t {
|
||||
@ -42,8 +45,11 @@ enum class Feature : uint32_t {
|
||||
|
||||
class FeatureState {
|
||||
friend class gfxConfig;
|
||||
friend class GfxConfigManager; // for testing
|
||||
|
||||
public:
|
||||
FeatureState() { Reset(); }
|
||||
|
||||
bool IsEnabled() const;
|
||||
FeatureStatus GetValue() const;
|
||||
|
||||
@ -54,6 +60,8 @@ class FeatureState {
|
||||
const char* aDisableMessage);
|
||||
bool InitOrUpdate(bool aEnable, FeatureStatus aDisableStatus,
|
||||
const char* aMessage);
|
||||
void SetDefaultFromPref(const char* aPrefName, bool aIsEnablePref,
|
||||
bool aDefaultValue, Maybe<bool> aUserValue);
|
||||
void SetDefaultFromPref(const char* aPrefName, bool aIsEnablePref,
|
||||
bool aDefaultValue);
|
||||
void UserEnable(const char* aMessage);
|
||||
|
@ -11,14 +11,17 @@ EXPORTS += [
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.gfx += [
|
||||
'gfxConfigManager.h',
|
||||
'gfxVarReceiver.h',
|
||||
'gfxVars.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'gfxConfig.cpp',
|
||||
'gfxConfigManager.cpp',
|
||||
'gfxFeature.cpp',
|
||||
'gfxVars.cpp',
|
||||
'WebRenderRollout.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
624
gfx/tests/gtest/TestConfigManager.cpp
Normal file
624
gfx/tests/gtest/TestConfigManager.cpp
Normal file
@ -0,0 +1,624 @@
|
||||
/* -*- 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 "gtest/gtest.h"
|
||||
|
||||
#include "gfxFeature.h"
|
||||
#include "mozilla/gfx/gfxConfigManager.h"
|
||||
#include "nsIGfxInfo.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class MockGfxInfo final : public nsIGfxInfo {
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
int32_t mStatusWr;
|
||||
int32_t mStatusWrCompositor;
|
||||
Maybe<bool> mHasBattery;
|
||||
const char* mVendorId;
|
||||
|
||||
// Default allows WebRender + compositor, and is desktop NVIDIA.
|
||||
MockGfxInfo()
|
||||
: mStatusWr(nsIGfxInfo::FEATURE_ALLOW_ALWAYS),
|
||||
mStatusWrCompositor(nsIGfxInfo::FEATURE_STATUS_OK),
|
||||
mHasBattery(Some(false)),
|
||||
mVendorId("0x10de") {}
|
||||
|
||||
NS_IMETHOD GetFeatureStatus(int32_t aFeature, nsACString& aFailureId,
|
||||
int32_t* _retval) override {
|
||||
switch (aFeature) {
|
||||
case nsIGfxInfo::FEATURE_WEBRENDER:
|
||||
*_retval = mStatusWr;
|
||||
break;
|
||||
case nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR:
|
||||
*_retval = mStatusWrCompositor;
|
||||
break;
|
||||
default:
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetHasBattery(bool* aHasBattery) override {
|
||||
if (mHasBattery.isNothing()) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
*aHasBattery = *mHasBattery;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetAdapterVendorID(nsAString& aAdapterVendorID) override {
|
||||
if (!mVendorId) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
aAdapterVendorID.AssignASCII(mVendorId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The following methods we don't need for testing gfxConfigManager.
|
||||
NS_IMETHOD GetFeatureSuggestedDriverVersion(int32_t aFeature,
|
||||
nsAString& _retval) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetMonitors(JSContext* cx,
|
||||
JS::MutableHandleValue _retval) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetFailures(nsTArray<int32_t>& indices,
|
||||
nsTArray<nsCString>& failures) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD_(void) LogFailure(const nsACString& failure) override {}
|
||||
NS_IMETHOD GetInfo(JSContext*, JS::MutableHandle<JS::Value>) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetFeatures(JSContext*, JS::MutableHandle<JS::Value>) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetFeatureLog(JSContext*, JS::MutableHandle<JS::Value>) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetActiveCrashGuards(JSContext*,
|
||||
JS::MutableHandle<JS::Value>) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetContentBackend(nsAString& aContentBackend) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetUsingGPUProcess(bool* aOutValue) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetWebRenderEnabled(bool* aWebRenderEnabled) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetIsHeadless(bool* aIsHeadless) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetUsesTiling(bool* aUsesTiling) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetContentUsesTiling(bool* aUsesTiling) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetOffMainThreadPaintEnabled(
|
||||
bool* aOffMainThreadPaintEnabled) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetOffMainThreadPaintWorkerCount(
|
||||
int32_t* aOffMainThreadPaintWorkerCount) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetTargetFrameRate(uint32_t* aTargetFrameRate) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetD2DEnabled(bool* aD2DEnabled) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetDWriteEnabled(bool* aDWriteEnabled) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetDWriteVersion(nsAString& aDwriteVersion) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetCleartypeParameters(nsAString& aCleartypeParams) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetWindowProtocol(nsAString& aWindowProtocol) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetDesktopEnvironment(nsAString& aDesktopEnvironment) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDescription(nsAString& aAdapterDescription) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDriver(nsAString& aAdapterDriver) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDeviceID(nsAString& aAdapterDeviceID) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterSubsysID(nsAString& aAdapterSubsysID) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterRAM(uint32_t* aAdapterRAM) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDriverVendor(nsAString& aAdapterDriverVendor) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDriverVersion(
|
||||
nsAString& aAdapterDriverVersion) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDriverDate(nsAString& aAdapterDriverDate) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDescription2(nsAString& aAdapterDescription) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDriver2(nsAString& aAdapterDriver) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterVendorID2(nsAString& aAdapterVendorID) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDeviceID2(nsAString& aAdapterDeviceID) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterSubsysID2(nsAString& aAdapterSubsysID) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterRAM2(uint32_t* aAdapterRAM) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDriverVendor2(nsAString& aAdapterDriverVendor) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDriverVersion2(
|
||||
nsAString& aAdapterDriverVersion) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetAdapterDriverDate2(nsAString& aAdapterDriverDate) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetIsGPU2Active(bool* aIsGPU2Active) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetDisplayWidth(nsTArray<uint32_t>& aDisplayWidth) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD GetDisplayHeight(nsTArray<uint32_t>& aDisplayHeight) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD ControlGPUProcessForXPCShell(bool aEnable,
|
||||
bool* _retval) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD_(void) GetData() override {}
|
||||
|
||||
private:
|
||||
virtual ~MockGfxInfo() = default;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(MockGfxInfo, nsIGfxInfo)
|
||||
|
||||
class GfxConfigManager : public ::testing::Test, public gfxConfigManager {
|
||||
public:
|
||||
GfxConfigManager() {
|
||||
mFeatureWr = &mFeatures.mWr;
|
||||
mFeatureWrQualified = &mFeatures.mWrQualified;
|
||||
mFeatureWrCompositor = &mFeatures.mWrCompositor;
|
||||
mFeatureWrAngle = &mFeatures.mWrAngle;
|
||||
mFeatureWrDComp = &mFeatures.mWrDComp;
|
||||
mFeatureWrPartial = &mFeatures.mWrPartial;
|
||||
mFeatureHwCompositing = &mFeatures.mHwCompositing;
|
||||
mFeatureD3D11HwAngle = &mFeatures.mD3D11HwAngle;
|
||||
mFeatureGPUProcess = &mFeatures.mGPUProcess;
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
mMockGfxInfo = new MockGfxInfo();
|
||||
mGfxInfo = mMockGfxInfo;
|
||||
|
||||
// By default, turn everything on. This effectively assumes we are on
|
||||
// qualified nightly Windows 10 with DirectComposition support.
|
||||
mFeatureHwCompositing->EnableByDefault();
|
||||
mFeatureD3D11HwAngle->EnableByDefault();
|
||||
mFeatureGPUProcess->EnableByDefault();
|
||||
|
||||
mWrCompositorEnabled.emplace(true);
|
||||
mWrQualified = true;
|
||||
mWrPictureCaching = true;
|
||||
mWrPartialPresent = true;
|
||||
mWrForceAngle = true;
|
||||
mWrDCompWinEnabled = true;
|
||||
mHwStretchingSupport = true;
|
||||
mIsWin10OrLater = true;
|
||||
mIsNightly = true;
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
mFeatures.mWr.Reset();
|
||||
mFeatures.mWrQualified.Reset();
|
||||
mFeatures.mWrCompositor.Reset();
|
||||
mFeatures.mWrAngle.Reset();
|
||||
mFeatures.mWrDComp.Reset();
|
||||
mFeatures.mWrPartial.Reset();
|
||||
mFeatures.mHwCompositing.Reset();
|
||||
mFeatures.mD3D11HwAngle.Reset();
|
||||
mFeatures.mGPUProcess.Reset();
|
||||
}
|
||||
|
||||
struct {
|
||||
FeatureState mWr;
|
||||
FeatureState mWrQualified;
|
||||
FeatureState mWrCompositor;
|
||||
FeatureState mWrAngle;
|
||||
FeatureState mWrDComp;
|
||||
FeatureState mWrPartial;
|
||||
FeatureState mHwCompositing;
|
||||
FeatureState mD3D11HwAngle;
|
||||
FeatureState mGPUProcess;
|
||||
} mFeatures;
|
||||
|
||||
RefPtr<MockGfxInfo> mMockGfxInfo;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderDefault) {
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderNoPartialPresent) {
|
||||
mWrPartialPresent = false;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderNoPictureCaching) {
|
||||
mWrPictureCaching = false;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderScaledResolutionWithHwStretching) {
|
||||
mScaledResolution = true;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderScaledResolutionNoHwStretching) {
|
||||
mHwStretchingSupport = false;
|
||||
mScaledResolution = true;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderEnabledWithDisableHwCompositingNoWr) {
|
||||
mDisableHwCompositingNoWr = true;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderDisabledWithDisableHwCompositingNoWr) {
|
||||
mDisableHwCompositingNoWr = true;
|
||||
mWrQualified = false;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderDisabledWithAllowSoftwareGPUProcess) {
|
||||
mDisableHwCompositingNoWr = true;
|
||||
mWrQualified = false;
|
||||
mGPUProcessAllowSoftware = true;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderQualifiedOverrideDisabled) {
|
||||
mWrQualifiedOverride.emplace(false);
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_FALSE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderSafeMode) {
|
||||
mSafeMode = true;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderEarlierThanWindows10) {
|
||||
mIsWin10OrLater = false;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderDCompDisabled) {
|
||||
mWrDCompWinEnabled = false;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderForceAngleDisabled) {
|
||||
mWrForceAngle = false;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderD3D11HwAngleDisabled) {
|
||||
mFeatures.mD3D11HwAngle.UserDisable("", EmptyCString());
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderD3D11HwAngleAndForceAngleDisabled) {
|
||||
mWrForceAngle = false;
|
||||
mFeatures.mD3D11HwAngle.UserDisable("", EmptyCString());
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderGPUProcessDisabled) {
|
||||
mFeatures.mGPUProcess.UserDisable("", EmptyCString());
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderQualifiedAndBlocklistAllowQualified) {
|
||||
mMockGfxInfo->mStatusWr = nsIGfxInfo::FEATURE_ALLOW_QUALIFIED;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderQualifiedAndBlocklistAllowAlways) {
|
||||
mIsNightly = false;
|
||||
mMockGfxInfo->mStatusWr = nsIGfxInfo::FEATURE_ALLOW_ALWAYS;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderNotQualifiedAndBlocklistAllowQualified) {
|
||||
mWrQualified = false;
|
||||
mMockGfxInfo->mStatusWr = nsIGfxInfo::FEATURE_ALLOW_QUALIFIED;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderNotQualifiedAndBlocklistAllowAlways) {
|
||||
mWrQualified = false;
|
||||
mIsNightly = false;
|
||||
mMockGfxInfo->mStatusWr = nsIGfxInfo::FEATURE_ALLOW_ALWAYS;
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderIntelBatteryNoPictureCaching) {
|
||||
mWrPictureCaching = false;
|
||||
mMockGfxInfo->mHasBattery.ref() = true;
|
||||
mMockGfxInfo->mVendorId = "0x8086";
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GfxConfigManager, WebRenderIntelBatteryNoHwStretchingNotNightly) {
|
||||
mIsNightly = false;
|
||||
mHwStretchingSupport = false;
|
||||
mScaledResolution = true;
|
||||
mMockGfxInfo->mHasBattery.ref() = true;
|
||||
mMockGfxInfo->mVendorId = "0x8086";
|
||||
ConfigureWebRender();
|
||||
|
||||
EXPECT_FALSE(mFeatures.mWrQualified.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWr.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
|
||||
EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
|
||||
EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
|
||||
}
|
@ -13,6 +13,7 @@ UNIFIED_SOURCES += [
|
||||
'TestBSPTree.cpp',
|
||||
'TestBufferRotation.cpp',
|
||||
'TestColorNames.cpp',
|
||||
'TestConfigManager.cpp',
|
||||
'TestGfxWidgets.cpp',
|
||||
'TestJobScheduler.cpp',
|
||||
'TestLayers.cpp',
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "mozilla/webrender/webrender_ffi.h"
|
||||
#include "mozilla/layers/PaintThread.h"
|
||||
#include "mozilla/gfx/gfxConfigManager.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/gfx/GraphicsMessages.h"
|
||||
@ -64,7 +65,6 @@
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include "gfxWindowsPlatform.h"
|
||||
# include "DisplayConfigWindows.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
# include "gfxPlatformMac.h"
|
||||
# include "gfxQuartzSurface.h"
|
||||
@ -80,7 +80,6 @@
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include "mozilla/WindowsVersion.h"
|
||||
# include "mozilla/gfx/DeviceManagerDx.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WAYLAND
|
||||
@ -798,82 +797,6 @@ WebRenderMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
#undef REPORT_INTERNER
|
||||
#undef REPORT_DATA_STORE
|
||||
|
||||
static const char* const WR_ROLLOUT_PREF = "gfx.webrender.all.qualified";
|
||||
static const bool WR_ROLLOUT_PREF_DEFAULTVALUE = true;
|
||||
static const char* const WR_ROLLOUT_DEFAULT_PREF =
|
||||
"gfx.webrender.all.qualified.default";
|
||||
static const bool WR_ROLLOUT_DEFAULT_PREF_DEFAULTVALUE = false;
|
||||
static const char* const WR_ROLLOUT_PREF_OVERRIDE =
|
||||
"gfx.webrender.all.qualified.gfxPref-default-override";
|
||||
static const char* const WR_ROLLOUT_HW_QUALIFIED_OVERRIDE =
|
||||
"gfx.webrender.all.qualified.hardware-override";
|
||||
static const char* const PROFILE_BEFORE_CHANGE_TOPIC = "profile-before-change";
|
||||
|
||||
// If the "gfx.webrender.all.qualified" pref is true we want to enable
|
||||
// WebRender for qualified hardware. This pref may be set by the Normandy
|
||||
// Preference Rollout feature. The Normandy pref rollout code sets default
|
||||
// values on rolled out prefs on every startup. Default pref values are not
|
||||
// persisted; they only exist in memory for that session. Gfx starts up
|
||||
// before Normandy does. So it's too early to observe the WR qualified pref
|
||||
// changed by Normandy rollout on gfx startup. So we add a shutdown observer to
|
||||
// save the default value on shutdown, and read the saved value on startup
|
||||
// instead.
|
||||
class WrRolloutPrefShutdownSaver : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Observe(nsISupports*, const char* aTopic,
|
||||
const char16_t*) override {
|
||||
if (strcmp(PROFILE_BEFORE_CHANGE_TOPIC, aTopic) != 0) {
|
||||
// Not the observer we're looking for, move along.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
SaveRolloutPref();
|
||||
|
||||
// Shouldn't receive another notification, remove the observer.
|
||||
RefPtr<WrRolloutPrefShutdownSaver> kungFuDeathGrip(this);
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (NS_WARN_IF(!observerService)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
observerService->RemoveObserver(this, PROFILE_BEFORE_CHANGE_TOPIC);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void AddShutdownObserver() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (NS_WARN_IF(!observerService)) {
|
||||
return;
|
||||
}
|
||||
RefPtr<WrRolloutPrefShutdownSaver> wrRolloutSaver =
|
||||
new WrRolloutPrefShutdownSaver();
|
||||
observerService->AddObserver(wrRolloutSaver, PROFILE_BEFORE_CHANGE_TOPIC,
|
||||
false);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~WrRolloutPrefShutdownSaver() = default;
|
||||
|
||||
void SaveRolloutPref() {
|
||||
if (Preferences::HasUserValue(WR_ROLLOUT_PREF) ||
|
||||
Preferences::GetType(WR_ROLLOUT_PREF) == nsIPrefBranch::PREF_INVALID) {
|
||||
// Don't need to create a backup of default value, because either:
|
||||
// 1. the user or the WR SHIELD study has set a user pref value, or
|
||||
// 2. we've not had a default pref set by Normandy that needs to be saved
|
||||
// for reading before Normandy has started up.
|
||||
return;
|
||||
}
|
||||
|
||||
bool defaultValue =
|
||||
Preferences::GetBool(WR_ROLLOUT_PREF, false, PrefValueKind::Default);
|
||||
Preferences::SetBool(WR_ROLLOUT_DEFAULT_PREF, defaultValue);
|
||||
}
|
||||
};
|
||||
|
||||
static void FrameRatePrefChanged(const char* aPref, void*) {
|
||||
int32_t newRate = gfxPlatform::ForceSoftwareVsync()
|
||||
? gfxPlatform::GetSoftwareVsyncRate()
|
||||
@ -884,8 +807,6 @@ static void FrameRatePrefChanged(const char* aPref, void*) {
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(WrRolloutPrefShutdownSaver, nsIObserver)
|
||||
|
||||
void gfxPlatform::Init() {
|
||||
MOZ_RELEASE_ASSERT(!XRE_IsGPUProcess(), "GFX: Not allowed in GPU process.");
|
||||
MOZ_RELEASE_ASSERT(!XRE_IsRDDProcess(), "GFX: Not allowed in RDD process.");
|
||||
@ -928,8 +849,6 @@ void gfxPlatform::Init() {
|
||||
}
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
WrRolloutPrefShutdownSaver::AddShutdownObserver();
|
||||
|
||||
nsCOMPtr<nsIFile> profDir;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_PROFILE_DIR_STARTUP,
|
||||
getter_AddRefs(profDir));
|
||||
@ -1237,22 +1156,6 @@ static bool IsFeatureSupported(long aFeature, bool aDefault) {
|
||||
return status == nsIGfxInfo::FEATURE_STATUS_OK;
|
||||
}
|
||||
|
||||
static void ApplyGfxInfoFeature(long aFeature, FeatureState& aFeatureState) {
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
nsCString blockId;
|
||||
int32_t status;
|
||||
if (!NS_SUCCEEDED(gfxInfo->GetFeatureStatus(aFeature, blockId, &status))) {
|
||||
aFeatureState.Disable(FeatureStatus::BlockedNoGfxInfo, "gfxInfo is broken",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_GFX_INFO"));
|
||||
|
||||
} else {
|
||||
if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
|
||||
aFeatureState.Disable(FeatureStatus::Blacklisted,
|
||||
"Blacklisted by gfxInfo", blockId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static*/
|
||||
bool gfxPlatform::IsDXInterop2Blocked() {
|
||||
return !IsFeatureSupported(nsIGfxInfo::FEATURE_DX_INTEROP2, false);
|
||||
@ -2770,140 +2673,12 @@ bool gfxPlatform::WebRenderEnvvarEnabled() {
|
||||
return (env && *env == '1');
|
||||
}
|
||||
|
||||
static bool WebRenderEnvvarDisabled() {
|
||||
/*static*/
|
||||
bool gfxPlatform::WebRenderEnvvarDisabled() {
|
||||
const char* env = PR_GetEnv("MOZ_WEBRENDER");
|
||||
return (env && *env == '0');
|
||||
}
|
||||
|
||||
static bool InMarionetteRolloutTest() {
|
||||
// This pref only ever gets set in test_pref_rollout_workaround, and in
|
||||
// that case we want to ignore the MOZ_WEBRENDER=0 that will be set by
|
||||
// the test harness so as to actually make the test work.
|
||||
return Preferences::HasUserValue(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE);
|
||||
}
|
||||
|
||||
// If the "gfx.webrender.all.qualified" pref is true we want to enable
|
||||
// WebRender for qualifying hardware. The Normandy pref rollout code sets
|
||||
// default values on rolled out prefs on every startup, but Gfx starts up
|
||||
// before Normandy does. So it's too early to observe the WR qualified pref
|
||||
// default value changed by Normandy rollout here yet. So we have a shutdown
|
||||
// observer to save the default value on shutdown, and read the saved default
|
||||
// value here instead, and emulate the behavior of the pref system, with
|
||||
// respect to default/user values of the rollout pref.
|
||||
static bool CalculateWrQualifiedPrefValue() {
|
||||
auto clearPrefOnExit = MakeScopeExit([]() {
|
||||
// Clear the mirror of the default value of the rollout pref on scope exit,
|
||||
// if we have one. This ensures the user doesn't mess with the pref.
|
||||
// If we need it again, we'll re-create it on shutdown.
|
||||
Preferences::ClearUser(WR_ROLLOUT_DEFAULT_PREF);
|
||||
});
|
||||
|
||||
if (!Preferences::HasUserValue(WR_ROLLOUT_PREF) &&
|
||||
Preferences::HasUserValue(WR_ROLLOUT_DEFAULT_PREF)) {
|
||||
// The user has not set a user pref, and we have a default value set by the
|
||||
// shutdown observer. Let's use this as it should be the value Normandy set
|
||||
// before startup. WR_ROLLOUT_DEFAULT_PREF should only be set on shutdown by
|
||||
// the shutdown observer.
|
||||
// Normandy runs *during* startup, but *after* this code here runs (hence
|
||||
// the need for the workaround).
|
||||
// To have a value stored in the WR_ROLLOUT_DEFAULT_PREF pref here, during
|
||||
// the previous run Normandy must have set a default value on the in-memory
|
||||
// pref, and on shutdown we stored the default value in this
|
||||
// WR_ROLLOUT_DEFAULT_PREF user pref. Then once the user restarts, we
|
||||
// observe this pref. Normandy is the only way a default (not user) value
|
||||
// can be set for this pref.
|
||||
return Preferences::GetBool(WR_ROLLOUT_DEFAULT_PREF,
|
||||
WR_ROLLOUT_DEFAULT_PREF_DEFAULTVALUE);
|
||||
}
|
||||
|
||||
// We don't have a user value for the rollout pref, and we don't have the
|
||||
// value of the rollout pref at last shutdown stored. So we should fallback
|
||||
// to using the default. *But* if we're running
|
||||
// under the Marionette pref rollout work-around test, we may want to override
|
||||
// the default value expressed here, so we can test the "default disabled;
|
||||
// rollout pref enabled" case.
|
||||
// Note that those preferences can't be defined in all.js nor
|
||||
// StaticPrefsList.h as they would create the pref, leading SaveRolloutPref()
|
||||
// above to abort early as the pref would have a valid type.
|
||||
// We also don't want those prefs to appear in about:config.
|
||||
if (Preferences::HasUserValue(WR_ROLLOUT_PREF_OVERRIDE)) {
|
||||
return Preferences::GetBool(WR_ROLLOUT_PREF_OVERRIDE);
|
||||
}
|
||||
return Preferences::GetBool(WR_ROLLOUT_PREF, WR_ROLLOUT_PREF_DEFAULTVALUE);
|
||||
}
|
||||
|
||||
static FeatureState& WebRenderHardwareQualificationStatus(
|
||||
bool* aOutGuardedByQualifiedPref) {
|
||||
FeatureState& featureWebRenderQualified =
|
||||
gfxConfig::GetFeature(Feature::WEBRENDER_QUALIFIED);
|
||||
featureWebRenderQualified.EnableByDefault();
|
||||
MOZ_ASSERT(aOutGuardedByQualifiedPref && *aOutGuardedByQualifiedPref);
|
||||
|
||||
if (Preferences::HasUserValue(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE)) {
|
||||
if (!Preferences::GetBool(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE)) {
|
||||
featureWebRenderQualified.Disable(
|
||||
FeatureStatus::BlockedOverride, "HW qualification pref override",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_WR_QUALIFICATION_OVERRIDE"));
|
||||
}
|
||||
return featureWebRenderQualified;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
nsCString failureId;
|
||||
int32_t status;
|
||||
if (NS_FAILED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBRENDER,
|
||||
failureId, &status))) {
|
||||
featureWebRenderQualified.Disable(
|
||||
FeatureStatus::BlockedNoGfxInfo, "gfxInfo is broken",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_WR_NO_GFX_INFO"));
|
||||
return featureWebRenderQualified;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case nsIGfxInfo::FEATURE_ALLOW_ALWAYS:
|
||||
#ifndef NIGHTLY_BUILD
|
||||
// We want to honour ALLOW_ALWAYS on beta and release, but on nightly,
|
||||
// we still want to perform experiments. A larger population is the most
|
||||
// useful, demote nightly to merely qualified.
|
||||
*aOutGuardedByQualifiedPref = false;
|
||||
break;
|
||||
#endif
|
||||
case nsIGfxInfo::FEATURE_ALLOW_QUALIFIED:
|
||||
*aOutGuardedByQualifiedPref = true;
|
||||
break;
|
||||
case nsIGfxInfo::FEATURE_DENIED:
|
||||
featureWebRenderQualified.Disable(FeatureStatus::Denied,
|
||||
"Not on allowlist", failureId);
|
||||
break;
|
||||
default:
|
||||
featureWebRenderQualified.Disable(FeatureStatus::Blacklisted,
|
||||
"No qualified hardware", failureId);
|
||||
break;
|
||||
case nsIGfxInfo::FEATURE_STATUS_OK:
|
||||
MOZ_ASSERT_UNREACHABLE("We should still be rolling out WebRender!");
|
||||
featureWebRenderQualified.Disable(FeatureStatus::Blocked,
|
||||
"Not controlled by rollout", failureId);
|
||||
break;
|
||||
}
|
||||
|
||||
#if !defined(NIGHTLY_BUILD) && defined(XP_WIN)
|
||||
// Disable WebRender if we don't have DirectComposition
|
||||
nsAutoString adapterVendorID;
|
||||
gfxInfo->GetAdapterVendorID(adapterVendorID);
|
||||
if (adapterVendorID == u"0x8086") {
|
||||
bool hasBattery = false;
|
||||
gfxInfo->GetHasBattery(&hasBattery);
|
||||
if (hasBattery && !gfxConfig::IsEnabled(Feature::WEBRENDER_COMPOSITOR)) {
|
||||
featureWebRenderQualified.Disable(
|
||||
FeatureStatus::Blocked, "Battery Intel requires os compositor",
|
||||
NS_LITERAL_CSTRING("INTEL_BATTERY_REQUIRES_DCOMP"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return featureWebRenderQualified;
|
||||
}
|
||||
|
||||
void gfxPlatform::InitWebRenderConfig() {
|
||||
bool prefEnabled = WebRenderPrefEnabled();
|
||||
bool envvarEnabled = WebRenderEnvvarEnabled();
|
||||
@ -2921,109 +2696,20 @@ void gfxPlatform::InitWebRenderConfig() {
|
||||
// The parent process runs through all the real decision-making code
|
||||
// later in this function. For other processes we still want to report
|
||||
// the state of the feature for crash reports.
|
||||
if (UseWebRender()) {
|
||||
if (gfxVars::UseWebRender()) {
|
||||
reporter.SetSuccessful();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize WebRender native compositor usage
|
||||
FeatureState& featureComp =
|
||||
gfxConfig::GetFeature(Feature::WEBRENDER_COMPOSITOR);
|
||||
featureComp.SetDefaultFromPref("gfx.webrender.compositor", true, false);
|
||||
|
||||
if (StaticPrefs::gfx_webrender_compositor_force_enabled_AtStartup()) {
|
||||
featureComp.UserForceEnable("Force enabled by pref");
|
||||
}
|
||||
|
||||
ApplyGfxInfoFeature(nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR, featureComp);
|
||||
// Update the gfxConfig feature states.
|
||||
gfxConfigManager manager;
|
||||
manager.Init();
|
||||
manager.ConfigureWebRender();
|
||||
|
||||
#ifdef XP_WIN
|
||||
// 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() &&
|
||||
HasScaledResolution()) {
|
||||
featureComp.Disable(
|
||||
FeatureStatus::Unavailable, "No hardware stretching support",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_HARDWARE_STRETCHING"));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool guardedByQualifiedPref = true;
|
||||
FeatureState& featureWebRenderQualified =
|
||||
WebRenderHardwareQualificationStatus(&guardedByQualifiedPref);
|
||||
FeatureState& featureWebRender = gfxConfig::GetFeature(Feature::WEBRENDER);
|
||||
|
||||
featureWebRender.DisableByDefault(
|
||||
FeatureStatus::OptIn, "WebRender is an opt-in feature",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_DEFAULT_OFF"));
|
||||
|
||||
const bool wrQualifiedAll = CalculateWrQualifiedPrefValue();
|
||||
|
||||
// envvar works everywhere; note that we need this for testing in CI.
|
||||
// Prior to bug 1523788, the `prefEnabled` check was only done on Nightly,
|
||||
// so as to prevent random users from easily enabling WebRender on
|
||||
// unqualified hardware in beta/release.
|
||||
if (envvarEnabled) {
|
||||
featureWebRender.UserEnable("Force enabled by envvar");
|
||||
} else if (prefEnabled) {
|
||||
featureWebRender.UserEnable("Force enabled by pref");
|
||||
} else if (featureWebRenderQualified.IsEnabled()) {
|
||||
// If the HW is qualified, we enable if either the HW has been qualified
|
||||
// on the release channel (i.e. it's no longer guarded by the qualified
|
||||
// pref), or if the qualified pref is enabled.
|
||||
if (!guardedByQualifiedPref) {
|
||||
featureWebRender.UserEnable("Qualified in release");
|
||||
} else if (wrQualifiedAll) {
|
||||
featureWebRender.UserEnable("Qualified enabled by pref");
|
||||
}
|
||||
}
|
||||
|
||||
// If the user set the pref to force-disable, let's do that. This will
|
||||
// override all the other enabling prefs (gfx.webrender.enabled,
|
||||
// gfx.webrender.all, and gfx.webrender.all.qualified).
|
||||
if (StaticPrefs::gfx_webrender_force_disabled_AtStartup() ||
|
||||
(WebRenderEnvvarDisabled() && !InMarionetteRolloutTest())) {
|
||||
featureWebRender.UserDisable(
|
||||
"User force-disabled WR",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_USER_FORCE_DISABLED"));
|
||||
}
|
||||
|
||||
// HW_COMPOSITING being disabled implies interfacing with the GPU might break
|
||||
if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) {
|
||||
featureWebRender.ForceDisable(
|
||||
FeatureStatus::UnavailableNoHwCompositing,
|
||||
"Hardware compositing is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBRENDER_NEED_HWCOMP"));
|
||||
}
|
||||
|
||||
if (InSafeMode()) {
|
||||
featureWebRender.ForceDisable(
|
||||
FeatureStatus::UnavailableInSafeMode, "Safe-mode is enabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_SAFE_MODE"));
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (StaticPrefs::gfx_webrender_force_angle_AtStartup()) {
|
||||
if (!gfxConfig::IsEnabled(Feature::D3D11_HW_ANGLE)) {
|
||||
featureWebRender.ForceDisable(
|
||||
FeatureStatus::UnavailableNoAngle, "ANGLE is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_ANGLE_DISABLED"));
|
||||
} else if (
|
||||
!gfxConfig::IsEnabled(Feature::GPU_PROCESS)
|
||||
# ifdef NIGHTLY_BUILD
|
||||
&& !StaticPrefs::
|
||||
gfx_webrender_enabled_no_gpu_process_with_angle_win_AtStartup()
|
||||
# endif
|
||||
) {
|
||||
// WebRender with ANGLE relies on the GPU process when on Windows
|
||||
featureWebRender.ForceDisable(
|
||||
FeatureStatus::UnavailableNoGpuProcess, "GPU Process is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_GPU_PROCESS_DISABLED"));
|
||||
} else {
|
||||
gfxVars::SetUseWebRenderANGLE(gfxConfig::IsEnabled(Feature::WEBRENDER));
|
||||
}
|
||||
if (gfxConfig::IsEnabled(Feature::WEBRENDER_ANGLE)) {
|
||||
gfxVars::SetUseWebRenderANGLE(gfxConfig::IsEnabled(Feature::WEBRENDER));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3066,41 +2752,17 @@ void gfxPlatform::InitWebRenderConfig() {
|
||||
|
||||
UpdateAllowSacrificingSubpixelAA();
|
||||
}
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
else {
|
||||
if (gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) {
|
||||
// Hardware compositing should be disabled by default if we aren't using
|
||||
// WebRender. We had to check if it is enabled at all, because it may
|
||||
// already have been forced disabled (e.g. safe mode, headless). It may
|
||||
// still be forced on by the user, and if so, this should have no effect.
|
||||
gfxConfig::Disable(Feature::HW_COMPOSITING, FeatureStatus::Blocked,
|
||||
"Acceleration blocked by platform");
|
||||
}
|
||||
|
||||
if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING) &&
|
||||
gfxConfig::IsEnabled(Feature::GPU_PROCESS) &&
|
||||
!StaticPrefs::layers_gpu_process_allow_software_AtStartup()) {
|
||||
// We have neither WebRender nor OpenGL, we don't allow the GPU process
|
||||
// for basic compositor, and it wasn't disabled already.
|
||||
gfxConfig::Disable(Feature::GPU_PROCESS, FeatureStatus::Unavailable,
|
||||
"Hardware compositing is unavailable.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (gfxConfig::IsEnabled(Feature::WEBRENDER_DCOMP_PRESENT)) {
|
||||
gfxVars::SetUseWebRenderDCompWin(true);
|
||||
}
|
||||
if (Preferences::GetBool("gfx.webrender.flip-sequential", false)) {
|
||||
// XXX relax win version to windows 8.
|
||||
if (IsWin10OrLater() && UseWebRender() && gfxVars::UseWebRenderANGLE()) {
|
||||
gfxVars::SetUseWebRenderFlipSequentialWin(true);
|
||||
}
|
||||
}
|
||||
if (Preferences::GetBool("gfx.webrender.dcomp-win.enabled", false)) {
|
||||
// XXX relax win version to windows 8.
|
||||
if (IsWin10OrLater() && UseWebRender() && gfxVars::UseWebRenderANGLE()) {
|
||||
gfxVars::SetUseWebRenderDCompWin(true);
|
||||
}
|
||||
}
|
||||
if (Preferences::GetBool("gfx.webrender.triple-buffering.enabled", false)) {
|
||||
if (gfxVars::UseWebRenderDCompWin() ||
|
||||
gfxVars::UseWebRenderFlipSequentialWin()) {
|
||||
@ -3109,21 +2771,7 @@ void gfxPlatform::InitWebRenderConfig() {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!StaticPrefs::gfx_webrender_picture_caching()) {
|
||||
featureComp.ForceDisable(
|
||||
FeatureStatus::Unavailable, "Picture caching is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_PICTURE_CACHING_DISABLED"));
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (!gfxVars::UseWebRenderDCompWin()) {
|
||||
featureComp.Disable(
|
||||
FeatureStatus::Unavailable, "No DirectComposition usage",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_DIRECTCOMPOSITION"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gfx::gfxConfig::IsEnabled(gfx::Feature::WEBRENDER_COMPOSITOR)) {
|
||||
if (gfxConfig::IsEnabled(Feature::WEBRENDER_COMPOSITOR)) {
|
||||
gfxVars::SetUseWebRenderCompositor(true);
|
||||
}
|
||||
|
||||
@ -3131,25 +2779,9 @@ void gfxPlatform::InitWebRenderConfig() {
|
||||
Telemetry::ScalarID::GFX_OS_COMPOSITOR,
|
||||
gfx::gfxConfig::IsEnabled(gfx::Feature::WEBRENDER_COMPOSITOR));
|
||||
|
||||
// Initialize WebRender partial present config.
|
||||
// Partial present is used only when WebRender compositor is not used.
|
||||
if (StaticPrefs::gfx_webrender_max_partial_present_rects_AtStartup() > 0) {
|
||||
if (UseWebRender()) {
|
||||
FeatureState& featurePartial =
|
||||
gfxConfig::GetFeature(Feature::WEBRENDER_PARTIAL);
|
||||
featurePartial.EnableByDefault();
|
||||
if (StaticPrefs::gfx_webrender_picture_caching()) {
|
||||
gfxVars::SetWebRenderMaxPartialPresentRects(
|
||||
StaticPrefs::gfx_webrender_max_partial_present_rects_AtStartup());
|
||||
// Call UserEnable() only for reporting to Decision Log.
|
||||
// If feature is enabled by default. It is not reported to Decision Log.
|
||||
featurePartial.UserEnable("Enabled");
|
||||
} else {
|
||||
featurePartial.ForceDisable(
|
||||
FeatureStatus::Unavailable, "Picture caching is disabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_PICTURE_CACHING_DISABLED"));
|
||||
}
|
||||
}
|
||||
if (gfxConfig::IsEnabled(Feature::WEBRENDER_PARTIAL)) {
|
||||
gfxVars::SetWebRenderMaxPartialPresentRects(
|
||||
StaticPrefs::gfx_webrender_max_partial_present_rects_AtStartup());
|
||||
}
|
||||
|
||||
// Set features that affect WR's RendererOptions
|
||||
|
@ -755,6 +755,8 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
|
||||
static bool WebRenderPrefEnabled();
|
||||
// you probably want to use gfxVars::UseWebRender() instead of this
|
||||
static bool WebRenderEnvvarEnabled();
|
||||
// you probably want to use gfxVars::UseWebRender() instead of this
|
||||
static bool WebRenderEnvvarDisabled();
|
||||
|
||||
void NotifyFrameStats(nsTArray<mozilla::layers::FrameStats>&& aFrameStats);
|
||||
|
||||
|
@ -67,6 +67,7 @@ EXPORTS += [
|
||||
EXPORTS.mozilla.gfx += [
|
||||
'D3D11Checks.h',
|
||||
'DeviceManagerDx.h',
|
||||
'DisplayConfigWindows.h',
|
||||
'PrintTarget.h',
|
||||
'PrintTargetThebes.h',
|
||||
'ThebesRLBox.h',
|
||||
|
Loading…
Reference in New Issue
Block a user