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