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