Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/gfx/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
0
  GPUChild* GetGPUChild() {
180
0
    return mGPUChild;
181
0
  }
182
183
  // Returns whether or not a GPU process was ever launched.
184
0
  bool AttemptedGPUProcess() const {
185
0
    return mNumProcessAttempts > 0;
186
0
  }
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
    ~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_