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