Bug 1794361 [wpt PR 36364] - Update overlapping nav and traversal tests to match...
[gecko.git] / gfx / ipc / GPUProcessManager.h
blob776bf18e5429db2f797e28a149393ba6d037f3e7
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 _include_mozilla_gfx_ipc_GPUProcessManager_h_
7 #define _include_mozilla_gfx_ipc_GPUProcessManager_h_
9 #include "base/basictypes.h"
10 #include "base/process.h"
11 #include "Units.h"
12 #include "mozilla/UniquePtr.h"
13 #include "mozilla/dom/ipc/IdType.h"
14 #include "mozilla/gfx/GPUProcessHost.h"
15 #include "mozilla/gfx/PGPUChild.h"
16 #include "mozilla/gfx/Point.h"
17 #include "mozilla/ipc/ProtocolUtils.h"
18 #include "mozilla/ipc/TaskFactory.h"
19 #include "mozilla/layers/LayersTypes.h"
20 #include "mozilla/webrender/WebRenderTypes.h"
21 #include "nsIObserver.h"
22 #include "nsThreadUtils.h"
23 class nsBaseWidget;
24 enum class DeviceResetReason;
26 namespace mozilla {
27 class MemoryReportingProcess;
28 class PRemoteDecoderManagerChild;
29 namespace layers {
30 class IAPZCTreeManager;
31 class CompositorOptions;
32 class CompositorSession;
33 class CompositorUpdateObserver;
34 class PCompositorBridgeChild;
35 class PCompositorManagerChild;
36 class PImageBridgeChild;
37 class PVideoBridgeParent;
38 class RemoteCompositorSession;
39 class InProcessCompositorSession;
40 class UiCompositorControllerChild;
41 class WebRenderLayerManager;
42 } // namespace layers
43 namespace widget {
44 class CompositorWidget;
45 } // namespace widget
46 namespace dom {
47 class ContentParent;
48 class BrowserParent;
49 } // namespace dom
50 namespace ipc {
51 class GeckoChildProcessHost;
52 } // namespace ipc
53 namespace gfx {
55 class GPUChild;
56 class GPUProcessListener;
57 class PVRManagerChild;
58 class VsyncBridgeChild;
59 class VsyncIOThreadHolder;
61 // The GPUProcessManager is a singleton responsible for creating GPU-bound
62 // objects that may live in another process. Currently, it provides access
63 // to the compositor via CompositorBridgeParent.
64 class GPUProcessManager final : public GPUProcessHost::Listener {
65 friend class layers::RemoteCompositorSession;
66 friend class layers::InProcessCompositorSession;
68 typedef layers::CompositorOptions CompositorOptions;
69 typedef layers::CompositorSession CompositorSession;
70 typedef layers::CompositorUpdateObserver CompositorUpdateObserver;
71 typedef layers::IAPZCTreeManager IAPZCTreeManager;
72 typedef layers::WebRenderLayerManager WebRenderLayerManager;
73 typedef layers::LayersId LayersId;
74 typedef layers::PCompositorBridgeChild PCompositorBridgeChild;
75 typedef layers::PCompositorManagerChild PCompositorManagerChild;
76 typedef layers::PImageBridgeChild PImageBridgeChild;
77 typedef layers::PVideoBridgeParent PVideoBridgeParent;
78 typedef layers::RemoteCompositorSession RemoteCompositorSession;
79 typedef layers::InProcessCompositorSession InProcessCompositorSession;
80 typedef layers::UiCompositorControllerChild UiCompositorControllerChild;
82 public:
83 static void Initialize();
84 static void Shutdown();
85 static GPUProcessManager* Get();
87 ~GPUProcessManager();
89 // If not using a GPU process, launch a new GPU process asynchronously.
90 bool LaunchGPUProcess();
91 bool IsGPUProcessLaunching();
93 // Ensure that GPU-bound methods can be used. If no GPU process is being
94 // used, or one is launched and ready, this function returns immediately.
95 // Otherwise it blocks until the GPU process has finished launching.
96 // If the GPU process is enabled but has not yet been launched then this will
97 // launch the process. If that is not desired then check that return value of
98 // Process() is non-null before calling.
99 bool EnsureGPUReady();
101 already_AddRefed<CompositorSession> CreateTopLevelCompositor(
102 nsBaseWidget* aWidget, WebRenderLayerManager* aLayerManager,
103 CSSToLayoutDeviceScale aScale, const CompositorOptions& aOptions,
104 bool aUseExternalSurfaceSize, const gfx::IntSize& aSurfaceSize,
105 uint64_t aInnerWindowId, bool* aRetry);
107 bool CreateContentBridges(
108 base::ProcessId aOtherProcess,
109 mozilla::ipc::Endpoint<PCompositorManagerChild>* aOutCompositor,
110 mozilla::ipc::Endpoint<PImageBridgeChild>* aOutImageBridge,
111 mozilla::ipc::Endpoint<PVRManagerChild>* aOutVRBridge,
112 mozilla::ipc::Endpoint<PRemoteDecoderManagerChild>* aOutVideoManager,
113 nsTArray<uint32_t>* aNamespaces);
115 // Initialize GPU process with consuming end of PVideoBridge.
116 void InitVideoBridge(
117 mozilla::ipc::Endpoint<PVideoBridgeParent>&& aVideoBridge,
118 layers::VideoBridgeSource aSource);
120 // Maps the layer tree and process together so that aOwningPID is allowed
121 // to access aLayersId across process.
122 void MapLayerTreeId(LayersId aLayersId, base::ProcessId aOwningId);
124 // Release compositor-thread resources referred to by |aID|.
126 // Must run on the content main thread.
127 void UnmapLayerTreeId(LayersId aLayersId, base::ProcessId aOwningId);
129 // Checks to see if aLayersId and aRequestingPID have been mapped by
130 // MapLayerTreeId
131 bool IsLayerTreeIdMapped(LayersId aLayersId, base::ProcessId aRequestingId);
133 // Allocate an ID that can be used to refer to a layer tree and
134 // associated resources that live only on the compositor thread.
136 // Must run on the browser main thread.
137 LayersId AllocateLayerTreeId();
139 // Allocate an ID that can be used as Namespace and
140 // Must run on the browser main thread.
141 uint32_t AllocateNamespace();
143 // Allocate a layers ID and connect it to a compositor. If the compositor is
144 // null, the connect operation will not be performed, but an ID will still be
145 // allocated. This must be called from the browser main thread.
147 // Note that a layer tree id is always allocated, even if this returns false.
148 bool AllocateAndConnectLayerTreeId(PCompositorBridgeChild* aCompositorBridge,
149 base::ProcessId aOtherPid,
150 LayersId* aOutLayersId,
151 CompositorOptions* aOutCompositorOptions);
153 // Destroy and recreate all of the compositors
154 void ResetCompositors();
156 // Record the device reset in telemetry / annotate the crash report.
157 static void RecordDeviceReset(DeviceResetReason aReason);
159 void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
160 void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;
161 void SimulateDeviceReset();
162 void DisableWebRender(wr::WebRenderError aError, const nsCString& aMsg);
163 void NotifyWebRenderError(wr::WebRenderError aError);
164 void OnInProcessDeviceReset(bool aTrackThreshold);
165 void OnRemoteProcessDeviceReset(GPUProcessHost* aHost) override;
166 void OnProcessDeclaredStable() override;
167 void NotifyListenersOnCompositeDeviceReset();
169 // Notify the GPUProcessManager that a top-level PGPU protocol has been
170 // terminated. This may be called from any thread.
171 void NotifyRemoteActorDestroyed(const uint64_t& aProcessToken);
173 void AddListener(GPUProcessListener* aListener);
174 void RemoveListener(GPUProcessListener* aListener);
176 // Send a message to the GPU process observer service to broadcast. Returns
177 // true if the message was sent, false if not.
178 bool NotifyGpuObservers(const char* aTopic);
180 // Kills the GPU process. Used for tests and diagnostics
181 void KillProcess();
183 // Causes the GPU process to crash. Used for tests and diagnostics
184 void CrashProcess();
186 // Returns -1 if there is no GPU process, or the platform pid for it.
187 base::ProcessId GPUProcessPid();
189 // If a GPU process is present, create a MemoryReportingProcess object.
190 // Otherwise, return null.
191 RefPtr<MemoryReportingProcess> GetProcessMemoryReporter();
193 // Returns access to the PGPU protocol if a GPU process is present.
194 GPUChild* GetGPUChild() { return mGPUChild; }
196 // Returns whether or not a GPU process was ever launched.
197 bool AttemptedGPUProcess() const { return mTotalProcessAttempts > 0; }
199 // Returns the process host
200 GPUProcessHost* Process() { return mProcess; }
203 * ** Test-only Method **
205 * Trigger GPU-process test metric instrumentation.
207 RefPtr<PGPUChild::TestTriggerMetricsPromise> TestTriggerMetrics();
209 private:
210 // Called from our xpcom-shutdown observer.
211 void OnXPCOMShutdown();
212 void OnPreferenceChange(const char16_t* aData);
214 bool CreateContentCompositorManager(
215 base::ProcessId aOtherProcess,
216 mozilla::ipc::Endpoint<PCompositorManagerChild>* aOutEndpoint);
217 bool CreateContentImageBridge(
218 base::ProcessId aOtherProcess,
219 mozilla::ipc::Endpoint<PImageBridgeChild>* aOutEndpoint);
220 bool CreateContentVRManager(
221 base::ProcessId aOtherProcess,
222 mozilla::ipc::Endpoint<PVRManagerChild>* aOutEndpoint);
223 void CreateContentRemoteDecoderManager(
224 base::ProcessId aOtherProcess,
225 mozilla::ipc::Endpoint<PRemoteDecoderManagerChild>* aOutEndPoint);
227 // Called from RemoteCompositorSession. We track remote sessions so we can
228 // notify their owning widgets that the session must be restarted.
229 void RegisterRemoteProcessSession(RemoteCompositorSession* aSession);
230 void UnregisterRemoteProcessSession(RemoteCompositorSession* aSession);
232 // Called from InProcessCompositorSession. We track in process sessino so we
233 // can notify their owning widgets that the session must be restarted
234 void RegisterInProcessSession(InProcessCompositorSession* aSession);
235 void UnregisterInProcessSession(InProcessCompositorSession* aSession);
237 void DestroyRemoteCompositorSessions();
238 void DestroyInProcessCompositorSessions();
240 // Returns true if we crossed the threshold such that we should disable
241 // acceleration.
242 bool OnDeviceReset(bool aTrackThreshold);
244 // Returns true if WebRender was enabled and is now disabled.
245 bool DisableWebRenderConfig(wr::WebRenderError aError, const nsCString& aMsg);
247 void FallbackToSoftware(const char* aMessage);
249 private:
250 GPUProcessManager();
252 // Permanently disable the GPU process and record a message why.
253 void DisableGPUProcess(const char* aMessage);
255 // May permanently disable the GPU process and record a message why. May
256 // return false if the fallback process decided we should retry the GPU
257 // process, but only if aAllowRestart is also true.
258 bool MaybeDisableGPUProcess(const char* aMessage, bool aAllowRestart);
260 bool FallbackFromAcceleration(wr::WebRenderError aError,
261 const nsCString& aMsg);
263 void ResetProcessStable();
265 // Returns true if the composting pocess is currently considered to be stable.
266 bool IsProcessStable(const TimeStamp& aNow);
268 // Shutdown the GPU process.
269 void CleanShutdown();
270 // Destroy the process and clean up resources.
271 // Setting aUnexpectedShutdown = true indicates that this is being called to
272 // clean up resources in response to an unexpected shutdown having been
273 // detected.
274 void DestroyProcess(bool aUnexpectedShutdown = false);
276 void HandleProcessLost();
277 // Reinitialize rendering following a GPU process loss.
278 void ReinitializeRendering();
280 void EnsureVsyncIOThread();
281 void ShutdownVsyncIOThread();
283 void EnsureProtocolsReady();
284 void EnsureCompositorManagerChild();
285 void EnsureImageBridgeChild();
286 void EnsureVRManager();
288 #if defined(MOZ_WIDGET_ANDROID)
289 already_AddRefed<UiCompositorControllerChild> CreateUiCompositorController(
290 nsBaseWidget* aWidget, const LayersId aId);
291 #endif // defined(MOZ_WIDGET_ANDROID)
293 RefPtr<CompositorSession> CreateRemoteSession(
294 nsBaseWidget* aWidget, WebRenderLayerManager* aLayerManager,
295 const LayersId& aRootLayerTreeId, CSSToLayoutDeviceScale aScale,
296 const CompositorOptions& aOptions, bool aUseExternalSurfaceSize,
297 const gfx::IntSize& aSurfaceSize, uint64_t aInnerWindowId);
299 DISALLOW_COPY_AND_ASSIGN(GPUProcessManager);
301 class Observer final : public nsIObserver {
302 public:
303 NS_DECL_ISUPPORTS
304 NS_DECL_NSIOBSERVER
305 explicit Observer(GPUProcessManager* aManager);
307 protected:
308 virtual ~Observer() = default;
310 GPUProcessManager* mManager;
312 friend class Observer;
314 private:
315 bool mDecodeVideoOnGpuProcess = true;
317 RefPtr<Observer> mObserver;
318 mozilla::ipc::TaskFactory<GPUProcessManager> mTaskFactory;
319 RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
320 uint32_t mNextNamespace;
321 uint32_t mIdNamespace;
322 uint32_t mResourceId;
324 uint32_t mUnstableProcessAttempts;
325 uint32_t mTotalProcessAttempts;
326 TimeStamp mProcessAttemptLastTime;
328 nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;
329 nsTArray<RefPtr<InProcessCompositorSession>> mInProcessSessions;
330 nsTArray<GPUProcessListener*> mListeners;
332 uint32_t mDeviceResetCount;
333 TimeStamp mDeviceResetLastTime;
335 // Keeps track of whether not the application is in the foreground on android.
336 bool mAppInForeground;
338 // Fields that are associated with the current GPU process.
339 GPUProcessHost* mProcess;
340 uint64_t mProcessToken;
341 bool mProcessStable;
342 Maybe<wr::WebRenderError> mLastError;
343 Maybe<nsCString> mLastErrorMsg;
344 GPUChild* mGPUChild;
345 RefPtr<VsyncBridgeChild> mVsyncBridge;
346 // Collects any pref changes that occur during process launch (after
347 // the initial map is passed in command-line arguments) to be sent
348 // when the process can receive IPC messages.
349 nsTArray<mozilla::dom::Pref> mQueuedPrefs;
352 } // namespace gfx
353 } // namespace mozilla
355 #endif // _include_mozilla_gfx_ipc_GPUProcessManager_h_