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_gfxFeature_h
7 #define mozilla_gfx_config_gfxFeature_h
8 
9 #include <functional>
10 #include <stdint.h>
11 #include "gfxTelemetry.h"
12 #include "mozilla/Assertions.h"
13 #include "mozilla/Maybe.h"
14 #include "nsString.h"
15 
16 namespace mozilla {
17 namespace gfx {
18 
19 #define GFX_FEATURE_MAP(_)                                               \
20   /* Name,                        Type,         Description */           \
21   _(HW_COMPOSITING, Feature, "Compositing")                              \
22   _(D3D11_COMPOSITING, Feature, "Direct3D11 Compositing")                \
23   _(OPENGL_COMPOSITING, Feature, "OpenGL Compositing")                   \
24   _(DIRECT2D, Feature, "Direct2D")                                       \
25   _(D3D11_HW_ANGLE, Feature, "Direct3D11 hardware ANGLE")                \
26   _(DIRECT_DRAW, Feature, "DirectDraw")                                  \
27   _(GPU_PROCESS, Feature, "GPU Process")                                 \
28   _(WEBRENDER, Feature, "WebRender")                                     \
29   _(WEBRENDER_QUALIFIED, Feature, "WebRender qualified")                 \
30   _(WEBRENDER_COMPOSITOR, Feature, "WebRender native compositor")        \
31   _(WEBRENDER_PARTIAL, Feature, "WebRender partial present")             \
32   _(WEBRENDER_SHADER_CACHE, Feature, "WebRender shader disk cache")      \
33   _(WEBRENDER_OPTIMIZED_SHADERS, Feature, "WebRender optimized shaders") \
34   _(WEBRENDER_ANGLE, Feature, "WebRender ANGLE")                         \
35   _(WEBRENDER_DCOMP_PRESENT, Feature, "WebRender DirectComposition")     \
36   _(WEBRENDER_SOFTWARE, Feature, "WebRender software fallback")          \
37   _(OMTP, Feature, "Off Main Thread Painting")                           \
38   _(WEBGPU, Feature, "WebGPU")                                           \
39   _(X11_EGL, Feature, "X11 EGL")                                         \
40   _(DMABUF, Feature, "DMABUF")                                           \
41   _(WINDOW_OCCLUSION, Feature, "WINDOW_OCCLUSION")                       \
42   _(VAAPI, Feature, "VA-API video decoding")                             \
43   /* Add new entries above this comment */
44 
45 enum class Feature : uint32_t {
46 #define MAKE_ENUM(name, type, desc) name,
47   GFX_FEATURE_MAP(MAKE_ENUM)
48 #undef MAKE_ENUM
49       NumValues
50 };
51 
52 class FeatureState {
53   friend class gfxConfig;
54   friend class GfxConfigManager;  // for testing
55 
56  public:
FeatureState()57   FeatureState() { Reset(); }
58 
59   bool IsEnabled() const;
60   FeatureStatus GetValue() const;
61 
62   void EnableByDefault();
63   void DisableByDefault(FeatureStatus aStatus, const char* aMessage,
64                         const nsACString& aFailureId);
65   bool SetDefault(bool aEnable, FeatureStatus aDisableStatus,
66                   const char* aDisableMessage);
67   bool InitOrUpdate(bool aEnable, FeatureStatus aDisableStatus,
68                     const char* aMessage);
69   void SetDefaultFromPref(const char* aPrefName, bool aIsEnablePref,
70                           bool aDefaultValue, Maybe<bool> aUserValue);
71   void SetDefaultFromPref(const char* aPrefName, bool aIsEnablePref,
72                           bool aDefaultValue);
73   void UserEnable(const char* aMessage);
74   void UserForceEnable(const char* aMessage);
75   void UserDisable(const char* aMessage, const nsACString& aFailureId);
76   void Disable(FeatureStatus aStatus, const char* aMessage,
77                const nsACString& aFailureId);
ForceDisable(FeatureStatus aStatus,const char * aMessage,const nsACString & aFailureId)78   void ForceDisable(FeatureStatus aStatus, const char* aMessage,
79                     const nsACString& aFailureId) {
80     SetFailed(aStatus, aMessage, aFailureId);
81   }
82   void SetFailed(FeatureStatus aStatus, const char* aMessage,
83                  const nsACString& aFailureId);
84   bool MaybeSetFailed(bool aEnable, FeatureStatus aStatus, const char* aMessage,
85                       const nsACString& aFailureId);
86   bool MaybeSetFailed(FeatureStatus aStatus, const char* aMessage,
87                       const nsACString& aFailureId);
88 
89   // aType is "base", "user", "env", or "runtime".
90   // aMessage may be null.
91   typedef std::function<void(const char* aType, FeatureStatus aStatus,
92                              const char* aMessage, const nsCString& aFailureId)>
93       StatusIterCallback;
94   void ForEachStatusChange(const StatusIterCallback& aCallback) const;
95 
96   const char* GetFailureMessage() const;
97   const nsCString& GetFailureId() const;
98   nsCString GetStatusAndFailureIdString() const;
99 
100   bool DisabledByDefault() const;
101 
102  private:
103   void SetUser(FeatureStatus aStatus, const char* aMessage,
104                const nsACString& aFailureId);
105   void SetEnvironment(FeatureStatus aStatus, const char* aMessage,
106                       const nsACString& aFailureId);
107   void SetRuntime(FeatureStatus aStatus, const char* aMessage,
108                   const nsACString& aFailureId);
109   bool IsForcedOnByUser() const;
110   const char* GetRuntimeMessage() const;
IsInitialized()111   bool IsInitialized() const { return mDefault.IsInitialized(); }
112 
AssertInitialized()113   void AssertInitialized() const { MOZ_ASSERT(IsInitialized()); }
114 
115   // Clear all state.
116   void Reset();
117 
118  private:
119   struct Instance {
120     char mMessage[64];
121     FeatureStatus mStatus;
122     nsCString mFailureId;
123 
124     void Set(FeatureStatus aStatus);
125     void Set(FeatureStatus aStatus, const char* aMessage,
126              const nsACString& aFailureId);
IsInitializedInstance127     bool IsInitialized() const { return mStatus != FeatureStatus::Unused; }
MessageOrNullInstance128     const char* MessageOrNull() const {
129       return mMessage[0] != '\0' ? mMessage : nullptr;
130     }
MessageInstance131     const char* Message() const {
132       MOZ_ASSERT(MessageOrNull());
133       return mMessage;
134     }
FailureIdInstance135     const nsCString& FailureId() const { return mFailureId; }
136   };
137 
138   // The default state is the state we decide on startup, based on the operating
139   // system or a base preference.
140   //
141   // The user state factors in any changes to preferences that the user made.
142   //
143   // The environment state factors in any additional decisions made, such as
144   // availability or blocklisting.
145   //
146   // The runtime state factors in any problems discovered at runtime.
147   Instance mDefault;
148   Instance mUser;
149   Instance mEnvironment;
150   Instance mRuntime;
151 };
152 
153 }  // namespace gfx
154 }  // namespace mozilla
155 
156 #endif  // mozilla_gfx_config_gfxFeature_h
157