Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "gfxPrefs.h"
7 :
8 : #include "MainThreadUtils.h"
9 : #include "nsXULAppAPI.h"
10 : #include "mozilla/Preferences.h"
11 : #include "mozilla/Unused.h"
12 : #include "mozilla/gfx/gfxVars.h"
13 : #include "mozilla/gfx/Logging.h"
14 : #include "mozilla/gfx/GPUChild.h"
15 : #include "mozilla/gfx/GPUProcessManager.h"
16 :
17 : using namespace mozilla;
18 :
19 : nsTArray<gfxPrefs::Pref*>* gfxPrefs::sGfxPrefList = nullptr;
20 : gfxPrefs* gfxPrefs::sInstance = nullptr;
21 : bool gfxPrefs::sInstanceHasBeenDestroyed = false;
22 :
23 : void
24 0 : gfxPrefs::DestroySingleton()
25 : {
26 0 : if (sInstance) {
27 0 : delete sInstance;
28 0 : sInstance = nullptr;
29 0 : sInstanceHasBeenDestroyed = true;
30 : }
31 0 : MOZ_ASSERT(!SingletonExists());
32 0 : }
33 :
34 : bool
35 33493 : gfxPrefs::SingletonExists()
36 : {
37 33493 : return sInstance != nullptr;
38 : }
39 :
40 3 : gfxPrefs::gfxPrefs()
41 : {
42 : // UI, content, and plugin processes use XPCOM and should have prefs
43 : // ready by the time we initialize gfxPrefs.
44 3 : MOZ_ASSERT_IF(XRE_IsContentProcess() ||
45 : XRE_IsParentProcess() ||
46 : XRE_GetProcessType() == GeckoProcessType_Plugin,
47 : Preferences::IsServiceAvailable());
48 :
49 3 : gfxPrefs::AssertMainThread();
50 3 : }
51 :
52 : void
53 3 : gfxPrefs::Init()
54 : {
55 : // Set up Moz2D prefs.
56 15 : SetGfxLoggingLevelChangeCallback([](const GfxPrefValue& aValue) -> void {
57 3 : mozilla::gfx::LoggingPrefs::sGfxLogLevel = aValue.get_int32_t();
58 12 : });
59 3 : }
60 :
61 0 : gfxPrefs::~gfxPrefs()
62 : {
63 0 : gfxPrefs::AssertMainThread();
64 0 : SetGfxLoggingLevelChangeCallback(nullptr);
65 0 : delete sGfxPrefList;
66 0 : sGfxPrefList = nullptr;
67 0 : }
68 :
69 1035 : void gfxPrefs::AssertMainThread()
70 : {
71 1035 : MOZ_ASSERT(NS_IsMainThread(), "this code must be run on the main thread");
72 1035 : }
73 :
74 : void
75 0 : gfxPrefs::Pref::OnChange()
76 : {
77 0 : if (auto gpm = gfx::GPUProcessManager::Get()) {
78 0 : if (gfx::GPUChild* gpu = gpm->GetGPUChild()) {
79 0 : GfxPrefValue value;
80 0 : GetLiveValue(&value);
81 0 : Unused << gpu->SendUpdatePref(gfx::GfxPrefSetting(mIndex, value));
82 : }
83 : }
84 0 : FireChangeCallback();
85 0 : }
86 :
87 : void
88 4 : gfxPrefs::Pref::FireChangeCallback()
89 : {
90 4 : if (mChangeCallback) {
91 8 : GfxPrefValue value;
92 4 : GetLiveValue(&value);
93 4 : mChangeCallback(value);
94 : }
95 4 : }
96 :
97 : void
98 4 : gfxPrefs::Pref::SetChangeCallback(ChangeCallback aCallback)
99 : {
100 4 : mChangeCallback = aCallback;
101 :
102 4 : if (!IsParentProcess() && IsPrefsServiceAvailable()) {
103 : // If we're in the parent process, we watch prefs by default so we can
104 : // send changes over to the GPU process. Otherwise, we need to add or
105 : // remove a watch for the pref now.
106 2 : if (aCallback) {
107 2 : WatchChanges(Name(), this);
108 : } else {
109 0 : UnwatchChanges(Name(), this);
110 : }
111 : }
112 :
113 : // Fire the callback once to make initialization easier for the caller.
114 4 : FireChangeCallback();
115 4 : }
116 :
117 : // On lightweight processes such as for GMP and GPU, XPCOM is not initialized,
118 : // and therefore we don't have access to Preferences. When XPCOM is not
119 : // available we rely on manual synchronization of gfxPrefs values over IPC.
120 : /* static */ bool
121 2332 : gfxPrefs::IsPrefsServiceAvailable()
122 : {
123 2332 : return Preferences::IsServiceAvailable();
124 : }
125 :
126 : /* static */ bool
127 1036 : gfxPrefs::IsParentProcess()
128 : {
129 1036 : return XRE_IsParentProcess();
130 : }
131 :
132 399 : void gfxPrefs::PrefAddVarCache(bool* aVariable,
133 : const char* aPref,
134 : bool aDefault)
135 : {
136 399 : MOZ_ASSERT(IsPrefsServiceAvailable());
137 399 : Preferences::AddBoolVarCache(aVariable, aPref, aDefault);
138 399 : }
139 :
140 213 : void gfxPrefs::PrefAddVarCache(int32_t* aVariable,
141 : const char* aPref,
142 : int32_t aDefault)
143 : {
144 213 : MOZ_ASSERT(IsPrefsServiceAvailable());
145 213 : Preferences::AddIntVarCache(aVariable, aPref, aDefault);
146 213 : }
147 :
148 33 : void gfxPrefs::PrefAddVarCache(uint32_t* aVariable,
149 : const char* aPref,
150 : uint32_t aDefault)
151 : {
152 33 : MOZ_ASSERT(IsPrefsServiceAvailable());
153 33 : Preferences::AddUintVarCache(aVariable, aPref, aDefault);
154 33 : }
155 :
156 123 : void gfxPrefs::PrefAddVarCache(float* aVariable,
157 : const char* aPref,
158 : float aDefault)
159 : {
160 123 : MOZ_ASSERT(IsPrefsServiceAvailable());
161 123 : Preferences::AddFloatVarCache(aVariable, aPref, aDefault);
162 123 : }
163 :
164 0 : void gfxPrefs::PrefAddVarCache(std::string* aVariable,
165 : const char* aPref,
166 : std::string aDefault)
167 : {
168 0 : MOZ_ASSERT(IsPrefsServiceAvailable());
169 0 : Preferences::SetCString(aPref, aVariable->c_str());
170 0 : }
171 :
172 148 : bool gfxPrefs::PrefGet(const char* aPref, bool aDefault)
173 : {
174 148 : MOZ_ASSERT(IsPrefsServiceAvailable());
175 148 : return Preferences::GetBool(aPref, aDefault);
176 : }
177 :
178 75 : int32_t gfxPrefs::PrefGet(const char* aPref, int32_t aDefault)
179 : {
180 75 : MOZ_ASSERT(IsPrefsServiceAvailable());
181 75 : return Preferences::GetInt(aPref, aDefault);
182 : }
183 :
184 33 : uint32_t gfxPrefs::PrefGet(const char* aPref, uint32_t aDefault)
185 : {
186 33 : MOZ_ASSERT(IsPrefsServiceAvailable());
187 33 : return Preferences::GetUint(aPref, aDefault);
188 : }
189 :
190 12 : float gfxPrefs::PrefGet(const char* aPref, float aDefault)
191 : {
192 12 : MOZ_ASSERT(IsPrefsServiceAvailable());
193 12 : return Preferences::GetFloat(aPref, aDefault);
194 : }
195 :
196 0 : std::string gfxPrefs::PrefGet(const char* aPref, std::string aDefault)
197 : {
198 0 : MOZ_ASSERT(IsPrefsServiceAvailable());
199 :
200 0 : nsAdoptingCString result;
201 0 : Preferences::GetCString(aPref, &result);
202 :
203 0 : if (result.IsEmpty()) {
204 0 : return aDefault;
205 : }
206 :
207 0 : return result.get();
208 : }
209 :
210 0 : void gfxPrefs::PrefSet(const char* aPref, bool aValue)
211 : {
212 0 : MOZ_ASSERT(IsPrefsServiceAvailable());
213 0 : Preferences::SetBool(aPref, aValue);
214 0 : }
215 :
216 0 : void gfxPrefs::PrefSet(const char* aPref, int32_t aValue)
217 : {
218 0 : MOZ_ASSERT(IsPrefsServiceAvailable());
219 0 : Preferences::SetInt(aPref, aValue);
220 0 : }
221 :
222 0 : void gfxPrefs::PrefSet(const char* aPref, uint32_t aValue)
223 : {
224 0 : MOZ_ASSERT(IsPrefsServiceAvailable());
225 0 : Preferences::SetUint(aPref, aValue);
226 0 : }
227 :
228 0 : void gfxPrefs::PrefSet(const char* aPref, float aValue)
229 : {
230 0 : MOZ_ASSERT(IsPrefsServiceAvailable());
231 0 : Preferences::SetFloat(aPref, aValue);
232 0 : }
233 :
234 0 : void gfxPrefs::PrefSet(const char* aPref, std::string aValue)
235 : {
236 0 : MOZ_ASSERT(IsPrefsServiceAvailable());
237 0 : Preferences::SetCString(aPref, aValue.c_str());
238 0 : }
239 :
240 : static void
241 0 : OnGfxPrefChanged(const char* aPrefname, void* aClosure)
242 : {
243 0 : reinterpret_cast<gfxPrefs::Pref*>(aClosure)->OnChange();
244 0 : }
245 :
246 258 : void gfxPrefs::WatchChanges(const char* aPrefname, Pref* aPref)
247 : {
248 258 : MOZ_ASSERT(IsPrefsServiceAvailable());
249 258 : Preferences::RegisterCallback(OnGfxPrefChanged, aPrefname, aPref);
250 258 : }
251 :
252 0 : void gfxPrefs::UnwatchChanges(const char* aPrefname, Pref* aPref)
253 : {
254 : // The Preferences service can go offline before gfxPrefs is destroyed.
255 0 : if (IsPrefsServiceAvailable()) {
256 0 : Preferences::UnregisterCallback(OnGfxPrefChanged, aPrefname, aPref);
257 : }
258 0 : }
259 :
260 1 : void gfxPrefs::CopyPrefValue(const bool* aValue, GfxPrefValue* aOutValue)
261 : {
262 1 : *aOutValue = *aValue;
263 1 : }
264 :
265 3 : void gfxPrefs::CopyPrefValue(const int32_t* aValue, GfxPrefValue* aOutValue)
266 : {
267 3 : *aOutValue = *aValue;
268 3 : }
269 :
270 0 : void gfxPrefs::CopyPrefValue(const uint32_t* aValue, GfxPrefValue* aOutValue)
271 : {
272 0 : *aOutValue = *aValue;
273 0 : }
274 :
275 0 : void gfxPrefs::CopyPrefValue(const float* aValue, GfxPrefValue* aOutValue)
276 : {
277 0 : *aOutValue = *aValue;
278 0 : }
279 :
280 0 : void gfxPrefs::CopyPrefValue(const std::string* aValue, GfxPrefValue* aOutValue)
281 : {
282 0 : *aOutValue = nsCString(aValue->c_str());
283 0 : }
284 :
285 0 : void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, bool* aOutValue)
286 : {
287 0 : *aOutValue = aValue->get_bool();
288 0 : }
289 :
290 0 : void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, int32_t* aOutValue)
291 : {
292 0 : *aOutValue = aValue->get_int32_t();
293 0 : }
294 :
295 0 : void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, uint32_t* aOutValue)
296 : {
297 0 : *aOutValue = aValue->get_uint32_t();
298 0 : }
299 :
300 0 : void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, float* aOutValue)
301 : {
302 0 : *aOutValue = aValue->get_float();
303 0 : }
304 :
305 0 : void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, std::string* aOutValue)
306 : {
307 0 : *aOutValue = aValue->get_nsCString().get();
308 0 : }
309 :
310 255 : bool gfxPrefs::OverrideBase_WebRender()
311 : {
312 255 : return gfx::gfxVars::UseWebRender();
313 : }
314 :
315 444 : bool gfxPrefs::OverrideBase_WebRendest()
316 : {
317 444 : return gfx::gfxVars::UseWebRender() && gfxPrefs::WebRendestEnabled();
318 : }
|