DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (56e7b9127e89)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_gfx_config_gfxConfig_h
#define mozilla_gfx_config_gfxConfig_h

#include <functional>
#include "gfxFeature.h"
#include "gfxFallback.h"
#include "mozilla/Assertions.h"

namespace mozilla {
namespace gfx {

// Defined in GraphicsMessages.ipdlh.
class FeatureChange;

// Manages the history and state of a graphics feature. The flow of a feature
// is:
//   - A default value, set by all.js, gfxPrefs, or gfxPlatform.
//   - A user value, set by an external value or user pref.
//   - An environment value, determined by system/hardware factors or nsIGfxInfo.
//   - A runtime value, determined by any failures encountered after enabling
//     the feature.
//
// Each state change for a feature is recorded in this class.
class gfxConfig
{
public:
  // Return the full state history of a feature.
  static FeatureState& GetFeature(Feature aFeature);

  // Query whether a parameter is enabled, taking into account any user or
  // runtime overrides. The algorithm works as follow:
  //
  //  1. If a runtime decision disabled the feature, return false.
  //  2. If the user force-enabled the feature, return true.
  //  3. If the environment disabled the feature, return false.
  //  4. If the user specified a decision, return it.
  //  5. Return the base setting for the feature.
  static bool IsEnabled(Feature aFeature);

  // Query the history of a parameter. ForcedOnByUser returns whether or not
  // the user specifically used a "force" preference to enable the parameter.
  // IsDisabledByDefault returns whether or not the initial status of the
  // feature, before adding user prefs and runtime decisions, was disabled.
  static bool IsForcedOnByUser(Feature aFeature);

  // This returns true if the feature was disabled by default, or was never
  // initialized to begin with.
  static bool IsDisabledByDefault(Feature aFeature);

  // Query the status value of a parameter. This is computed similar to
  // IsEnabled:
  //
  //  1. If a runtime failure was set, return it.
  //  2. If the user force-enabled the feature, return ForceEnabled.
  //  3. If an environment status was set, return it.
  //  4. If a user status was set, return it.
  //  5. Return the default status.
  static FeatureStatus GetValue(Feature aFeature);

  // Reset the entire state of a feature.
  static void Reset(Feature aFeature);

  // Initialize the base value of a parameter. The return value is aEnable.
  static bool SetDefault(Feature aFeature,
                         bool aEnable,
                         FeatureStatus aDisableStatus,
                         const char* aDisableMessage);
  static void DisableByDefault(Feature aFeature,
                               FeatureStatus aDisableStatus,
                               const char* aDisableMessage,
                               const nsACString& aFailureId = EmptyCString());
  static void EnableByDefault(Feature aFeature);

  // Inherit a computed value from another process.
  static void Inherit(Feature aFeature, FeatureStatus aStatus);

  // Set a environment status that overrides both the default and user
  // statuses; this should be used to disable features based on system
  // or hardware problems that can be determined up-front. The only
  // status that can override this decision is the user force-enabling
  // the feature.
  static void Disable(Feature aFeature,
                      FeatureStatus aStatus,
                      const char* aMessage,
                      const nsACString& aFailureId = EmptyCString());

  // Given a preference name, infer the default value and whether or not the
  // user has changed it. |aIsEnablePref| specifies whether or not the pref
  // is intended to enable a feature (true), or disable it (false).
  static void SetDefaultFromPref(Feature aFeature,
                                 const char* aPrefName,
                                 bool aIsEnablePref,
                                 bool aDefaultValue);

  // Disable a parameter based on a runtime decision. This permanently
  // disables the feature, since runtime decisions override all other
  // decisions.
  static void SetFailed(Feature aFeature,
                        FeatureStatus aStatus,
                        const char* aMessage,
                        const nsACString& aFailureId = EmptyCString());

  // Force a feature to be disabled permanently. This is the same as
  // SetFailed(), but the name may be clearer depending on the context.
  static void ForceDisable(Feature aFeature,
                           FeatureStatus aStatus,
                           const char* aMessage,
                           const nsACString& aFailureId = EmptyCString())
  {
    SetFailed(aFeature, aStatus, aMessage, aFailureId);
  }

  // Convenience helpers for SetFailed().
  static bool MaybeSetFailed(Feature aFeature,
                             bool aEnable,
                             FeatureStatus aDisableStatus,
                             const char* aDisableMessage,
                             const nsACString& aFailureId = EmptyCString())
  {
    if (!aEnable) {
      SetFailed(aFeature, aDisableStatus, aDisableMessage, aFailureId);
      return false;
    }
    return true;
  }

  // Convenience helper for SetFailed().
  static bool MaybeSetFailed(Feature aFeature,
                             FeatureStatus aStatus,
                             const char* aDisableMessage,
                             const nsACString& aFailureId = EmptyCString())
  {
    return MaybeSetFailed(
      aFeature,
      (aStatus != FeatureStatus::Available &&
       aStatus != FeatureStatus::ForceEnabled),
      aStatus,
      aDisableMessage, aFailureId);
  }

  // Re-enables a feature that was previously disabled, by attaching it to a
  // fallback. The fallback inherits the message that was used for disabling
  // the feature. This can be used, for example, when D3D11 fails at runtime
  // but we acquire a second, successful device with WARP.
  static void Reenable(Feature aFeature, Fallback aFallback);

  // Same as SetDefault, except if the feature already has a default value
  // set, the new value will be set as a runtime value. This is useful for
  // when the base value can change (for example, via an update from the
  // parent process).
  static bool InitOrUpdate(Feature aFeature,
                           bool aEnable,
                           FeatureStatus aDisableStatus,
                           const char* aDisableMessage);

  // Set a user status that overrides the base value (but not runtime value)
  // of a parameter.
  static void UserEnable(Feature aFeature, const char* aMessage);
  static void UserForceEnable(Feature aFeature, const char* aMessage);
  static void UserDisable(Feature aFeature, const char* aMessage, const nsACString& aFailureId = EmptyCString());

  // Query whether a fallback has been toggled.
  static bool UseFallback(Fallback aFallback);

  // Add a log entry denoting that a given fallback had to be used. This can
  // be called from any thread in the UI or GPU process.
  static void EnableFallback(Fallback aFallback, const char* aMessage);

  // Run a callback for each initialized FeatureState.
  typedef std::function<void(const char* aName,
                             const char* aDescription,
                             FeatureState& aFeature)> FeatureIterCallback;
  static void ForEachFeature(const FeatureIterCallback& aCallback);

  // Run a callback for each enabled fallback.
  typedef std::function<void(const char* aName, const char* aMsg)> 
    FallbackIterCallback;
  static void ForEachFallback(const FallbackIterCallback& aCallback);

  // Get the most descriptive failure id message for this feature.
  static const nsCString& GetFailureId(Feature aFeature);

  static void ImportChange(Feature aFeature, const FeatureChange& aChange);

  static void Init();
  static void Shutdown();

private:
  void ForEachFallbackImpl(const FallbackIterCallback& aCallback);

private:
  FeatureState& GetState(Feature aFeature) {
    MOZ_ASSERT(size_t(aFeature) < kNumFeatures);
    return mFeatures[size_t(aFeature)];
  }
  const FeatureState& GetState(Feature aFeature) const {
    MOZ_ASSERT(size_t(aFeature) < kNumFeatures);
    return mFeatures[size_t(aFeature)];
  }

  bool UseFallbackImpl(Fallback aFallback) const;
  void EnableFallbackImpl(Fallback aFallback, const char* aMessage);

private:
  static const size_t kNumFeatures = size_t(Feature::NumValues);
  static const size_t kNumFallbacks = size_t(Fallback::NumValues);

private:
  FeatureState mFeatures[kNumFeatures];
  uint64_t mFallbackBits;

private:
  struct FallbackLogEntry {
    Fallback mFallback;
    char mMessage[80];
  };

  FallbackLogEntry mFallbackLog[kNumFallbacks];
  size_t mNumFallbackLogEntries;
};

} // namespace gfx
} // namespace mozilla

#endif // mozilla_gfx_config_gfxConfig_h