Line data Source code
1 : /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim: set sts=2 ts=8 sw=2 tw=99 et: */
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 : #include "gfxConfig.h"
7 : #include "mozilla/UniquePtr.h"
8 : #include "mozilla/Unused.h"
9 : #include "mozilla/gfx/GPUParent.h"
10 : #include "mozilla/gfx/GraphicsMessages.h"
11 : #include "plstr.h"
12 :
13 : namespace mozilla {
14 : namespace gfx {
15 :
16 3 : static UniquePtr<gfxConfig> sConfig;
17 :
18 : /* static */ FeatureState&
19 7 : gfxConfig::GetFeature(Feature aFeature)
20 : {
21 7 : return sConfig->GetState(aFeature);
22 : }
23 :
24 : /* static */ bool
25 10 : gfxConfig::IsEnabled(Feature aFeature)
26 : {
27 10 : const FeatureState& state = sConfig->GetState(aFeature);
28 10 : return state.IsEnabled();
29 : }
30 :
31 : /* static */ bool
32 0 : gfxConfig::IsDisabledByDefault(Feature aFeature)
33 : {
34 0 : const FeatureState& state = sConfig->GetState(aFeature);
35 0 : return state.DisabledByDefault();
36 : }
37 :
38 : /* static */ bool
39 0 : gfxConfig::IsForcedOnByUser(Feature aFeature)
40 : {
41 0 : const FeatureState& state = sConfig->GetState(aFeature);
42 0 : return state.IsForcedOnByUser();
43 : }
44 :
45 : /* static */ FeatureStatus
46 8 : gfxConfig::GetValue(Feature aFeature)
47 : {
48 8 : const FeatureState& state = sConfig->GetState(aFeature);
49 8 : return state.GetValue();
50 : }
51 :
52 : /* static */ bool
53 0 : gfxConfig::SetDefault(Feature aFeature,
54 : bool aEnable,
55 : FeatureStatus aDisableStatus,
56 : const char* aDisableMessage)
57 : {
58 0 : FeatureState& state = sConfig->GetState(aFeature);
59 0 : return state.SetDefault(aEnable, aDisableStatus, aDisableMessage);
60 : }
61 :
62 : /* static */ void
63 0 : gfxConfig::DisableByDefault(Feature aFeature,
64 : FeatureStatus aDisableStatus,
65 : const char* aDisableMessage,
66 : const nsACString& aFailureId)
67 : {
68 0 : FeatureState& state = sConfig->GetState(aFeature);
69 0 : state.DisableByDefault(aDisableStatus, aDisableMessage, aFailureId);
70 0 : }
71 :
72 : /* static */ void
73 0 : gfxConfig::EnableByDefault(Feature aFeature)
74 : {
75 0 : FeatureState& state = sConfig->GetState(aFeature);
76 0 : state.EnableByDefault();
77 0 : }
78 :
79 : /* static */ void
80 0 : gfxConfig::SetDefaultFromPref(Feature aFeature,
81 : const char* aPrefName,
82 : bool aIsEnablePref,
83 : bool aDefaultValue)
84 : {
85 0 : FeatureState& state = sConfig->GetState(aFeature);
86 0 : return state.SetDefaultFromPref(aPrefName, aIsEnablePref, aDefaultValue);
87 : }
88 :
89 : /* static */ bool
90 0 : gfxConfig::InitOrUpdate(Feature aFeature,
91 : bool aEnable,
92 : FeatureStatus aDisableStatus,
93 : const char* aDisableMessage)
94 : {
95 0 : FeatureState& state = sConfig->GetState(aFeature);
96 0 : return state.InitOrUpdate(aEnable, aDisableStatus, aDisableMessage);
97 : }
98 :
99 : /* static */ void
100 0 : gfxConfig::SetFailed(Feature aFeature, FeatureStatus aStatus, const char* aMessage,
101 : const nsACString& aFailureId)
102 : {
103 0 : FeatureState& state = sConfig->GetState(aFeature);
104 0 : state.SetFailed(aStatus, aMessage, aFailureId);
105 0 : }
106 :
107 : /* static */ void
108 0 : gfxConfig::Disable(Feature aFeature, FeatureStatus aStatus, const char* aMessage,
109 : const nsACString& aFailureId)
110 : {
111 0 : FeatureState& state = sConfig->GetState(aFeature);
112 0 : state.Disable(aStatus, aMessage, aFailureId);
113 0 : }
114 :
115 : /* static */ void
116 0 : gfxConfig::UserEnable(Feature aFeature, const char* aMessage)
117 : {
118 0 : FeatureState& state = sConfig->GetState(aFeature);
119 0 : state.UserEnable(aMessage);
120 0 : }
121 :
122 : /* static */ void
123 0 : gfxConfig::UserForceEnable(Feature aFeature, const char* aMessage)
124 : {
125 0 : FeatureState& state = sConfig->GetState(aFeature);
126 0 : state.UserForceEnable(aMessage);
127 0 : }
128 :
129 : /* static */ void
130 0 : gfxConfig::UserDisable(Feature aFeature, const char* aMessage, const nsACString& aFailureId)
131 : {
132 0 : FeatureState& state = sConfig->GetState(aFeature);
133 0 : state.UserDisable(aMessage, aFailureId);
134 0 : }
135 :
136 : /* static */ void
137 0 : gfxConfig::Reenable(Feature aFeature, Fallback aFallback)
138 : {
139 0 : FeatureState& state = sConfig->GetState(aFeature);
140 0 : MOZ_ASSERT(IsFeatureStatusFailure(state.GetValue()));
141 :
142 0 : const char* message = state.GetRuntimeMessage();
143 0 : EnableFallback(aFallback, message);
144 0 : state.SetRuntime(FeatureStatus::Available, nullptr);
145 0 : }
146 :
147 : /* static */ void
148 0 : gfxConfig::Reset(Feature aFeature)
149 : {
150 0 : FeatureState& state = sConfig->GetState(aFeature);
151 0 : state.Reset();
152 0 : }
153 :
154 : /* static */ void
155 0 : gfxConfig::Inherit(Feature aFeature, FeatureStatus aStatus)
156 : {
157 0 : FeatureState& state = sConfig->GetState(aFeature);
158 :
159 0 : state.Reset();
160 :
161 0 : switch (aStatus) {
162 : case FeatureStatus::Unused:
163 0 : break;
164 : case FeatureStatus::Available:
165 0 : gfxConfig::EnableByDefault(aFeature);
166 0 : break;
167 : case FeatureStatus::ForceEnabled:
168 0 : gfxConfig::EnableByDefault(aFeature);
169 0 : gfxConfig::UserForceEnable(aFeature, "Inherited from parent process");
170 0 : break;
171 : default:
172 : gfxConfig::SetDefault(
173 : aFeature,
174 : false,
175 : aStatus,
176 0 : "Disabled in parent process");
177 0 : break;
178 : }
179 0 : }
180 :
181 : /* static */ bool
182 0 : gfxConfig::UseFallback(Fallback aFallback)
183 : {
184 0 : return sConfig->UseFallbackImpl(aFallback);
185 : }
186 :
187 : /* static */ void
188 0 : gfxConfig::EnableFallback(Fallback aFallback, const char* aMessage)
189 : {
190 0 : if (!NS_IsMainThread()) {
191 0 : nsCString message(aMessage);
192 0 : NS_DispatchToMainThread(
193 0 : NS_NewRunnableFunction("gfxConfig::EnableFallback",
194 0 : [=]() -> void {
195 :
196 0 : gfxConfig::EnableFallback(aFallback, message.get());
197 0 : }));
198 0 : return;
199 : }
200 :
201 0 : if (XRE_IsGPUProcess()) {
202 0 : nsCString message(aMessage);
203 0 : Unused << GPUParent::GetSingleton()->SendUsedFallback(aFallback, message);
204 0 : return;
205 : }
206 :
207 0 : sConfig->EnableFallbackImpl(aFallback, aMessage);
208 : }
209 :
210 : bool
211 0 : gfxConfig::UseFallbackImpl(Fallback aFallback) const
212 : {
213 0 : return !!(mFallbackBits & (uint64_t(1) << uint64_t(aFallback)));
214 : }
215 :
216 : void
217 0 : gfxConfig::EnableFallbackImpl(Fallback aFallback, const char* aMessage)
218 : {
219 0 : if (!UseFallbackImpl(aFallback)) {
220 0 : MOZ_ASSERT(mNumFallbackLogEntries < kNumFallbacks);
221 :
222 0 : FallbackLogEntry& entry = mFallbackLog[mNumFallbackLogEntries];
223 0 : mNumFallbackLogEntries++;
224 :
225 0 : entry.mFallback = aFallback;
226 0 : PL_strncpyz(entry.mMessage, aMessage, sizeof(entry.mMessage));
227 : }
228 0 : mFallbackBits |= (uint64_t(1) << uint64_t(aFallback));
229 0 : }
230 :
231 : struct FeatureInfo {
232 : const char* name;
233 : const char* description;
234 : };
235 : static const FeatureInfo sFeatureInfo[] = {
236 : #define FOR_EACH_FEATURE(name, type, desc) {#name, desc},
237 : GFX_FEATURE_MAP(FOR_EACH_FEATURE)
238 : #undef FOR_EACH_FEATURE
239 : {nullptr, nullptr}
240 : };
241 :
242 : /* static */ void
243 0 : gfxConfig::ForEachFeature(const FeatureIterCallback& aCallback)
244 : {
245 0 : for (size_t i = 0; i < kNumFeatures; i++) {
246 0 : FeatureState& state = GetFeature(static_cast<Feature>(i));
247 0 : if (!state.IsInitialized()) {
248 0 : continue;
249 : }
250 :
251 0 : aCallback(sFeatureInfo[i].name,
252 0 : sFeatureInfo[i].description,
253 0 : state);
254 : }
255 0 : }
256 :
257 : static const char* sFallbackNames[] = {
258 : #define FOR_EACH_FALLBACK(name) #name,
259 : GFX_FALLBACK_MAP(FOR_EACH_FALLBACK)
260 : #undef FOR_EACH_FALLBACK
261 : nullptr
262 : };
263 :
264 : /* static */ void
265 0 : gfxConfig::ForEachFallback(const FallbackIterCallback& aCallback)
266 : {
267 0 : sConfig->ForEachFallbackImpl(aCallback);
268 0 : }
269 :
270 : void
271 0 : gfxConfig::ForEachFallbackImpl(const FallbackIterCallback& aCallback)
272 : {
273 0 : for (size_t i = 0; i < mNumFallbackLogEntries; i++) {
274 0 : const FallbackLogEntry& entry = mFallbackLog[i];
275 0 : aCallback(sFallbackNames[size_t(entry.mFallback)], entry.mMessage);
276 : }
277 0 : }
278 :
279 : /* static */ const nsCString&
280 0 : gfxConfig::GetFailureId(Feature aFeature)
281 : {
282 0 : const FeatureState& state = sConfig->GetState(aFeature);
283 0 : return state.GetFailureId();
284 : }
285 :
286 : /* static */ void
287 0 : gfxConfig::ImportChange(Feature aFeature, const FeatureChange& aChange)
288 : {
289 0 : if (aChange.type() == FeatureChange::Tnull_t) {
290 0 : return;
291 : }
292 :
293 0 : const FeatureFailure& failure = aChange.get_FeatureFailure();
294 0 : gfxConfig::SetFailed(
295 : aFeature,
296 0 : failure.status(),
297 0 : failure.message().get(),
298 0 : failure.failureId());
299 : }
300 :
301 : /* static */ void
302 3 : gfxConfig::Init()
303 : {
304 3 : sConfig = mozilla::MakeUnique<gfxConfig>();
305 3 : }
306 :
307 : /* static */ void
308 0 : gfxConfig::Shutdown()
309 : {
310 0 : sConfig = nullptr;
311 0 : }
312 :
313 : } // namespace gfx
314 : } // namespace mozilla
|