/src/mozilla-central/gfx/ipc/GPUProcessManager.h
Line | Count | Source (jump to first uncovered line) |
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_ |
8 | | |
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/Point.h" |
16 | | #include "mozilla/ipc/ProtocolUtils.h" |
17 | | #include "mozilla/ipc/TaskFactory.h" |
18 | | #include "mozilla/ipc/Transport.h" |
19 | | #include "mozilla/layers/LayersTypes.h" |
20 | | #include "mozilla/webrender/WebRenderTypes.h" |
21 | | #include "nsIObserverService.h" |
22 | | #include "nsThreadUtils.h" |
23 | | class nsBaseWidget; |
24 | | |
25 | | |
26 | | namespace mozilla { |
27 | | class MemoryReportingProcess; |
28 | | namespace layers { |
29 | | class IAPZCTreeManager; |
30 | | class CompositorOptions; |
31 | | class CompositorSession; |
32 | | class CompositorUpdateObserver; |
33 | | class PCompositorBridgeChild; |
34 | | class PCompositorManagerChild; |
35 | | class PImageBridgeChild; |
36 | | class RemoteCompositorSession; |
37 | | class InProcessCompositorSession; |
38 | | class UiCompositorControllerChild; |
39 | | } // namespace layers |
40 | | namespace widget { |
41 | | class CompositorWidget; |
42 | | } // namespace widget |
43 | | namespace dom { |
44 | | class ContentParent; |
45 | | class TabParent; |
46 | | class PVideoDecoderManagerChild; |
47 | | } // namespace dom |
48 | | namespace ipc { |
49 | | class GeckoChildProcessHost; |
50 | | } // namespace ipc |
51 | | namespace gfx { |
52 | | |
53 | | class GPUChild; |
54 | | class GPUProcessListener; |
55 | | class PVRManagerChild; |
56 | | class VsyncBridgeChild; |
57 | | class VsyncIOThreadHolder; |
58 | | |
59 | | // The GPUProcessManager is a singleton responsible for creating GPU-bound |
60 | | // objects that may live in another process. Currently, it provides access |
61 | | // to the compositor via CompositorBridgeParent. |
62 | | class GPUProcessManager final : public GPUProcessHost::Listener |
63 | | { |
64 | | friend class layers::RemoteCompositorSession; |
65 | | friend class layers::InProcessCompositorSession; |
66 | | |
67 | | typedef layers::CompositorOptions CompositorOptions; |
68 | | typedef layers::CompositorSession CompositorSession; |
69 | | typedef layers::CompositorUpdateObserver CompositorUpdateObserver; |
70 | | typedef layers::IAPZCTreeManager IAPZCTreeManager; |
71 | | typedef layers::LayerManager LayerManager; |
72 | | typedef layers::LayersId LayersId; |
73 | | typedef layers::PCompositorBridgeChild PCompositorBridgeChild; |
74 | | typedef layers::PCompositorManagerChild PCompositorManagerChild; |
75 | | typedef layers::PImageBridgeChild PImageBridgeChild; |
76 | | typedef layers::RemoteCompositorSession RemoteCompositorSession; |
77 | | typedef layers::InProcessCompositorSession InProcessCompositorSession; |
78 | | typedef layers::UiCompositorControllerChild UiCompositorControllerChild; |
79 | | |
80 | | public: |
81 | | static void Initialize(); |
82 | | static void Shutdown(); |
83 | | static GPUProcessManager* Get(); |
84 | | |
85 | | ~GPUProcessManager(); |
86 | | |
87 | | // If not using a GPU process, launch a new GPU process asynchronously. |
88 | | void LaunchGPUProcess(); |
89 | | |
90 | | // Ensure that GPU-bound methods can be used. If no GPU process is being |
91 | | // used, or one is launched and ready, this function returns immediately. |
92 | | // Otherwise it blocks until the GPU process has finished launching. |
93 | | bool EnsureGPUReady(); |
94 | | |
95 | | already_AddRefed<CompositorSession> CreateTopLevelCompositor( |
96 | | nsBaseWidget* aWidget, |
97 | | LayerManager* aLayerManager, |
98 | | CSSToLayoutDeviceScale aScale, |
99 | | const CompositorOptions& aOptions, |
100 | | bool aUseExternalSurfaceSize, |
101 | | const gfx::IntSize& aSurfaceSize, |
102 | | bool* aRetry); |
103 | | |
104 | | bool CreateContentBridges( |
105 | | base::ProcessId aOtherProcess, |
106 | | mozilla::ipc::Endpoint<PCompositorManagerChild>* aOutCompositor, |
107 | | mozilla::ipc::Endpoint<PImageBridgeChild>* aOutImageBridge, |
108 | | mozilla::ipc::Endpoint<PVRManagerChild>* aOutVRBridge, |
109 | | mozilla::ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutVideoManager, |
110 | | nsTArray<uint32_t>* aNamespaces); |
111 | | |
112 | | // Maps the layer tree and process together so that aOwningPID is allowed |
113 | | // to access aLayersId across process. |
114 | | void MapLayerTreeId(LayersId aLayersId, base::ProcessId aOwningId); |
115 | | |
116 | | // Release compositor-thread resources referred to by |aID|. |
117 | | // |
118 | | // Must run on the content main thread. |
119 | | void UnmapLayerTreeId(LayersId aLayersId, base::ProcessId aOwningId); |
120 | | |
121 | | // Checks to see if aLayersId and aRequestingPID have been mapped by MapLayerTreeId |
122 | | bool IsLayerTreeIdMapped(LayersId aLayersId, base::ProcessId aRequestingId); |
123 | | |
124 | | // Allocate an ID that can be used to refer to a layer tree and |
125 | | // associated resources that live only on the compositor thread. |
126 | | // |
127 | | // Must run on the browser main thread. |
128 | | LayersId AllocateLayerTreeId(); |
129 | | |
130 | | // Allocate an ID that can be used as Namespace and |
131 | | // Must run on the browser main thread. |
132 | | uint32_t AllocateNamespace(); |
133 | | |
134 | | // Allocate a layers ID and connect it to a compositor. If the compositor is null, |
135 | | // the connect operation will not be performed, but an ID will still be allocated. |
136 | | // This must be called from the browser main thread. |
137 | | // |
138 | | // Note that a layer tree id is always allocated, even if this returns false. |
139 | | bool AllocateAndConnectLayerTreeId( |
140 | | PCompositorBridgeChild* aCompositorBridge, |
141 | | base::ProcessId aOtherPid, |
142 | | LayersId* aOutLayersId, |
143 | | CompositorOptions* aOutCompositorOptions); |
144 | | |
145 | | // Destroy and recreate all of the compositors |
146 | | void ResetCompositors(); |
147 | | |
148 | | void OnProcessLaunchComplete(GPUProcessHost* aHost) override; |
149 | | void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override; |
150 | | void SimulateDeviceReset(); |
151 | | void DisableWebRender(wr::WebRenderError aError); |
152 | | void NotifyWebRenderError(wr::WebRenderError aError); |
153 | | void OnInProcessDeviceReset(); |
154 | | void OnRemoteProcessDeviceReset(GPUProcessHost* aHost) override; |
155 | | void NotifyListenersOnCompositeDeviceReset(); |
156 | | |
157 | | // Notify the GPUProcessManager that a top-level PGPU protocol has been |
158 | | // terminated. This may be called from any thread. |
159 | | void NotifyRemoteActorDestroyed(const uint64_t& aProcessToken); |
160 | | |
161 | | void AddListener(GPUProcessListener* aListener); |
162 | | void RemoveListener(GPUProcessListener* aListener); |
163 | | |
164 | | // Send a message to the GPU process observer service to broadcast. Returns |
165 | | // true if the message was sent, false if not. |
166 | | bool NotifyGpuObservers(const char* aTopic); |
167 | | |
168 | | // Used for tests and diagnostics |
169 | | void KillProcess(); |
170 | | |
171 | | // Returns -1 if there is no GPU process, or the platform pid for it. |
172 | | base::ProcessId GPUProcessPid(); |
173 | | |
174 | | // If a GPU process is present, create a MemoryReportingProcess object. |
175 | | // Otherwise, return null. |
176 | | RefPtr<MemoryReportingProcess> GetProcessMemoryReporter(); |
177 | | |
178 | | // Returns access to the PGPU protocol if a GPU process is present. |
179 | | GPUChild* GetGPUChild() { |
180 | | return mGPUChild; |
181 | | } |
182 | | |
183 | | // Returns whether or not a GPU process was ever launched. |
184 | | bool AttemptedGPUProcess() const { |
185 | | return mNumProcessAttempts > 0; |
186 | | } |
187 | | |
188 | | private: |
189 | | // Called from our xpcom-shutdown observer. |
190 | | void OnXPCOMShutdown(); |
191 | | |
192 | | bool CreateContentCompositorManager(base::ProcessId aOtherProcess, |
193 | | mozilla::ipc::Endpoint<PCompositorManagerChild>* aOutEndpoint); |
194 | | bool CreateContentImageBridge(base::ProcessId aOtherProcess, |
195 | | mozilla::ipc::Endpoint<PImageBridgeChild>* aOutEndpoint); |
196 | | bool CreateContentVRManager(base::ProcessId aOtherProcess, |
197 | | mozilla::ipc::Endpoint<PVRManagerChild>* aOutEndpoint); |
198 | | void CreateContentVideoDecoderManager(base::ProcessId aOtherProcess, |
199 | | mozilla::ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndPoint); |
200 | | |
201 | | // Called from RemoteCompositorSession. We track remote sessions so we can |
202 | | // notify their owning widgets that the session must be restarted. |
203 | | void RegisterRemoteProcessSession(RemoteCompositorSession* aSession); |
204 | | void UnregisterRemoteProcessSession(RemoteCompositorSession* aSession); |
205 | | |
206 | | // Called from InProcessCompositorSession. We track in process sessino so we can |
207 | | // notify their owning widgets that the session must be restarted |
208 | | void RegisterInProcessSession(InProcessCompositorSession* aSession); |
209 | | void UnregisterInProcessSession(InProcessCompositorSession* aSession); |
210 | | |
211 | | void RebuildRemoteSessions(); |
212 | | void RebuildInProcessSessions(); |
213 | | |
214 | | private: |
215 | | GPUProcessManager(); |
216 | | |
217 | | // Permanently disable the GPU process and record a message why. |
218 | | void DisableGPUProcess(const char* aMessage); |
219 | | |
220 | | // Shutdown the GPU process. |
221 | | void CleanShutdown(); |
222 | | void DestroyProcess(); |
223 | | |
224 | | void HandleProcessLost(); |
225 | | |
226 | | void EnsureVsyncIOThread(); |
227 | | void ShutdownVsyncIOThread(); |
228 | | |
229 | | void EnsureProtocolsReady(); |
230 | | void EnsureCompositorManagerChild(); |
231 | | void EnsureImageBridgeChild(); |
232 | | void EnsureVRManager(); |
233 | | |
234 | | #if defined(MOZ_WIDGET_ANDROID) |
235 | | already_AddRefed<UiCompositorControllerChild> CreateUiCompositorController(nsBaseWidget* aWidget, const LayersId aId); |
236 | | #endif // defined(MOZ_WIDGET_ANDROID) |
237 | | |
238 | | RefPtr<CompositorSession> CreateRemoteSession( |
239 | | nsBaseWidget* aWidget, |
240 | | LayerManager* aLayerManager, |
241 | | const LayersId& aRootLayerTreeId, |
242 | | CSSToLayoutDeviceScale aScale, |
243 | | const CompositorOptions& aOptions, |
244 | | bool aUseExternalSurfaceSize, |
245 | | const gfx::IntSize& aSurfaceSize); |
246 | | |
247 | | DISALLOW_COPY_AND_ASSIGN(GPUProcessManager); |
248 | | |
249 | | class Observer final : public nsIObserver { |
250 | | public: |
251 | | NS_DECL_ISUPPORTS |
252 | | NS_DECL_NSIOBSERVER |
253 | | explicit Observer(GPUProcessManager* aManager); |
254 | | |
255 | | protected: |
256 | 0 | ~Observer() {} |
257 | | |
258 | | GPUProcessManager* mManager; |
259 | | }; |
260 | | friend class Observer; |
261 | | |
262 | | private: |
263 | | bool mDecodeVideoOnGpuProcess = true; |
264 | | |
265 | | RefPtr<Observer> mObserver; |
266 | | mozilla::ipc::TaskFactory<GPUProcessManager> mTaskFactory; |
267 | | RefPtr<VsyncIOThreadHolder> mVsyncIOThread; |
268 | | uint32_t mNextNamespace; |
269 | | uint32_t mIdNamespace; |
270 | | uint32_t mResourceId; |
271 | | uint32_t mNumProcessAttempts; |
272 | | |
273 | | nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions; |
274 | | nsTArray<RefPtr<InProcessCompositorSession>> mInProcessSessions; |
275 | | nsTArray<GPUProcessListener*> mListeners; |
276 | | |
277 | | uint32_t mDeviceResetCount; |
278 | | TimeStamp mDeviceResetLastTime; |
279 | | |
280 | | // Fields that are associated with the current GPU process. |
281 | | GPUProcessHost* mProcess; |
282 | | uint64_t mProcessToken; |
283 | | GPUChild* mGPUChild; |
284 | | RefPtr<VsyncBridgeChild> mVsyncBridge; |
285 | | }; |
286 | | |
287 | | } // namespace gfx |
288 | | } // namespace mozilla |
289 | | |
290 | | #endif // _include_mozilla_gfx_ipc_GPUProcessManager_h_ |