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/. */
7 #include "mozilla/UniquePtr.h"
8 #include "mozilla/Unused.h"
9 #include "mozilla/gfx/GPUParent.h"
10 #include "mozilla/gfx/GraphicsMessages.h"
16 static UniquePtr
<gfxConfig
> sConfig
;
18 /* static */ FeatureState
& gfxConfig::GetFeature(Feature aFeature
) {
19 return sConfig
->GetState(aFeature
);
23 bool gfxConfig::IsEnabled(Feature aFeature
) {
24 const FeatureState
& state
= sConfig
->GetState(aFeature
);
25 return state
.IsEnabled();
29 bool gfxConfig::IsDisabledByDefault(Feature aFeature
) {
30 const FeatureState
& state
= sConfig
->GetState(aFeature
);
31 return state
.DisabledByDefault();
35 bool gfxConfig::IsForcedOnByUser(Feature aFeature
) {
36 const FeatureState
& state
= sConfig
->GetState(aFeature
);
37 return state
.IsForcedOnByUser();
41 FeatureStatus
gfxConfig::GetValue(Feature aFeature
) {
42 const FeatureState
& state
= sConfig
->GetState(aFeature
);
43 return state
.GetValue();
47 bool gfxConfig::SetDefault(Feature aFeature
, bool aEnable
,
48 FeatureStatus aDisableStatus
,
49 const char* aDisableMessage
) {
50 FeatureState
& state
= sConfig
->GetState(aFeature
);
51 return state
.SetDefault(aEnable
, aDisableStatus
, aDisableMessage
);
55 void gfxConfig::DisableByDefault(Feature aFeature
, FeatureStatus aDisableStatus
,
56 const char* aDisableMessage
,
57 const nsACString
& aFailureId
) {
58 FeatureState
& state
= sConfig
->GetState(aFeature
);
59 state
.DisableByDefault(aDisableStatus
, aDisableMessage
, aFailureId
);
63 void gfxConfig::EnableByDefault(Feature aFeature
) {
64 FeatureState
& state
= sConfig
->GetState(aFeature
);
65 state
.EnableByDefault();
69 void gfxConfig::SetDefaultFromPref(Feature aFeature
, const char* aPrefName
,
70 bool aIsEnablePref
, bool aDefaultValue
) {
71 FeatureState
& state
= sConfig
->GetState(aFeature
);
72 return state
.SetDefaultFromPref(aPrefName
, aIsEnablePref
, aDefaultValue
);
76 bool gfxConfig::InitOrUpdate(Feature aFeature
, bool aEnable
,
77 FeatureStatus aDisableStatus
,
78 const char* aDisableMessage
) {
79 FeatureState
& state
= sConfig
->GetState(aFeature
);
80 return state
.InitOrUpdate(aEnable
, aDisableStatus
, aDisableMessage
);
84 void gfxConfig::SetFailed(Feature aFeature
, FeatureStatus aStatus
,
85 const char* aMessage
, const nsACString
& aFailureId
) {
86 FeatureState
& state
= sConfig
->GetState(aFeature
);
87 state
.SetFailed(aStatus
, aMessage
, aFailureId
);
91 void gfxConfig::Disable(Feature aFeature
, FeatureStatus aStatus
,
92 const char* aMessage
, const nsACString
& aFailureId
) {
93 FeatureState
& state
= sConfig
->GetState(aFeature
);
94 state
.Disable(aStatus
, aMessage
, aFailureId
);
98 void gfxConfig::UserEnable(Feature aFeature
, const char* aMessage
) {
99 FeatureState
& state
= sConfig
->GetState(aFeature
);
100 state
.UserEnable(aMessage
);
104 void gfxConfig::UserForceEnable(Feature aFeature
, const char* aMessage
) {
105 FeatureState
& state
= sConfig
->GetState(aFeature
);
106 state
.UserForceEnable(aMessage
);
110 void gfxConfig::UserDisable(Feature aFeature
, const char* aMessage
,
111 const nsACString
& aFailureId
) {
112 FeatureState
& state
= sConfig
->GetState(aFeature
);
113 state
.UserDisable(aMessage
, aFailureId
);
117 void gfxConfig::Reenable(Feature aFeature
, Fallback aFallback
) {
118 FeatureState
& state
= sConfig
->GetState(aFeature
);
119 MOZ_ASSERT(IsFeatureStatusFailure(state
.GetValue()));
121 const char* message
= state
.GetRuntimeMessage();
122 EnableFallback(aFallback
, message
);
123 state
.SetRuntime(FeatureStatus::Available
, nullptr, nsCString());
127 void gfxConfig::Reset(Feature aFeature
) {
128 FeatureState
& state
= sConfig
->GetState(aFeature
);
133 void gfxConfig::Inherit(Feature aFeature
, FeatureStatus aStatus
) {
134 FeatureState
& state
= sConfig
->GetState(aFeature
);
139 case FeatureStatus::Unused
:
141 case FeatureStatus::Available
:
142 gfxConfig::EnableByDefault(aFeature
);
144 case FeatureStatus::ForceEnabled
:
145 gfxConfig::EnableByDefault(aFeature
);
146 gfxConfig::UserForceEnable(aFeature
, "Inherited from parent process");
149 gfxConfig::SetDefault(aFeature
, false, aStatus
,
150 "Disabled in parent process");
156 void gfxConfig::Inherit(EnumSet
<Feature
> aFeatures
,
157 const DevicePrefs
& aDevicePrefs
) {
158 for (Feature feature
: aFeatures
) {
159 FeatureStatus status
= FeatureStatus::Unused
;
161 case Feature::HW_COMPOSITING
:
162 status
= aDevicePrefs
.hwCompositing();
164 case Feature::D3D11_COMPOSITING
:
165 status
= aDevicePrefs
.d3d11Compositing();
167 case Feature::OPENGL_COMPOSITING
:
168 status
= aDevicePrefs
.oglCompositing();
170 case Feature::DIRECT2D
:
171 status
= aDevicePrefs
.useD2D1();
176 gfxConfig::Inherit(feature
, status
);
181 bool gfxConfig::UseFallback(Fallback aFallback
) {
182 return sConfig
->UseFallbackImpl(aFallback
);
186 void gfxConfig::EnableFallback(Fallback aFallback
, const char* aMessage
) {
187 if (!NS_IsMainThread()) {
188 nsCString
message(aMessage
);
189 NS_DispatchToMainThread(
190 NS_NewRunnableFunction("gfxConfig::EnableFallback", [=]() -> void {
191 gfxConfig::EnableFallback(aFallback
, message
.get());
196 if (XRE_IsGPUProcess()) {
197 nsCString
message(aMessage
);
198 Unused
<< GPUParent::GetSingleton()->SendUsedFallback(aFallback
, message
);
202 sConfig
->EnableFallbackImpl(aFallback
, aMessage
);
205 bool gfxConfig::UseFallbackImpl(Fallback aFallback
) const {
206 return !!(mFallbackBits
& (uint64_t(1) << uint64_t(aFallback
)));
209 void gfxConfig::EnableFallbackImpl(Fallback aFallback
, const char* aMessage
) {
210 if (!UseFallbackImpl(aFallback
)) {
211 MOZ_ASSERT(mNumFallbackLogEntries
< kNumFallbacks
);
213 FallbackLogEntry
& entry
= mFallbackLog
[mNumFallbackLogEntries
];
214 mNumFallbackLogEntries
++;
216 entry
.mFallback
= aFallback
;
217 PL_strncpyz(entry
.mMessage
, aMessage
, sizeof(entry
.mMessage
));
219 mFallbackBits
|= (uint64_t(1) << uint64_t(aFallback
));
224 const char* description
;
226 static const FeatureInfo sFeatureInfo
[] = {
227 #define FOR_EACH_FEATURE(name, type, desc) {#name, desc},
228 GFX_FEATURE_MAP(FOR_EACH_FEATURE
)
229 #undef FOR_EACH_FEATURE
233 void gfxConfig::ForEachFeature(const FeatureIterCallback
& aCallback
) {
234 for (size_t i
= 0; i
< kNumFeatures
; i
++) {
235 FeatureState
& state
= GetFeature(static_cast<Feature
>(i
));
236 if (!state
.IsInitialized()) {
240 aCallback(sFeatureInfo
[i
].name
, sFeatureInfo
[i
].description
, state
);
244 static const char* sFallbackNames
[] = {
245 #define FOR_EACH_FALLBACK(name) #name,
246 GFX_FALLBACK_MAP(FOR_EACH_FALLBACK
)
247 #undef FOR_EACH_FALLBACK
251 void gfxConfig::ForEachFallback(const FallbackIterCallback
& aCallback
) {
252 sConfig
->ForEachFallbackImpl(aCallback
);
255 void gfxConfig::ForEachFallbackImpl(const FallbackIterCallback
& aCallback
) {
256 for (size_t i
= 0; i
< mNumFallbackLogEntries
; i
++) {
257 const FallbackLogEntry
& entry
= mFallbackLog
[i
];
258 aCallback(sFallbackNames
[size_t(entry
.mFallback
)], entry
.mMessage
);
262 /* static */ const nsCString
& gfxConfig::GetFailureId(Feature aFeature
) {
263 const FeatureState
& state
= sConfig
->GetState(aFeature
);
264 return state
.GetFailureId();
268 void gfxConfig::ImportChange(Feature aFeature
,
269 const Maybe
<FeatureFailure
>& aChange
) {
270 if (aChange
.isNothing()) {
274 const FeatureFailure
& failure
= aChange
.ref();
275 gfxConfig::SetFailed(aFeature
, failure
.status(), failure
.message().get(),
276 failure
.failureId());
280 void gfxConfig::Init() { sConfig
= mozilla::MakeUnique
<gfxConfig
>(); }
283 void gfxConfig::Shutdown() { sConfig
= nullptr; }
286 } // namespace mozilla