diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/src/DriverCrashGuard.h | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/gfx/src/DriverCrashGuard.h b/gfx/src/DriverCrashGuard.h new file mode 100644 index 0000000000..1cb8d78d56 --- /dev/null +++ b/gfx/src/DriverCrashGuard.h @@ -0,0 +1,172 @@ +/* -*- 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 gfx_src_DriverCrashGuard_h__ +#define gfx_src_DriverCrashGuard_h__ + +#include "nsCOMPtr.h" +#include "nsIGfxInfo.h" +#include "nsIFile.h" +#include "nsString.h" +#include <functional> +#include <string> + +namespace mozilla { + +namespace dom { +class ContentParent; +} // namespace dom + +namespace gfx { + +enum class DriverInitStatus { + // Drivers have not been initialized yet. + Unknown, + + // We're attempting to initialize drivers. + Attempting, + + // Drivers were successfully initialized last run. + Okay, + + // We crashed during driver initialization, and have restarted. + Crashed +}; + +enum class CrashGuardType : uint32_t { + D3D11Layers, + GLContext, + WMFVPXVideo, + // Add new entries above this line, update the name array in + // DriverCrashGuard.cpp, make sure to add an entry in ContentParent.cpp, + // and add a fluent identifier in aboutSupport.ftl. + + NUM_TYPES +}; + +// DriverCrashGuard is used to detect crashes at graphics driver callsites. +// +// If the graphics environment is unrecognized or has changed since the last +// session, the crash guard will activate and will detect any crashes within +// the scope of the guard object. +// +// If a callsite has a previously encountered crash, and the environment has +// not changed since the last session, then the guard will set a status flag +// indicating that the driver should not be used. +class DriverCrashGuard { + public: + DriverCrashGuard(CrashGuardType aType, dom::ContentParent* aContentParent); + virtual ~DriverCrashGuard(); + + bool Crashed(); + void NotifyCrashed(); + + // These are the values reported to Telemetry (GRAPHICS_DRIVER_STARTUP_TEST). + // Values should not change; add new values to the end. + enum class TelemetryState { + Okay = 0, + EnvironmentChanged = 1, + RecoveredFromCrash = 2, + FeatureDisabled = 3 + }; + + enum class Mode { + // Normal operation. + Normal, + + // Acting as a proxy between the parent and child process. + Proxy + }; + + typedef std::function<void(const char* aName, const char* aPrefName)> + CrashGuardCallback; + static void ForEachActiveCrashGuard(const CrashGuardCallback& aCallback); + + protected: + virtual void Initialize(); + // UpdateEnvironment needs to return true should we need to attempt the + // operation once again. + // It should return true once only so that in case of a crash, we won't + // needlessly attempt the operation over and over again leading to continual + // crashes. several times + virtual bool UpdateEnvironment() { + // We don't care about any extra preferences here. + return false; + } + virtual void LogCrashRecovery() = 0; + virtual void LogFeatureDisabled() = 0; + + // Helper functions. + bool FeatureEnabled(int aFeature, bool aDefault = true); + bool CheckAndUpdatePref(const char* aPrefName, + const nsAString& aCurrentValue); + bool CheckAndUpdateBoolPref(const char* aPrefName, bool aCurrentValue); + std::string GetFullPrefName(const char* aPref); + + private: + // Either process. + void InitializeIfNeeded(); + bool CheckOrRefreshEnvironment(); + bool UpdateBaseEnvironment(); + DriverInitStatus GetStatus() const; + + // Parent process only. + nsCOMPtr<nsIFile> GetGuardFile(); + bool RecoverFromCrash(); + void ActivateGuard(); + void FlushPreferences(); + void SetStatus(DriverInitStatus aStatus); + + private: + CrashGuardType mType; + Mode mMode; + bool mInitialized; + bool mGuardActivated; + bool mCrashDetected; + nsCOMPtr<nsIFile> mGuardFile; + + protected: + nsCString mStatusPref; + nsCOMPtr<nsIGfxInfo> mGfxInfo; +}; + +class D3D11LayersCrashGuard final : public DriverCrashGuard { + public: + explicit D3D11LayersCrashGuard(dom::ContentParent* aContentParent = nullptr); + + protected: + void Initialize() override; + bool UpdateEnvironment() override; + void LogCrashRecovery() override; + void LogFeatureDisabled() override; + + private: + void RecordTelemetry(TelemetryState aState); +}; + +class GLContextCrashGuard final : public DriverCrashGuard { + public: + explicit GLContextCrashGuard(dom::ContentParent* aContentParent = nullptr); + void Initialize() override; + + protected: + bool UpdateEnvironment() override; + void LogCrashRecovery() override; + void LogFeatureDisabled() override; +}; + +class WMFVPXVideoCrashGuard final : public DriverCrashGuard { + public: + explicit WMFVPXVideoCrashGuard(dom::ContentParent* aContentParent = nullptr); + + protected: + void LogCrashRecovery() override; + void LogFeatureDisabled() override; +}; + +} // namespace gfx +} // namespace mozilla + +#endif // gfx_src_DriverCrashGuard_h__ |