Bug 1640914 [wpt PR 23771] - Python 3: port tests in resource-timing, a=testonly
[gecko.git] / gfx / config / WebRenderRollout.cpp
blob205010f3f31257d0394922bc68d2c822efa73553
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/. */
7 #include "WebRenderRollout.h"
8 #include "mozilla/Preferences.h"
9 #include "mozilla/ScopeExit.h"
10 #include "mozilla/Services.h"
11 #include "nsCOMPtr.h"
12 #include "nsIObserver.h"
13 #include "nsIObserverService.h"
14 #include "nsISupportsImpl.h"
15 #include "nsXULAppAPI.h"
17 namespace mozilla {
18 namespace gfx {
20 static const char* const WR_ROLLOUT_PREF = "gfx.webrender.all.qualified";
21 static const bool WR_ROLLOUT_PREF_DEFAULTVALUE = true;
22 static const char* const WR_ROLLOUT_DEFAULT_PREF =
23 "gfx.webrender.all.qualified.default";
24 static const bool WR_ROLLOUT_DEFAULT_PREF_DEFAULTVALUE = false;
25 static const char* const WR_ROLLOUT_PREF_OVERRIDE =
26 "gfx.webrender.all.qualified.gfxPref-default-override";
27 static const char* const WR_ROLLOUT_HW_QUALIFIED_OVERRIDE =
28 "gfx.webrender.all.qualified.hardware-override";
29 static const char* const PROFILE_BEFORE_CHANGE_TOPIC = "profile-before-change";
31 // If the "gfx.webrender.all.qualified" pref is true we want to enable
32 // WebRender for qualified hardware. This pref may be set by the Normandy
33 // Preference Rollout feature. The Normandy pref rollout code sets default
34 // values on rolled out prefs on every startup. Default pref values are not
35 // persisted; they only exist in memory for that session. Gfx starts up
36 // before Normandy does. So it's too early to observe the WR qualified pref
37 // changed by Normandy rollout on gfx startup. So we add a shutdown observer to
38 // save the default value on shutdown, and read the saved value on startup
39 // instead.
40 class WrRolloutPrefShutdownSaver final : public nsIObserver {
41 public:
42 NS_DECL_ISUPPORTS
44 NS_IMETHOD Observe(nsISupports*, const char* aTopic,
45 const char16_t*) override {
46 if (strcmp(PROFILE_BEFORE_CHANGE_TOPIC, aTopic) != 0) {
47 // Not the observer we're looking for, move along.
48 return NS_OK;
51 SaveRolloutPref();
53 // Shouldn't receive another notification, remove the observer.
54 RefPtr<WrRolloutPrefShutdownSaver> kungFuDeathGrip(this);
55 nsCOMPtr<nsIObserverService> observerService =
56 mozilla::services::GetObserverService();
57 if (NS_WARN_IF(!observerService)) {
58 return NS_ERROR_FAILURE;
60 observerService->RemoveObserver(this, PROFILE_BEFORE_CHANGE_TOPIC);
61 return NS_OK;
64 static void AddShutdownObserver() {
65 MOZ_ASSERT(XRE_IsParentProcess());
66 nsCOMPtr<nsIObserverService> observerService =
67 mozilla::services::GetObserverService();
68 if (NS_WARN_IF(!observerService)) {
69 return;
71 RefPtr<WrRolloutPrefShutdownSaver> wrRolloutSaver =
72 new WrRolloutPrefShutdownSaver();
73 observerService->AddObserver(wrRolloutSaver, PROFILE_BEFORE_CHANGE_TOPIC,
74 false);
77 private:
78 virtual ~WrRolloutPrefShutdownSaver() = default;
80 void SaveRolloutPref() {
81 if (Preferences::HasUserValue(WR_ROLLOUT_PREF) ||
82 Preferences::GetType(WR_ROLLOUT_PREF) == nsIPrefBranch::PREF_INVALID) {
83 // Don't need to create a backup of default value, because either:
84 // 1. the user or the WR SHIELD study has set a user pref value, or
85 // 2. we've not had a default pref set by Normandy that needs to be saved
86 // for reading before Normandy has started up.
87 return;
90 bool defaultValue =
91 Preferences::GetBool(WR_ROLLOUT_PREF, false, PrefValueKind::Default);
92 Preferences::SetBool(WR_ROLLOUT_DEFAULT_PREF, defaultValue);
96 NS_IMPL_ISUPPORTS(WrRolloutPrefShutdownSaver, nsIObserver)
98 /* static */ void WebRenderRollout::Init() {
99 WrRolloutPrefShutdownSaver::AddShutdownObserver();
102 /* static */ Maybe<bool> WebRenderRollout::CalculateQualifiedOverride() {
103 // This pref only ever gets set in test_pref_rollout_workaround, and in
104 // that case we want to ignore the MOZ_WEBRENDER=0 that will be set by
105 // the test harness so as to actually make the test work.
106 if (!Preferences::HasUserValue(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE)) {
107 return Nothing();
109 return Some(Preferences::GetBool(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE, false));
112 // If the "gfx.webrender.all.qualified" pref is true we want to enable
113 // WebRender for qualifying hardware. The Normandy pref rollout code sets
114 // default values on rolled out prefs on every startup, but Gfx starts up
115 // before Normandy does. So it's too early to observe the WR qualified pref
116 // default value changed by Normandy rollout here yet. So we have a shutdown
117 // observer to save the default value on shutdown, and read the saved default
118 // value here instead, and emulate the behavior of the pref system, with
119 // respect to default/user values of the rollout pref.
120 /* static */ bool WebRenderRollout::CalculateQualified() {
121 auto clearPrefOnExit = MakeScopeExit([]() {
122 // Clear the mirror of the default value of the rollout pref on scope exit,
123 // if we have one. This ensures the user doesn't mess with the pref.
124 // If we need it again, we'll re-create it on shutdown.
125 Preferences::ClearUser(WR_ROLLOUT_DEFAULT_PREF);
128 if (!Preferences::HasUserValue(WR_ROLLOUT_PREF) &&
129 Preferences::HasUserValue(WR_ROLLOUT_DEFAULT_PREF)) {
130 // The user has not set a user pref, and we have a default value set by the
131 // shutdown observer. Let's use this as it should be the value Normandy set
132 // before startup. WR_ROLLOUT_DEFAULT_PREF should only be set on shutdown by
133 // the shutdown observer.
134 // Normandy runs *during* startup, but *after* this code here runs (hence
135 // the need for the workaround).
136 // To have a value stored in the WR_ROLLOUT_DEFAULT_PREF pref here, during
137 // the previous run Normandy must have set a default value on the in-memory
138 // pref, and on shutdown we stored the default value in this
139 // WR_ROLLOUT_DEFAULT_PREF user pref. Then once the user restarts, we
140 // observe this pref. Normandy is the only way a default (not user) value
141 // can be set for this pref.
142 return Preferences::GetBool(WR_ROLLOUT_DEFAULT_PREF,
143 WR_ROLLOUT_DEFAULT_PREF_DEFAULTVALUE);
146 // We don't have a user value for the rollout pref, and we don't have the
147 // value of the rollout pref at last shutdown stored. So we should fallback
148 // to using the default. *But* if we're running
149 // under the Marionette pref rollout work-around test, we may want to override
150 // the default value expressed here, so we can test the "default disabled;
151 // rollout pref enabled" case.
152 // Note that those preferences can't be defined in all.js nor
153 // StaticPrefsList.h as they would create the pref, leading SaveRolloutPref()
154 // above to abort early as the pref would have a valid type.
155 // We also don't want those prefs to appear in about:config.
156 if (Preferences::HasUserValue(WR_ROLLOUT_PREF_OVERRIDE)) {
157 return Preferences::GetBool(WR_ROLLOUT_PREF_OVERRIDE);
159 return Preferences::GetBool(WR_ROLLOUT_PREF, WR_ROLLOUT_PREF_DEFAULTVALUE);
162 } // namespace gfx
163 } // namespace mozilla