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