DriverCrashGuard.h (4854B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #ifndef gfx_src_DriverCrashGuard_h__ 7 #define gfx_src_DriverCrashGuard_h__ 8 9 #include "nsCOMPtr.h" 10 #include "nsIGfxInfo.h" 11 #include "nsIFile.h" 12 #include "nsString.h" 13 #include <functional> 14 #include <string> 15 16 namespace mozilla { 17 18 namespace dom { 19 class ContentParent; 20 } // namespace dom 21 22 namespace gfx { 23 24 enum class DriverInitStatus { 25 // Drivers have not been initialized yet. 26 Unknown, 27 28 // We're attempting to initialize drivers. 29 Attempting, 30 31 // Drivers were successfully initialized last run. 32 Okay, 33 34 // We crashed during driver initialization, and have restarted. 35 Crashed 36 }; 37 38 enum class CrashGuardType : uint32_t { 39 D3D11Layers, 40 GLContext, 41 WMFVPXVideo, 42 // Add new entries above this line, update the name array in 43 // DriverCrashGuard.cpp, make sure to add an entry in ContentParent.cpp, 44 // and add a fluent identifier in aboutSupport.ftl. 45 46 NUM_TYPES 47 }; 48 49 // DriverCrashGuard is used to detect crashes at graphics driver callsites. 50 // 51 // If the graphics environment is unrecognized or has changed since the last 52 // session, the crash guard will activate and will detect any crashes within 53 // the scope of the guard object. 54 // 55 // If a callsite has a previously encountered crash, and the environment has 56 // not changed since the last session, then the guard will set a status flag 57 // indicating that the driver should not be used. 58 class DriverCrashGuard { 59 public: 60 DriverCrashGuard(CrashGuardType aType, dom::ContentParent* aContentParent); 61 virtual ~DriverCrashGuard(); 62 63 bool Crashed(); 64 void NotifyCrashed(); 65 66 // These are the values reported to Telemetry (GRAPHICS_DRIVER_STARTUP_TEST). 67 // Values should not change; add new values to the end. 68 enum class TelemetryState { 69 Okay = 0, 70 EnvironmentChanged = 1, 71 RecoveredFromCrash = 2, 72 FeatureDisabled = 3 73 }; 74 75 enum class Mode { 76 // Normal operation. 77 Normal, 78 79 // Acting as a proxy between the parent and child process. 80 Proxy 81 }; 82 83 typedef std::function<void(const char* aName, const char* aPrefName)> 84 CrashGuardCallback; 85 static void ForEachActiveCrashGuard(const CrashGuardCallback& aCallback); 86 87 protected: 88 virtual void Initialize(); 89 // UpdateEnvironment needs to return true should we need to attempt the 90 // operation once again. 91 // It should return true once only so that in case of a crash, we won't 92 // needlessly attempt the operation over and over again leading to continual 93 // crashes. several times 94 virtual bool UpdateEnvironment() { 95 // We don't care about any extra preferences here. 96 return false; 97 } 98 virtual void LogCrashRecovery() = 0; 99 virtual void LogFeatureDisabled() = 0; 100 101 // Helper functions. 102 bool FeatureEnabled(int aFeature, bool aDefault = true); 103 bool CheckAndUpdatePref(const char* aPrefName, 104 const nsAString& aCurrentValue); 105 bool CheckAndUpdateBoolPref(const char* aPrefName, bool aCurrentValue); 106 std::string GetFullPrefName(const char* aPref); 107 108 private: 109 // Either process. 110 void InitializeIfNeeded(); 111 bool CheckOrRefreshEnvironment(); 112 bool UpdateBaseEnvironment(); 113 DriverInitStatus GetStatus() const; 114 115 // Parent process only. 116 nsCOMPtr<nsIFile> GetGuardFile(); 117 bool RecoverFromCrash(); 118 void ActivateGuard(); 119 void FlushPreferences(); 120 void SetStatus(DriverInitStatus aStatus); 121 122 private: 123 CrashGuardType mType; 124 Mode mMode; 125 bool mInitialized; 126 bool mGuardActivated; 127 bool mCrashDetected; 128 nsCOMPtr<nsIFile> mGuardFile; 129 130 protected: 131 nsCString mStatusPref; 132 nsCOMPtr<nsIGfxInfo> mGfxInfo; 133 }; 134 135 class D3D11LayersCrashGuard final : public DriverCrashGuard { 136 public: 137 explicit D3D11LayersCrashGuard(dom::ContentParent* aContentParent = nullptr); 138 139 protected: 140 void Initialize() override; 141 bool UpdateEnvironment() override; 142 void LogCrashRecovery() override; 143 void LogFeatureDisabled() override; 144 145 private: 146 void RecordTelemetry(TelemetryState aState); 147 }; 148 149 class GLContextCrashGuard final : public DriverCrashGuard { 150 public: 151 explicit GLContextCrashGuard(dom::ContentParent* aContentParent = nullptr); 152 void Initialize() override; 153 154 protected: 155 bool UpdateEnvironment() override; 156 void LogCrashRecovery() override; 157 void LogFeatureDisabled() override; 158 }; 159 160 class WMFVPXVideoCrashGuard final : public DriverCrashGuard { 161 public: 162 explicit WMFVPXVideoCrashGuard(dom::ContentParent* aContentParent = nullptr); 163 164 protected: 165 void LogCrashRecovery() override; 166 void LogFeatureDisabled() override; 167 }; 168 169 } // namespace gfx 170 } // namespace mozilla 171 172 #endif // gfx_src_DriverCrashGuard_h__