author | Benoit Girard <b56girard@gmail.com> |
Fri, 03 Jun 2016 14:54:56 -0400 | |
changeset 300507 | f382e0ae3c2bd83bd5f89eaa4b71238bf500e393 |
parent 300506 | 0fe8a8bde7f03cf80825a434f4a3fc2c58d69a84 |
child 300508 | eb3f64c79e83a413c724d785cf7c1739bf0ad04c |
push id | 30313 |
push user | cbook@mozilla.com |
push date | Mon, 06 Jun 2016 09:56:25 +0000 |
treeherder | mozilla-central@0a3b6e2df656 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dvander |
bugs | 1274046 |
milestone | 49.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/config/gfxConfig.cpp +++ b/gfx/config/gfxConfig.cpp @@ -1,158 +1,162 @@ /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* vim: set sts=2 ts=8 sw=2 tw=99 et: */ /* 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 "gfxConfig.h" +#include "mozilla/UniquePtr.h" #include "plstr.h" namespace mozilla { namespace gfx { -static gfxConfig sConfig; +static UniquePtr<gfxConfig> sConfig; /* static */ FeatureState& gfxConfig::GetFeature(Feature aFeature) { - return sConfig.GetState(aFeature); + return sConfig->GetState(aFeature); } /* static */ bool gfxConfig::IsEnabled(Feature aFeature) { - const FeatureState& state = sConfig.GetState(aFeature); + const FeatureState& state = sConfig->GetState(aFeature); return state.IsEnabled(); } /* static */ bool gfxConfig::IsDisabledByDefault(Feature aFeature) { - const FeatureState& state = sConfig.GetState(aFeature); + const FeatureState& state = sConfig->GetState(aFeature); return state.DisabledByDefault(); } /* static */ bool gfxConfig::IsForcedOnByUser(Feature aFeature) { - const FeatureState& state = sConfig.GetState(aFeature); + const FeatureState& state = sConfig->GetState(aFeature); return state.IsForcedOnByUser(); } /* static */ FeatureStatus gfxConfig::GetValue(Feature aFeature) { - const FeatureState& state = sConfig.GetState(aFeature); + const FeatureState& state = sConfig->GetState(aFeature); return state.GetValue(); } /* static */ bool gfxConfig::SetDefault(Feature aFeature, bool aEnable, FeatureStatus aDisableStatus, const char* aDisableMessage) { - FeatureState& state = sConfig.GetState(aFeature); + FeatureState& state = sConfig->GetState(aFeature); return state.SetDefault(aEnable, aDisableStatus, aDisableMessage); } /* static */ void gfxConfig::DisableByDefault(Feature aFeature, FeatureStatus aDisableStatus, - const char* aDisableMessage) + const char* aDisableMessage, + const nsACString& aFailureId) { - FeatureState& state = sConfig.GetState(aFeature); - state.DisableByDefault(aDisableStatus, aDisableMessage); + FeatureState& state = sConfig->GetState(aFeature); + state.DisableByDefault(aDisableStatus, aDisableMessage, aFailureId); } /* static */ void gfxConfig::EnableByDefault(Feature aFeature) { - FeatureState& state = sConfig.GetState(aFeature); + FeatureState& state = sConfig->GetState(aFeature); state.EnableByDefault(); } /* static */ void gfxConfig::SetDefaultFromPref(Feature aFeature, const char* aPrefName, bool aIsEnablePref, bool aDefaultValue) { - FeatureState& state = sConfig.GetState(aFeature); + FeatureState& state = sConfig->GetState(aFeature); return state.SetDefaultFromPref(aPrefName, aIsEnablePref, aDefaultValue); } /* static */ bool gfxConfig::InitOrUpdate(Feature aFeature, bool aEnable, FeatureStatus aDisableStatus, const char* aDisableMessage) { - FeatureState& state = sConfig.GetState(aFeature); + FeatureState& state = sConfig->GetState(aFeature); return state.InitOrUpdate(aEnable, aDisableStatus, aDisableMessage); } /* static */ void -gfxConfig::SetFailed(Feature aFeature, FeatureStatus aStatus, const char* aMessage) +gfxConfig::SetFailed(Feature aFeature, FeatureStatus aStatus, const char* aMessage, + const nsACString& aFailureId) { - FeatureState& state = sConfig.GetState(aFeature); - state.SetFailed(aStatus, aMessage); + FeatureState& state = sConfig->GetState(aFeature); + state.SetFailed(aStatus, aMessage, aFailureId); } /* static */ void -gfxConfig::Disable(Feature aFeature, FeatureStatus aStatus, const char* aMessage) +gfxConfig::Disable(Feature aFeature, FeatureStatus aStatus, const char* aMessage, + const nsACString& aFailureId) { - FeatureState& state = sConfig.GetState(aFeature); - state.Disable(aStatus, aMessage); + FeatureState& state = sConfig->GetState(aFeature); + state.Disable(aStatus, aMessage, aFailureId); } /* static */ void gfxConfig::UserEnable(Feature aFeature, const char* aMessage) { - FeatureState& state = sConfig.GetState(aFeature); + FeatureState& state = sConfig->GetState(aFeature); state.UserEnable(aMessage); } /* static */ void gfxConfig::UserForceEnable(Feature aFeature, const char* aMessage) { - FeatureState& state = sConfig.GetState(aFeature); + FeatureState& state = sConfig->GetState(aFeature); state.UserForceEnable(aMessage); } /* static */ void -gfxConfig::UserDisable(Feature aFeature, const char* aMessage) +gfxConfig::UserDisable(Feature aFeature, const char* aMessage, const nsACString& aFailureId) { - FeatureState& state = sConfig.GetState(aFeature); - state.UserDisable(aMessage); + FeatureState& state = sConfig->GetState(aFeature); + state.UserDisable(aMessage, aFailureId); } /* static */ void gfxConfig::Reenable(Feature aFeature, Fallback aFallback) { - FeatureState& state = sConfig.GetState(aFeature); + FeatureState& state = sConfig->GetState(aFeature); MOZ_ASSERT(IsFeatureStatusFailure(state.GetValue())); const char* message = state.GetRuntimeMessage(); EnableFallback(aFallback, message); state.SetRuntime(FeatureStatus::Available, nullptr); } /* static */ bool gfxConfig::UseFallback(Fallback aFallback) { - return sConfig.UseFallbackImpl(aFallback); + return sConfig->UseFallbackImpl(aFallback); } /* static */ void gfxConfig::EnableFallback(Fallback aFallback, const char* aMessage) { // Ignore aMessage for now. - sConfig.EnableFallbackImpl(aFallback, aMessage); + sConfig->EnableFallbackImpl(aFallback, aMessage); } bool gfxConfig::UseFallbackImpl(Fallback aFallback) const { return !!(mFallbackBits & (uint64_t(1) << uint64_t(aFallback))); } @@ -202,22 +206,41 @@ static const char* sFallbackNames[] = { GFX_FALLBACK_MAP(FOR_EACH_FALLBACK) #undef FOR_EACH_FALLBACK nullptr }; /* static */ void gfxConfig::ForEachFallback(const FallbackIterCallback& aCallback) { - sConfig.ForEachFallbackImpl(aCallback); + sConfig->ForEachFallbackImpl(aCallback); } void gfxConfig::ForEachFallbackImpl(const FallbackIterCallback& aCallback) { for (size_t i = 0; i < mNumFallbackLogEntries; i++) { const FallbackLogEntry& entry = mFallbackLog[i]; aCallback(sFallbackNames[size_t(entry.mFallback)], entry.mMessage); } } +/* static */ const nsACString& +gfxConfig::GetFailureId(Feature aFeature) +{ + const FeatureState& state = sConfig->GetState(aFeature); + return state.GetFailureId(); +} + +/* static */ void +gfxConfig::Init() +{ + sConfig = mozilla::MakeUnique<gfxConfig>(); +} + +/* static */ void +gfxConfig::Shutdown() +{ + sConfig = nullptr; +} + } // namespace gfx } // namespace mozilla
--- a/gfx/config/gfxConfig.h +++ b/gfx/config/gfxConfig.h @@ -58,76 +58,82 @@ public: // Initialize the base value of a parameter. The return value is aEnable. static bool SetDefault(Feature aFeature, bool aEnable, FeatureStatus aDisableStatus, const char* aDisableMessage); static void DisableByDefault(Feature aFeature, FeatureStatus aDisableStatus, - const char* aDisableMessage); + const char* aDisableMessage, + const nsACString& aFailureId = EmptyCString()); static void EnableByDefault(Feature aFeature); // 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); + const char* aMessage, + const nsACString& aFailureId = EmptyCString()); // Given a preference name, infer the default value and whether or not the // user has changed it. |aIsEnablePref| specifies whether or not the pref // is intended to enable a feature (true), or disable it (false). static void SetDefaultFromPref(Feature aFeature, const char* aPrefName, bool aIsEnablePref, bool aDefaultValue); // 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); + const char* aMessage, + const nsACString& aFailureId = EmptyCString()); // 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) + const char* aMessage, + const nsACString& aFailureId = EmptyCString()) { - SetFailed(aFeature, aStatus, aMessage); + SetFailed(aFeature, aStatus, aMessage, aFailureId); } // Convenience helpers for SetFailed(). static bool MaybeSetFailed(Feature aFeature, bool aEnable, FeatureStatus aDisableStatus, - const char* aDisableMessage) + const char* aDisableMessage, + const nsACString& aFailureId = EmptyCString()) { if (!aEnable) { - SetFailed(aFeature, aDisableStatus, aDisableMessage); + SetFailed(aFeature, aDisableStatus, aDisableMessage, aFailureId); return false; } return true; } // Convenience helper for SetFailed(). static bool MaybeSetFailed(Feature aFeature, FeatureStatus aStatus, - const char* aDisableMessage) + const char* aDisableMessage, + const nsACString& aFailureId = EmptyCString()) { return MaybeSetFailed( aFeature, (aStatus != FeatureStatus::Available && aStatus != FeatureStatus::ForceEnabled), aStatus, - aDisableMessage); + aDisableMessage, aFailureId); } // Re-enables a feature that was previously disabled, by attaching it to a // fallback. The fallback inherits the message that was used for disabling // the feature. This can be used, for example, when D3D11 fails at runtime // but we acquire a second, successful device with WARP. static void Reenable(Feature aFeature, Fallback aFallback); @@ -139,17 +145,17 @@ public: bool aEnable, FeatureStatus aDisableStatus, const char* aDisableMessage); // Set a user status that overrides the base value (but not runtime value) // of a parameter. static void UserEnable(Feature aFeature, const char* aMessage); static void UserForceEnable(Feature aFeature, const char* aMessage); - static void UserDisable(Feature aFeature, const char* aMessage); + static void UserDisable(Feature aFeature, const char* aMessage, const nsACString& aFailureId = EmptyCString()); // Query whether a fallback has been toggled. static bool UseFallback(Fallback aFallback); // Enable a fallback. static void EnableFallback(Fallback aFallback, const char* aMessage); // Run a callback for each initialized FeatureState. @@ -158,16 +164,22 @@ public: FeatureState& aFeature)> FeatureIterCallback; static void ForEachFeature(const FeatureIterCallback& aCallback); // Run a callback for each enabled fallback. typedef mozilla::function<void(const char* aName, const char* aMsg)> FallbackIterCallback; static void ForEachFallback(const FallbackIterCallback& aCallback); + // Get the most descriptive failure id message for this feature. + static const nsACString& GetFailureId(Feature aFeature); + + static void Init(); + static void Shutdown(); + private: void ForEachFallbackImpl(const FallbackIterCallback& aCallback); private: FeatureState& GetState(Feature aFeature) { MOZ_ASSERT(size_t(aFeature) < kNumFeatures); return mFeatures[size_t(aFeature)]; }
--- a/gfx/config/gfxFeature.cpp +++ b/gfx/config/gfxFeature.cpp @@ -38,17 +38,18 @@ FeatureState::GetValue() const } bool FeatureState::SetDefault(bool aEnable, FeatureStatus aDisableStatus, const char* aDisableMessage) { if (!aEnable) { - DisableByDefault(aDisableStatus, aDisableMessage); + DisableByDefault(aDisableStatus, aDisableMessage, + NS_LITERAL_CSTRING("FEATURE_FAILURE_DISABLED")); return false; } EnableByDefault(); return true; } void FeatureState::SetDefaultFromPref(const char* aPrefName, @@ -62,30 +63,30 @@ FeatureState::SetDefaultFromPref(const c bool userValue = Preferences::GetBool(aPrefName, aDefaultValue); if (userValue == aIsEnablePref) { nsCString message("Enabled via "); message.AppendASCII(aPrefName); UserEnable(message.get()); } else { nsCString message("Disabled via "); message.AppendASCII(aPrefName); - UserDisable(message.get()); + UserDisable(message.get(), NS_LITERAL_CSTRING("FEATURE_FAILURE_PREF_OFF")); } } } bool FeatureState::InitOrUpdate(bool aEnable, FeatureStatus aDisableStatus, const char* aDisableMessage) { if (!IsInitialized()) { return SetDefault(aEnable, aDisableStatus, aDisableMessage); } - return MaybeSetFailed(aEnable, aDisableStatus, aDisableMessage); + return MaybeSetFailed(aEnable, aDisableStatus, aDisableMessage, nsCString()); } void FeatureState::UserEnable(const char* aMessage) { AssertInitialized(); SetUser(FeatureStatus::Available, aMessage); } @@ -93,60 +94,68 @@ FeatureState::UserEnable(const char* aMe void FeatureState::UserForceEnable(const char* aMessage) { AssertInitialized(); SetUser(FeatureStatus::ForceEnabled, aMessage); } void -FeatureState::UserDisable(const char* aMessage) +FeatureState::UserDisable(const char* aMessage, const nsACString& aFailureId) { AssertInitialized(); SetUser(FeatureStatus::Disabled, aMessage); + SetFailureId(aFailureId); } void -FeatureState::Disable(FeatureStatus aStatus, const char* aMessage) +FeatureState::Disable(FeatureStatus aStatus, const char* aMessage, + const nsACString& aFailureId) { AssertInitialized(); // 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)); SetEnvironment(aStatus, aMessage); + SetFailureId(aFailureId); } void -FeatureState::SetFailed(FeatureStatus aStatus, const char* aMessage) +FeatureState::SetFailed(FeatureStatus aStatus, const char* aMessage, + const nsACString& aFailureId) { AssertInitialized(); // 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)); SetRuntime(aStatus, aMessage); + SetFailureId(aFailureId); } bool -FeatureState::MaybeSetFailed(bool aEnable, FeatureStatus aStatus, const char* aMessage) +FeatureState::MaybeSetFailed(bool aEnable, FeatureStatus aStatus, const char* aMessage, + const nsACString& aFailureId) { if (!aEnable) { - SetFailed(aStatus, aMessage); + SetFailed(aStatus, aMessage, aFailureId); return false; } return true; } bool -FeatureState::MaybeSetFailed(FeatureStatus aStatus, const char* aMessage) +FeatureState::MaybeSetFailed(FeatureStatus aStatus, const char* aMessage, + const nsACString& aFailureId) { - return MaybeSetFailed(IsFeatureStatusSuccess(aStatus), aStatus, aMessage); + return MaybeSetFailed(IsFeatureStatusSuccess(aStatus), aStatus, aMessage, + aFailureId); } bool FeatureState::DisabledByDefault() const { AssertInitialized(); return mDefault.mStatus != FeatureStatus::Available; } @@ -165,24 +174,26 @@ FeatureState::EnableByDefault() MOZ_ASSERT(!mUser.IsInitialized()); MOZ_ASSERT(!mEnvironment.IsInitialized()); MOZ_ASSERT(!mRuntime.IsInitialized()); mDefault.Set(FeatureStatus::Available); } void -FeatureState::DisableByDefault(FeatureStatus aStatus, const char* aMessage) +FeatureState::DisableByDefault(FeatureStatus aStatus, const char* aMessage, + const nsACString& aFailureId) { // User/runtime decisions should not have been made yet. MOZ_ASSERT(!mUser.IsInitialized()); MOZ_ASSERT(!mEnvironment.IsInitialized()); MOZ_ASSERT(!mRuntime.IsInitialized()); mDefault.Set(aStatus, aMessage); + SetFailureId(aFailureId); } void FeatureState::SetUser(FeatureStatus aStatus, const char* aMessage) { // Default decision must have been made, but not runtime or environment. MOZ_ASSERT(mDefault.IsInitialized()); MOZ_ASSERT(!mEnvironment.IsInitialized()); @@ -229,16 +240,31 @@ FeatureState::ForEachStatusChange(const aCallback("env", mEnvironment.mStatus, mEnvironment.Message()); } if (mRuntime.IsInitialized()) { aCallback("runtime", mRuntime.mStatus, mRuntime.Message()); } } void +FeatureState::SetFailureId(const nsACString& aFailureId) +{ + if (mFailureId.IsEmpty()) { + mFailureId = aFailureId; + } +} + +const nsACString& +FeatureState::GetFailureId() const +{ + MOZ_ASSERT(!IsEnabled()); + return mFailureId; +} + +void FeatureState::Instance::Set(FeatureStatus aStatus, const char* aMessage /* = nullptr */) { mStatus = aStatus; if (aMessage) { PR_snprintf(mMessage, sizeof(mMessage), "%s", aMessage); } }
--- a/gfx/config/gfxFeature.h +++ b/gfx/config/gfxFeature.h @@ -5,16 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_gfx_config_gfxFeature_h #define mozilla_gfx_config_gfxFeature_h #include <stdint.h> #include "gfxTelemetry.h" #include "mozilla/Assertions.h" #include "mozilla/Function.h" +#include "nsString.h" namespace mozilla { namespace gfx { #define GFX_FEATURE_MAP(_) \ /* Name, Type, Description */ \ _(HW_COMPOSITING, Feature, "Compositing") \ _(D3D11_COMPOSITING, Feature, "Direct3D11 Compositing") \ @@ -34,58 +35,62 @@ class FeatureState { friend class gfxConfig; public: bool IsEnabled() const; FeatureStatus GetValue() const; void EnableByDefault(); - void DisableByDefault(FeatureStatus aStatus, const char* aMessage); + void DisableByDefault(FeatureStatus aStatus, const char* aMessage, const nsACString& aFailureId); bool SetDefault(bool aEnable, FeatureStatus aDisableStatus, const char* aDisableMessage); bool InitOrUpdate(bool aEnable, FeatureStatus aDisableStatus, const char* aMessage); void SetDefaultFromPref(const char* aPrefName, bool aIsEnablePref, bool aDefaultValue); void UserEnable(const char* aMessage); void UserForceEnable(const char* aMessage); - void UserDisable(const char* aMessage); - void Disable(FeatureStatus aStatus, const char* aMessage); - void ForceDisable(FeatureStatus aStatus, const char* aMessage) { - SetFailed(aStatus, aMessage); + void UserDisable(const char* aMessage, const nsACString& aFailureId); + void Disable(FeatureStatus aStatus, const char* aMessage, const nsACString& aFailureId); + void ForceDisable(FeatureStatus aStatus, const char* aMessage, const nsACString& aFailureId) { + SetFailed(aStatus, aMessage, aFailureId); } - void SetFailed(FeatureStatus aStatus, const char* aMessage); - bool MaybeSetFailed(bool aEnable, FeatureStatus aStatus, const char* aMessage); - bool MaybeSetFailed(FeatureStatus aStatus, const char* aMessage); + void SetFailed(FeatureStatus aStatus, const char* aMessage, const nsACString& aFailureId); + bool MaybeSetFailed(bool aEnable, FeatureStatus aStatus, const char* aMessage, const nsACString& aFailureId); + bool MaybeSetFailed(FeatureStatus aStatus, const char* aMessage, const nsACString& aFailureId); // aType is "base", "user", "env", or "runtime". // aMessage may be null. typedef mozilla::function<void(const char* aType, FeatureStatus aStatus, const char* aMessage)> StatusIterCallback; void ForEachStatusChange(const StatusIterCallback& aCallback) const; + const nsACString& GetFailureId() const; + private: 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; const char* GetRuntimeMessage() const; bool IsInitialized() const { return mDefault.IsInitialized(); } void AssertInitialized() const { MOZ_ASSERT(IsInitialized()); } private: + void SetFailureId(const nsACString& aFailureId); + struct Instance { char mMessage[64]; FeatureStatus mStatus; void Set(FeatureStatus aStatus, const char* aMessage = nullptr); bool IsInitialized() const { return mStatus != FeatureStatus::Unused; } @@ -106,14 +111,18 @@ class FeatureState // 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; + + // Store the first reported failureId for now but we might want to track this + // by instance later if we need a specific breakdown. + nsCString mFailureId; }; } // namespace gfx } // namespace mozilla #endif // mozilla_gfx_config_gfxFeature_h
--- a/gfx/gl/GLLibraryEGL.cpp +++ b/gfx/gl/GLLibraryEGL.cpp @@ -171,17 +171,18 @@ GetAndInitDisplay(GLLibraryEGL& egl, voi static EGLDisplay GetAndInitDisplayForAccelANGLE(GLLibraryEGL& egl) { EGLDisplay ret = 0; FeatureState& d3d11ANGLE = gfxConfig::GetFeature(Feature::D3D11_HW_ANGLE); if (!gfxPrefs::WebGLANGLETryD3D11()) - d3d11ANGLE.UserDisable("User disabled D3D11 ANGLE by pref"); + d3d11ANGLE.UserDisable("User disabled D3D11 ANGLE by pref", + NS_LITERAL_CSTRING("FAILURE_ID_ANGLE_PREF")); if (gfxPrefs::WebGLANGLEForceD3D11()) d3d11ANGLE.UserForceEnable("User force-enabled D3D11 ANGLE on disabled hardware"); if (gfxConfig::IsForcedOnByUser(Feature::D3D11_HW_ANGLE)) return GetAndInitDisplay(egl, LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE); if (d3d11ANGLE.IsEnabled()) {
--- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -587,16 +587,18 @@ gfxPlatform::Init() NS_RUNTIMEABORT("Already started???"); } gEverInitialized = true; // Initialize the preferences by creating the singleton. gfxPrefs::GetSingleton(); MediaPrefs::GetSingleton(); + gfxConfig::Init(); + GPUProcessManager::Initialize(); auto fwd = new CrashStatsLogForwarder("GraphicsCriticalError"); fwd->SetCircularBufferSize(gfxPrefs::GfxLoggingCrashLength()); // Drop a note in the crash report if we end up forcing an option that could // destabilize things. New items should be appended at the end (of an existing // or in a new section), so that we don't have to know the version to interpret @@ -853,16 +855,18 @@ gfxPlatform::Shutdown() gfx::Factory::ShutDown(); delete gGfxPlatformPrefsLock; gfxPrefs::DestroySingleton(); gfxFont::DestroySingletons(); + gfxConfig::Shutdown(); + delete gPlatform; gPlatform = nullptr; } /* static */ void gfxPlatform::InitLayersIPC() { if (sLayersIPCIsUp) { @@ -2120,34 +2124,37 @@ gfxPlatform::InitCompositorAccelerationP FeatureState& feature = gfxConfig::GetFeature(Feature::HW_COMPOSITING); // Base value - does the platform allow acceleration? if (feature.SetDefault(AccelerateLayersByDefault(), FeatureStatus::Blocked, "Acceleration blocked by platform")) { if (gfxPrefs::LayersAccelerationDisabledDoNotUseDirectly()) { - feature.UserDisable("Disabled by pref"); + feature.UserDisable("Disabled by pref", + NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_PREF")); } else if (acceleratedEnv && *acceleratedEnv == '0') { - feature.UserDisable("Disabled by envvar"); + feature.UserDisable("Disabled by envvar", + NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_ENV")); } } else { if (acceleratedEnv && *acceleratedEnv == '1') { feature.UserEnable("Enabled by envvar"); } } // This has specific meaning elsewhere, so we always record it. if (gfxPrefs::LayersAccelerationForceEnabledDoNotUseDirectly()) { feature.UserForceEnable("Force-enabled by pref"); } // Safe mode trumps everything. if (InSafeMode()) { - feature.ForceDisable(FeatureStatus::Blocked, "Acceleration blocked by safe-mode"); + feature.ForceDisable(FeatureStatus::Blocked, "Acceleration blocked by safe-mode", + NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_SAFEMODE")); } } bool gfxPlatform::CanUseHardwareVideoDecoding() { // this function is called from the compositor thread, so it is not // safe to init the prefs etc. from here.
--- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -555,17 +555,18 @@ gfxWindowsPlatform::CreatePlatformFontLi pfl = new gfxDWriteFontList(); if (NS_SUCCEEDED(pfl->InitFontList())) { return pfl; } // DWrite font initialization failed! Don't know why this would happen, // but apparently it can - see bug 594865. // So we're going to fall back to GDI fonts & rendering. gfxPlatformFontList::Shutdown(); - DisableD2D(FeatureStatus::Failed, "Failed to initialize fonts"); + DisableD2D(FeatureStatus::Failed, "Failed to initialize fonts", + NS_LITERAL_CSTRING("FEATURE_FAILURE_FONT_FAIL")); } pfl = new gfxGDIFontList(); if (NS_SUCCEEDED(pfl->InitFontList())) { return pfl; } @@ -575,19 +576,20 @@ gfxWindowsPlatform::CreatePlatformFontLi // This function will permanently disable D2D for the session. It's intended to // be used when, after initially chosing to use Direct2D, we encounter a // scenario we can't support. // // This is called during gfxPlatform::Init() so at this point there should be no // DrawTargetD2D/1 instances. void -gfxWindowsPlatform::DisableD2D(FeatureStatus aStatus, const char* aMessage) +gfxWindowsPlatform::DisableD2D(FeatureStatus aStatus, const char* aMessage, + const nsACString& aFailureId) { - gfxConfig::SetFailed(Feature::DIRECT2D, aStatus, aMessage); + gfxConfig::SetFailed(Feature::DIRECT2D, aStatus, aMessage, aFailureId); Factory::SetDirect3D11Device(nullptr); UpdateBackendPrefs(); } already_AddRefed<gfxASurface> gfxWindowsPlatform::CreateOffscreenSurface(const IntSize& aSize, gfxImageFormat aFormat) { @@ -1888,30 +1890,29 @@ bool DoesD3D11TextureSharingWork(ID3D11D } bool DoesD3D11AlphaTextureSharingWork(ID3D11Device *device) { return DoesD3D11TextureSharingWorkInternal(device, DXGI_FORMAT_R8_UNORM, D3D11_BIND_SHADER_RESOURCE); } static inline bool -IsGfxInfoStatusOkay(int32_t aFeature, nsCString* aOutMessage) +IsGfxInfoStatusOkay(int32_t aFeature, nsCString* aOutMessage, nsCString& aFailureId) { nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo(); if (!gfxInfo) { return true; } int32_t status; - nsCString failureId; - if (SUCCEEDED(gfxInfo->GetFeatureStatus(aFeature, failureId, &status)) && + if (SUCCEEDED(gfxInfo->GetFeatureStatus(aFeature, aFailureId, &status)) && status != nsIGfxInfo::FEATURE_STATUS_OK) { aOutMessage->AssignLiteral("#BLOCKLIST_"); - aOutMessage->AppendASCII(failureId.get()); + aOutMessage->AppendASCII(aFailureId.get()); return false; } return true; } static inline bool IsWARPStable() @@ -1924,25 +1925,28 @@ IsWARPStable() } static void InitializeANGLEConfig() { FeatureState& d3d11ANGLE = gfxConfig::GetFeature(Feature::D3D11_HW_ANGLE); if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) { - d3d11ANGLE.DisableByDefault(FeatureStatus::Unavailable, "D3D11 compositing is disabled"); + d3d11ANGLE.DisableByDefault(FeatureStatus::Unavailable, "D3D11 compositing is disabled", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DISABLED")); return; } d3d11ANGLE.EnableByDefault(); nsCString message; - if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_11_ANGLE, &message)) { - d3d11ANGLE.Disable(FeatureStatus::Blacklisted, message.get()); + nsCString failureId; + if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_11_ANGLE, &message, + failureId)) { + d3d11ANGLE.Disable(FeatureStatus::Blacklisted, message.get(), failureId); } } void gfxWindowsPlatform::InitializeConfig() { if (!XRE_IsParentProcess()) { @@ -1959,17 +1963,18 @@ gfxWindowsPlatform::InitializeConfig() void gfxWindowsPlatform::InitializeD3D9Config() { MOZ_ASSERT(XRE_IsParentProcess()); FeatureState& d3d9 = gfxConfig::GetFeature(Feature::D3D9_COMPOSITING); if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) { - d3d9.DisableByDefault(FeatureStatus::Unavailable, "Hardware compositing is disabled"); + d3d9.DisableByDefault(FeatureStatus::Unavailable, "Hardware compositing is disabled", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D9_NEED_HWCOMP")); return; } if (!IsVistaOrLater()) { d3d9.EnableByDefault(); } else { d3d9.SetDefaultFromPref( gfxPrefs::GetLayersAllowD3D9FallbackPrefName(), @@ -1977,53 +1982,59 @@ gfxWindowsPlatform::InitializeD3D9Config gfxPrefs::GetLayersAllowD3D9FallbackPrefDefault()); if (!d3d9.IsEnabled() && gfxPrefs::LayersPreferD3D9()) { d3d9.UserEnable("Direct3D9 enabled via layers.prefer-d3d9"); } } nsCString message; - if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, &message)) { - d3d9.Disable(FeatureStatus::Blacklisted, message.get()); + nsCString failureId; + if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, &message, + failureId)) { + d3d9.Disable(FeatureStatus::Blacklisted, message.get(), failureId); } if (gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING)) { d3d9.UserForceEnable("Hardware compositing is force-enabled"); } } void gfxWindowsPlatform::InitializeD3D11Config() { MOZ_ASSERT(XRE_IsParentProcess()); FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING); if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) { - d3d11.DisableByDefault(FeatureStatus::Unavailable, "Hardware compositing is disabled"); + d3d11.DisableByDefault(FeatureStatus::Unavailable, "Hardware compositing is disabled", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_NEED_HWCOMP")); return; } d3d11.EnableByDefault(); // If the user prefers D3D9, act as though they disabled D3D11. if (gfxPrefs::LayersPreferD3D9()) { - d3d11.UserDisable("Disabled due to user preference for Direct3D 9"); + d3d11.UserDisable("Disabled due to user preference for Direct3D 9", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_PREF")); return; } nsCString message; - if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS, &message)) { + nsCString failureId; + if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS, &message, failureId)) { if (IsWARPStable() && !gfxPrefs::LayersD3D11DisableWARP()) { // We do not expect hardware D3D11 to work, so we'll try WARP. gfxConfig::EnableFallback(Fallback::USE_D3D11_WARP_COMPOSITOR, message.get()); } else { // There is little to no chance of D3D11 working, so just disable it. - d3d11.Disable(FeatureStatus::Blacklisted, message.get()); + d3d11.Disable(FeatureStatus::Blacklisted, message.get(), + failureId); } } // Check if the user really, really wants WARP. if (gfxPrefs::LayersD3D11ForceWARP()) { // Force D3D11 on even if we disabled it. d3d11.UserForceEnable("User force-enabled WARP on disabled hardware"); @@ -2086,35 +2097,39 @@ gfxWindowsPlatform::AttemptD3D11DeviceCr return true; } void gfxWindowsPlatform::AttemptD3D11DeviceCreation(FeatureState& d3d11) { RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter(); if (!adapter) { - d3d11.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a DXGI adapter"); + d3d11.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a DXGI adapter", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DXGI")); return; } HRESULT hr; RefPtr<ID3D11Device> device; if (!AttemptD3D11DeviceCreationHelper(adapter, device, hr)) { gfxCriticalError() << "Crash during D3D11 device creation"; - d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed trying to acquire a D3D11 device"); + d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed trying to acquire a D3D11 device", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE1")); return; } if (FAILED(hr) || !device) { gfxCriticalError() << "D3D11 device creation failed: " << hexa(hr); - d3d11.SetFailed(FeatureStatus::Failed, "Failed to acquire a D3D11 device"); + d3d11.SetFailed(FeatureStatus::Failed, "Failed to acquire a D3D11 device", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE2")); return; } if (!DoesD3D11DeviceWork()) { - d3d11.SetFailed(FeatureStatus::Broken, "Direct3D11 device was determined to be broken"); + d3d11.SetFailed(FeatureStatus::Broken, "Direct3D11 device was determined to be broken", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_BROKEN")); return; } { MutexAutoLock lock(mDeviceLock); mD3D11Device = device; } @@ -2166,24 +2181,26 @@ gfxWindowsPlatform::AttemptWARPDeviceCre { ScopedGfxFeatureReporter reporterWARP("D3D11-WARP", gfxPrefs::LayersD3D11ForceWARP()); FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING); HRESULT hr; RefPtr<ID3D11Device> device; if (!AttemptWARPDeviceCreationHelper(reporterWARP, device, hr)) { gfxCriticalError() << "Exception occurred initializing WARP D3D11 device!"; - d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed creating a D3D11 WARP device"); + d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed creating a D3D11 WARP device", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE")); return; } if (FAILED(hr) || !device) { // This should always succeed... in theory. gfxCriticalError() << "Failed to initialize WARP D3D11 device! " << hexa(hr); - d3d11.SetFailed(FeatureStatus::Failed, "Failed to create a D3D11 WARP device"); + d3d11.SetFailed(FeatureStatus::Failed, "Failed to create a D3D11 WARP device", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE2")); return; } { MutexAutoLock lock(mDeviceLock); mD3D11Device = device; } @@ -2420,23 +2437,25 @@ gfxWindowsPlatform::InitializeD3D11() } // Check if D3D11 is available on this system. nsModuleHandle d3d11Module(LoadLibrarySystem32(L"d3d11.dll")); sD3D11CreateDeviceFn = (decltype(D3D11CreateDevice)*)GetProcAddress(d3d11Module, "D3D11CreateDevice"); if (!sD3D11CreateDeviceFn) { // We should just be on Windows Vista or XP in this case. - d3d11.SetFailed(FeatureStatus::Unavailable, "Direct3D11 not available on this computer"); + d3d11.SetFailed(FeatureStatus::Unavailable, "Direct3D11 not available on this computer", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_LIB")); return; } // Check if a failure was injected for testing. if (gfxPrefs::DeviceFailForTesting()) { - d3d11.SetFailed(FeatureStatus::Failed, "Direct3D11 device failure simulated by preference"); + d3d11.SetFailed(FeatureStatus::Failed, "Direct3D11 device failure simulated by preference", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_SIM")); return; } if (XRE_IsParentProcess()) { if (!gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) { AttemptD3D11DeviceCreation(d3d11); if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) { return; @@ -2495,17 +2514,18 @@ gfxWindowsPlatform::InitializeD3D11() d3d11Module.disown(); } void gfxWindowsPlatform::DisableD3D11AfterCrash() { gfxConfig::Disable(Feature::D3D11_COMPOSITING, FeatureStatus::CrashedInHandler, - "Crashed while acquiring a Direct3D11 device"); + "Crashed while acquiring a Direct3D11 device", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_CRASH")); ResetD3D11Devices(); } void gfxWindowsPlatform::ResetD3D11Devices() { MutexAutoLock lock(mDeviceLock); @@ -2516,32 +2536,35 @@ gfxWindowsPlatform::ResetD3D11Devices() } void gfxWindowsPlatform::InitializeD2DConfig() { FeatureState& d2d1 = gfxConfig::GetFeature(Feature::DIRECT2D); if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) { - d2d1.DisableByDefault(FeatureStatus::Unavailable, "Direct2D requires Direct3D 11 compositing"); + d2d1.DisableByDefault(FeatureStatus::Unavailable, "Direct2D requires Direct3D 11 compositing", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_D3D11_COMP")); return; } if (!IsVistaOrLater()) { - d2d1.DisableByDefault(FeatureStatus::Unavailable, "Direct2D is not available on Windows XP"); + d2d1.DisableByDefault(FeatureStatus::Unavailable, "Direct2D is not available on Windows XP", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_XP")); return; } d2d1.SetDefaultFromPref( gfxPrefs::GetDirect2DDisabledPrefName(), false, gfxPrefs::GetDirect2DDisabledPrefDefault()); nsCString message; - if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT2D, &message)) { - d2d1.Disable(FeatureStatus::Blacklisted, message.get()); + nsCString failureId; + if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT2D, &message, failureId)) { + d2d1.Disable(FeatureStatus::Blacklisted, message.get(), failureId); } if (!d2d1.IsEnabled() && gfxPrefs::Direct2DForceEnabled()) { d2d1.UserForceEnable("Force-enabled via user-preference"); } } void @@ -2549,48 +2572,54 @@ gfxWindowsPlatform::InitializeD2D() { ScopedGfxFeatureReporter d2d1_1("D2D1.1"); FeatureState& d2d1 = gfxConfig::GetFeature(Feature::DIRECT2D); // We don't know this value ahead of time, but the user can force-override // it, so we use Disable instead of SetFailed. if (mIsWARP) { - d2d1.Disable(FeatureStatus::Blocked, "Direct2D is not compatible with Direct3D11 WARP"); + d2d1.Disable(FeatureStatus::Blocked, "Direct2D is not compatible with Direct3D11 WARP", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_WARP_BLOCK")); } // If we pass all the initial checks, we can proceed to runtime decisions. if (!d2d1.IsEnabled()) { return; } if (!Factory::SupportsD2D1()) { - d2d1.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a Direct2D 1.1 factory"); + d2d1.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a Direct2D 1.1 factory", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_FACTORY")); return; } if (!mD3D11ContentDevice) { - d2d1.SetFailed(FeatureStatus::Failed, "Failed to acquire a Direct3D 11 content device"); + d2d1.SetFailed(FeatureStatus::Failed, "Failed to acquire a Direct3D 11 content device", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_DEVICE")); return; } if (!mCompositorD3D11TextureSharingWorks) { - d2d1.SetFailed(FeatureStatus::Failed, "Direct3D11 device does not support texture sharing"); + d2d1.SetFailed(FeatureStatus::Failed, "Direct3D11 device does not support texture sharing", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_TXT_SHARING")); return; } // Using Direct2D depends on DWrite support. if (!mDWriteFactory && !InitDWriteSupport()) { - d2d1.SetFailed(FeatureStatus::Failed, "Failed to initialize DirectWrite support"); + d2d1.SetFailed(FeatureStatus::Failed, "Failed to initialize DirectWrite support", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_DWRITE")); return; } // Verify that Direct2D device creation succeeded. if (!Factory::SetDirect3D11Device(mD3D11ContentDevice)) { - d2d1.SetFailed(FeatureStatus::Failed, "Failed to create a Direct2D device"); + d2d1.SetFailed(FeatureStatus::Failed, "Failed to create a Direct2D device", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_CREATE_FAILED")); return; } MOZ_ASSERT(d2d1.IsEnabled()); d2d1_1.SetSuccessful(); } bool
--- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -278,17 +278,18 @@ private: void Init(); void InitAcceleration() override; void InitializeDevices(); void InitializeD3D11(); void InitializeD2D(); bool InitDWriteSupport(); - void DisableD2D(mozilla::gfx::FeatureStatus aStatus, const char* aMessage); + void DisableD2D(mozilla::gfx::FeatureStatus aStatus, const char* aMessage, + const nsACString& aFailureId); void InitializeConfig(); void InitializeD3D9Config(); void InitializeD3D11Config(); void InitializeD2DConfig(); void AttemptD3D11DeviceCreation(mozilla::gfx::FeatureState& d3d11); bool AttemptD3D11DeviceCreationHelper(