Add another feature state for blacklisting and environment decisions. (bug 1254899 part 7, r=milan)

This commit is contained in:
David Anderson 2016-04-27 22:54:26 -07:00
Родитель 61b7fa9e83
Коммит c5ec073736
6 изменённых файлов: 111 добавлений и 25 удалений

Просмотреть файл

@ -80,7 +80,20 @@ gfxConfig::InitOrUpdate(Feature aFeature,
if (!state.IsInitialized()) {
return SetDefault(aFeature, aEnable, aDisableStatus, aDisableMessage);
}
return UpdateIfFailed(aFeature, aEnable, aDisableStatus, aDisableMessage);
return MaybeSetFailed(aFeature, aEnable, aDisableStatus, aDisableMessage);
}
/* static */ void
gfxConfig::SetFailed(Feature aFeature, FeatureStatus aStatus, const char* aMessage)
{
AssertStatusInitialized(aFeature);
// We should never bother setting a runtime status to "enabled," since it could
// override an explicit user decision to disable it.
MOZ_ASSERT(IsFeatureStatusFailure(aStatus));
FeatureState& state = sConfig.GetState(aFeature);
state.SetRuntime(aStatus, aMessage);
}
/* static */ void
@ -88,12 +101,12 @@ gfxConfig::Disable(Feature aFeature, FeatureStatus aStatus, const char* aMessage
{
AssertStatusInitialized(aFeature);
// We should never bother setting a runtime status to "enabled," since it would
// override an explicit user decision to disable it.
// We should never bother setting an environment status to "enabled," since
// it could override an explicit user decision to disable it.
MOZ_ASSERT(IsFeatureStatusFailure(aStatus));
FeatureState& state = sConfig.GetState(aFeature);
state.SetRuntime(aStatus, aMessage);
state.SetEnvironment(aStatus, aMessage);
}
/* static */ void

Просмотреть файл

@ -13,16 +13,26 @@
namespace mozilla {
namespace gfx {
// Manages the history and state of a graphics feature. The flow of a feature
// is:
// - A default value, set by all.js, gfxPrefs, or gfxPlatform.
// - A user value, set by an external value or user pref.
// - An environment value, determined by system/hardware factors or nsIGfxInfo.
// - A runtime value, determined by any failures encountered after enabling
// the feature.
//
// Each state change for a feature is recorded in this class.
class gfxConfig
{
public:
// Query whether a parameter is enabled, taking into account any user or
// runtime overrides. The algorithm works as follow:
//
// 1. If a runtime decision disabled the parameter, return false.
// 2. If a user decision enabled or disabled the parameter, return true or
// false accordingly.
// 3. Return whether or not the base value is enabled or disabled.
// 1. If a runtime decision disabled the feature, return false.
// 2. If the user force-enabled the feature, return true.
// 3. If the environment disabled the feature, return false.
// 4. If the user specified a decision, return it.
// 5. Return the base setting for the feature.
static bool IsEnabled(Feature aFeature);
// Query the history of a parameter. ForcedOnByUser returns whether or not
@ -32,7 +42,14 @@ public:
static bool IsForcedOnByUser(Feature aFeature);
static bool IsDisabledByDefault(Feature aFeature);
// Query the raw computed status value of a parameter.
// Query the raw computed status value of a parameter. This is computed
// similar to IsEnabled:
//
// 1. If a runtime failure was set, return it.
// 2. If the user force-enabled the feature, return ForceEnabled.
// 3. If an environment status was set, return it.
// 4. If a user status was set, return it.
// 5. Return the default status.
static FeatureStatus GetValue(Feature aFeature);
// Initialize the base value of a parameter. The return value is aEnable.
@ -41,24 +58,57 @@ public:
FeatureStatus aDisableStatus,
const char* aDisableMessage);
// Disable a parameter based on a runtime decision.
// Set a environment status that overrides both the default and user
// statuses; this should be used to disable features based on system
// or hardware problems that can be determined up-front. The only
// status that can override this decision is the user force-enabling
// the feature.
static void Disable(Feature aFeature,
FeatureStatus aStatus,
const char* aMessage);
// Convenience helper for Disable().
static bool UpdateIfFailed(Feature aFeature,
// Disable a parameter based on a runtime decision. This permanently
// disables the feature, since runtime decisions override all other
// decisions.
static void SetFailed(Feature aFeature,
FeatureStatus aStatus,
const char* aMessage);
// Force a feature to be disabled permanently. This is the same as
// SetFailed(), but the name may be clearer depending on the context.
static void ForceDisable(Feature aFeature,
FeatureStatus aStatus,
const char* aMessage)
{
SetFailed(aFeature, aStatus, aMessage);
}
// Convenience helpers for SetFailed().
static bool MaybeSetFailed(Feature aFeature,
bool aEnable,
FeatureStatus aDisableStatus,
const char* aDisableMessage)
{
if (!aEnable) {
Disable(aFeature, aDisableStatus, aDisableMessage);
SetFailed(aFeature, aDisableStatus, aDisableMessage);
return false;
}
return true;
}
// Convenience helper for SetFailed().
static bool MaybeSetFailed(Feature aFeature,
FeatureStatus aStatus,
const char* aDisableMessage)
{
return MaybeSetFailed(
aFeature,
(aStatus != FeatureStatus::Available &&
aStatus != FeatureStatus::ForceEnabled),
aStatus,
aDisableMessage);
}
// Same as SetDefault, except if the feature already has a default value
// set, the new value will be set as a runtime value. This is useful for
// when the base value can change (for example, via an update from the

Просмотреть файл

@ -15,6 +15,12 @@ FeatureState::GetValue() const
if (mRuntime.mStatus != FeatureStatus::Unused) {
return mRuntime.mStatus;
}
if (mUser.mStatus == FeatureStatus::ForceEnabled) {
return FeatureStatus::ForceEnabled;
}
if (mEnvironment.mStatus != FeatureStatus::Unused) {
return mEnvironment.mStatus;
}
if (mUser.mStatus != FeatureStatus::Unused) {
return mUser.mStatus;
}
@ -55,12 +61,23 @@ FeatureState::DisableByDefault(FeatureStatus aStatus, const char* aMessage)
void
FeatureState::SetUser(FeatureStatus aStatus, const char* aMessage)
{
// Default decision must have been made, but not runtime or environment.
MOZ_ASSERT(mDefault.mStatus != FeatureStatus::Unused);
MOZ_ASSERT(mEnvironment.mStatus == FeatureStatus::Unused);
MOZ_ASSERT(mRuntime.mStatus == FeatureStatus::Unused);
mUser.Set(aStatus, aMessage);
}
void
FeatureState::SetEnvironment(FeatureStatus aStatus, const char* aMessage)
{
// Default decision must have been made, but not runtime.
MOZ_ASSERT(mDefault.mStatus != FeatureStatus::Unused);
MOZ_ASSERT(mRuntime.mStatus == FeatureStatus::Unused);
mUser.Set(aStatus, aMessage);
mEnvironment.Set(aStatus, aMessage);
}
void

Просмотреть файл

@ -33,6 +33,7 @@ class FeatureState
void EnableByDefault();
void DisableByDefault(FeatureStatus aStatus, const char* aMessage);
void SetUser(FeatureStatus aStatus, const char* aMessage);
void SetEnvironment(FeatureStatus aStatus, const char* aMessage);
void SetRuntime(FeatureStatus aStatus, const char* aMessage);
bool IsForcedOnByUser() const;
bool DisabledByDefault() const;
@ -52,14 +53,18 @@ class FeatureState
void Set(FeatureStatus aStatus, const char* aMessage = nullptr);
};
// The default state is the state we decide on startup, based on default
// the system, environment, and default preferences.
// The default state is the state we decide on startup, based on the operating
// system or a base preference.
//
// The user state factors in any changes to preferences that the user made.
//
// The environment state factors in any additional decisions made, such as
// availability or blacklisting.
//
// The runtime state factors in any problems discovered at runtime.
Instance mDefault;
Instance mUser;
Instance mEnvironment;
Instance mRuntime;
};

Просмотреть файл

@ -2159,12 +2159,13 @@ gfxPlatform::InitCompositorAccelerationPrefs()
gfxConfig::UserForceEnable(Feature::HW_COMPOSITING, "Force-enabled by pref");
}
// Safe mode trumps everything, so we update it as a runtime status.
gfxConfig::UpdateIfFailed(
// Safe mode trumps everything.
if (InSafeMode()) {
gfxConfig::ForceDisable(
Feature::HW_COMPOSITING,
!InSafeMode(),
FeatureStatus::Blocked,
"Acceleration blocked by safe-mode");
}
}
bool

Просмотреть файл

@ -2267,7 +2267,7 @@ gfxWindowsPlatform::InitializeDevices()
// If we previously crashed initializing devices, bail out now.
D3D11LayersCrashGuard detectCrashes;
if (detectCrashes.Crashed()) {
gfxConfig::Disable(Feature::HW_COMPOSITING,
gfxConfig::SetFailed(Feature::HW_COMPOSITING,
FeatureStatus::CrashedOnStartup,
"Crashed during startup in a previous session");
return;