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 mozilla_gfx_config_gfxConfig_h 7 #define mozilla_gfx_config_gfxConfig_h 8 9 #include <functional> 10 #include "gfxFeature.h" 11 #include "gfxFallback.h" 12 #include "mozilla/Assertions.h" 13 #include "mozilla/EnumSet.h" 14 #include "mozilla/Maybe.h" 15 16 namespace mozilla { 17 namespace gfx { 18 19 // Defined in GraphicsMessages.ipdlh. 20 class DevicePrefs; 21 class FeatureFailure; 22 23 // Manages the history and state of a graphics feature. The flow of a feature 24 // is: 25 // - A default value, set by all.js, or gfxPlatform. 26 // - A user value, set by an external value or user pref. 27 // - An environment value, determined by system/hardware factors or 28 // nsIGfxInfo. 29 // - A runtime value, determined by any failures encountered after enabling 30 // the feature. 31 // 32 // Each state change for a feature is recorded in this class. 33 class gfxConfig { 34 public: 35 // Return the full state history of a feature. 36 static FeatureState& GetFeature(Feature aFeature); 37 38 // Query whether a parameter is enabled, taking into account any user or 39 // runtime overrides. The algorithm works as follow: 40 // 41 // 1. If a runtime decision disabled the feature, return false. 42 // 2. If the user force-enabled the feature, return true. 43 // 3. If the environment disabled the feature, return false. 44 // 4. If the user specified a decision, return it. 45 // 5. Return the base setting for the feature. 46 static bool IsEnabled(Feature aFeature); 47 48 // Query the history of a parameter. ForcedOnByUser returns whether or not 49 // the user specifically used a "force" preference to enable the parameter. 50 // IsDisabledByDefault returns whether or not the initial status of the 51 // feature, before adding user prefs and runtime decisions, was disabled. 52 static bool IsForcedOnByUser(Feature aFeature); 53 54 // This returns true if the feature was disabled by default, or was never 55 // initialized to begin with. 56 static bool IsDisabledByDefault(Feature aFeature); 57 58 // Query the status value of a parameter. This is computed similar to 59 // IsEnabled: 60 // 61 // 1. If a runtime failure was set, return it. 62 // 2. If the user force-enabled the feature, return ForceEnabled. 63 // 3. If an environment status was set, return it. 64 // 4. If a user status was set, return it. 65 // 5. Return the default status. 66 static FeatureStatus GetValue(Feature aFeature); 67 68 // Reset the entire state of a feature. 69 static void Reset(Feature aFeature); 70 71 // Initialize the base value of a parameter. The return value is aEnable. 72 static bool SetDefault(Feature aFeature, bool aEnable, 73 FeatureStatus aDisableStatus, 74 const char* aDisableMessage); 75 static void DisableByDefault(Feature aFeature, FeatureStatus aDisableStatus, 76 const char* aDisableMessage, 77 const nsACString& aFailureId = ""_ns); 78 static void EnableByDefault(Feature aFeature); 79 80 // Inherit a computed value from another process. 81 static void Inherit(Feature aFeature, FeatureStatus aStatus); 82 83 // Inherit a set of computed values from another process. 84 static void Inherit(EnumSet<Feature> aFeatures, 85 const DevicePrefs& aDevicePrefs); 86 87 // Set a environment status that overrides both the default and user 88 // statuses; this should be used to disable features based on system 89 // or hardware problems that can be determined up-front. The only 90 // status that can override this decision is the user force-enabling 91 // the feature. 92 static void Disable(Feature aFeature, FeatureStatus aStatus, 93 const char* aMessage, 94 const nsACString& aFailureId = ""_ns); 95 96 // Given a preference name, infer the default value and whether or not the 97 // user has changed it. |aIsEnablePref| specifies whether or not the pref 98 // is intended to enable a feature (true), or disable it (false). 99 static void SetDefaultFromPref(Feature aFeature, const char* aPrefName, 100 bool aIsEnablePref, bool aDefaultValue); 101 102 // Disable a parameter based on a runtime decision. This permanently 103 // disables the feature, since runtime decisions override all other 104 // decisions. 105 static void SetFailed(Feature aFeature, FeatureStatus aStatus, 106 const char* aMessage, 107 const nsACString& aFailureId = ""_ns); 108 109 // Force a feature to be disabled permanently. This is the same as 110 // SetFailed(), but the name may be clearer depending on the context. 111 static void ForceDisable(Feature aFeature, FeatureStatus aStatus, 112 const char* aMessage, 113 const nsACString& aFailureId = ""_ns) { 114 SetFailed(aFeature, aStatus, aMessage, aFailureId); 115 } 116 117 // Convenience helpers for SetFailed(). 118 static bool MaybeSetFailed(Feature aFeature, bool aEnable, 119 FeatureStatus aDisableStatus, 120 const char* aDisableMessage, 121 const nsACString& aFailureId = ""_ns) { 122 if (!aEnable) { 123 SetFailed(aFeature, aDisableStatus, aDisableMessage, aFailureId); 124 return false; 125 } 126 return true; 127 } 128 129 // Convenience helper for SetFailed(). 130 static bool MaybeSetFailed(Feature aFeature, FeatureStatus aStatus, 131 const char* aDisableMessage, 132 const nsACString& aFailureId = ""_ns) { 133 return MaybeSetFailed(aFeature, 134 (aStatus != FeatureStatus::Available && 135 aStatus != FeatureStatus::ForceEnabled), 136 aStatus, aDisableMessage, aFailureId); 137 } 138 139 // Re-enables a feature that was previously disabled, by attaching it to a 140 // fallback. The fallback inherits the message that was used for disabling 141 // the feature. This can be used, for example, when D3D11 fails at runtime 142 // but we acquire a second, successful device with WARP. 143 static void Reenable(Feature aFeature, Fallback aFallback); 144 145 // Same as SetDefault, except if the feature already has a default value 146 // set, the new value will be set as a runtime value. This is useful for 147 // when the base value can change (for example, via an update from the 148 // parent process). 149 static bool InitOrUpdate(Feature aFeature, bool aEnable, 150 FeatureStatus aDisableStatus, 151 const char* aDisableMessage); 152 153 // Set a user status that overrides the base value (but not runtime value) 154 // of a parameter. 155 static void UserEnable(Feature aFeature, const char* aMessage); 156 static void UserForceEnable(Feature aFeature, const char* aMessage); 157 static void UserDisable(Feature aFeature, const char* aMessage, 158 const nsACString& aFailureId = ""_ns); 159 160 // Query whether a fallback has been toggled. 161 static bool UseFallback(Fallback aFallback); 162 163 // Add a log entry denoting that a given fallback had to be used. This can 164 // be called from any thread in the UI or GPU process. 165 static void EnableFallback(Fallback aFallback, const char* aMessage); 166 167 // Run a callback for each initialized FeatureState. 168 typedef std::function<void(const char* aName, const char* aDescription, 169 FeatureState& aFeature)> 170 FeatureIterCallback; 171 static void ForEachFeature(const FeatureIterCallback& aCallback); 172 173 // Run a callback for each enabled fallback. 174 typedef std::function<void(const char* aName, const char* aMsg)> 175 FallbackIterCallback; 176 static void ForEachFallback(const FallbackIterCallback& aCallback); 177 178 // Get the most descriptive failure id message for this feature. 179 static const nsCString& GetFailureId(Feature aFeature); 180 181 static void ImportChange(Feature aFeature, 182 const Maybe<FeatureFailure>& aChange); 183 184 static void Init(); 185 static void Shutdown(); 186 187 private: 188 void ForEachFallbackImpl(const FallbackIterCallback& aCallback); 189 190 private: GetState(Feature aFeature)191 FeatureState& GetState(Feature aFeature) { 192 MOZ_ASSERT(size_t(aFeature) < kNumFeatures); 193 return mFeatures[size_t(aFeature)]; 194 } GetState(Feature aFeature)195 const FeatureState& GetState(Feature aFeature) const { 196 MOZ_ASSERT(size_t(aFeature) < kNumFeatures); 197 return mFeatures[size_t(aFeature)]; 198 } 199 200 bool UseFallbackImpl(Fallback aFallback) const; 201 void EnableFallbackImpl(Fallback aFallback, const char* aMessage); 202 203 private: 204 static const size_t kNumFeatures = size_t(Feature::NumValues); 205 static const size_t kNumFallbacks = size_t(Fallback::NumValues); 206 207 private: 208 FeatureState mFeatures[kNumFeatures]; 209 uint64_t mFallbackBits; 210 211 private: 212 struct FallbackLogEntry { 213 Fallback mFallback; 214 char mMessage[80]; 215 }; 216 217 FallbackLogEntry mFallbackLog[kNumFallbacks]; 218 size_t mNumFallbackLogEntries; 219 }; 220 221 } // namespace gfx 222 } // namespace mozilla 223 224 #endif // mozilla_gfx_config_gfxConfig_h 225