/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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 "mozilla/Function.h" #include 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, D3D9Video, GLContext, D3D11Video, // Add new entries above this line, update the name array in // DriverCrashGuard.cpp, and make sure to add an entry in // ContentParent.cpp. 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(); enum class Mode { // Normal operation. Normal, // Acting as a proxy between the parent and child process. Proxy }; typedef mozilla::function CrashGuardCallback; static void ForEachActiveCrashGuard(const CrashGuardCallback& aCallback); protected: virtual void Initialize(); virtual bool UpdateEnvironment() = 0; 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 GetGuardFile(); bool RecoverFromCrash(); void ActivateGuard(); void FlushPreferences(); void SetStatus(DriverInitStatus aStatus); private: CrashGuardType mType; Mode mMode; bool mInitialized; bool mGuardActivated; bool mCrashDetected; nsCOMPtr mGuardFile; protected: nsCString mStatusPref; nsCOMPtr 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; }; class D3D9VideoCrashGuard final : public DriverCrashGuard { public: explicit D3D9VideoCrashGuard(dom::ContentParent* aContentParent = nullptr); protected: bool UpdateEnvironment() override; void LogCrashRecovery() override; void LogFeatureDisabled() override; }; class D3D11VideoCrashGuard final : public DriverCrashGuard { public: explicit D3D11VideoCrashGuard(dom::ContentParent* aContentParent = nullptr); protected: bool UpdateEnvironment() override; void LogCrashRecovery() override; void LogFeatureDisabled() override; }; 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; }; } // namespace gfx } // namespace mozilla #endif // gfx_src_DriverCrashGuard_h__