summaryrefslogtreecommitdiffstats
path: root/gfx/ipc/GPUProcessManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/ipc/GPUProcessManager.h')
-rw-r--r--gfx/ipc/GPUProcessManager.h234
1 files changed, 234 insertions, 0 deletions
diff --git a/gfx/ipc/GPUProcessManager.h b/gfx/ipc/GPUProcessManager.h
new file mode 100644
index 000000000..84ed03609
--- /dev/null
+++ b/gfx/ipc/GPUProcessManager.h
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=99: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef _include_mozilla_gfx_ipc_GPUProcessManager_h_
+#define _include_mozilla_gfx_ipc_GPUProcessManager_h_
+
+#include "base/basictypes.h"
+#include "base/process.h"
+#include "Units.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/dom/ipc/IdType.h"
+#include "mozilla/gfx/GPUProcessHost.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/ipc/ProtocolUtils.h"
+#include "mozilla/ipc/TaskFactory.h"
+#include "mozilla/ipc/Transport.h"
+#include "nsIObserverService.h"
+#include "nsThreadUtils.h"
+class nsBaseWidget;
+
+
+namespace mozilla {
+namespace layers {
+class IAPZCTreeManager;
+class CompositorSession;
+class CompositorUpdateObserver;
+class PCompositorBridgeChild;
+class PImageBridgeChild;
+class RemoteCompositorSession;
+} // namespace layers
+namespace widget {
+class CompositorWidget;
+} // namespace widget
+namespace dom {
+class ContentParent;
+class TabParent;
+class PVideoDecoderManagerChild;
+} // namespace dom
+namespace ipc {
+class GeckoChildProcessHost;
+} // namespace ipc
+namespace gfx {
+
+class GPUChild;
+class GPUProcessListener;
+class PVRManagerChild;
+class VsyncBridgeChild;
+class VsyncIOThreadHolder;
+
+// The GPUProcessManager is a singleton responsible for creating GPU-bound
+// objects that may live in another process. Currently, it provides access
+// to the compositor via CompositorBridgeParent.
+class GPUProcessManager final : public GPUProcessHost::Listener
+{
+ friend class layers::RemoteCompositorSession;
+
+ typedef layers::CompositorSession CompositorSession;
+ typedef layers::CompositorUpdateObserver CompositorUpdateObserver;
+ typedef layers::IAPZCTreeManager IAPZCTreeManager;
+ typedef layers::LayerManager LayerManager;
+ typedef layers::PCompositorBridgeChild PCompositorBridgeChild;
+ typedef layers::PImageBridgeChild PImageBridgeChild;
+ typedef layers::RemoteCompositorSession RemoteCompositorSession;
+
+public:
+ static void Initialize();
+ static void Shutdown();
+ static GPUProcessManager* Get();
+
+ ~GPUProcessManager();
+
+ // If not using a GPU process, launch a new GPU process asynchronously.
+ void LaunchGPUProcess();
+
+ // Ensure that GPU-bound methods can be used. If no GPU process is being
+ // used, or one is launched and ready, this function returns immediately.
+ // Otherwise it blocks until the GPU process has finished launching.
+ void EnsureGPUReady();
+
+ RefPtr<CompositorSession> CreateTopLevelCompositor(
+ nsBaseWidget* aWidget,
+ LayerManager* aLayerManager,
+ CSSToLayoutDeviceScale aScale,
+ bool aUseAPZ,
+ bool aUseExternalSurfaceSize,
+ const gfx::IntSize& aSurfaceSize);
+
+ bool CreateContentBridges(
+ base::ProcessId aOtherProcess,
+ ipc::Endpoint<PCompositorBridgeChild>* aOutCompositor,
+ ipc::Endpoint<PImageBridgeChild>* aOutImageBridge,
+ ipc::Endpoint<PVRManagerChild>* aOutVRBridge,
+ ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutVideoManager);
+
+ // This returns a reference to the APZCTreeManager to which
+ // pan/zoom-related events can be sent.
+ already_AddRefed<IAPZCTreeManager> GetAPZCTreeManagerForLayers(uint64_t aLayersId);
+
+ // Maps the layer tree and process together so that aOwningPID is allowed
+ // to access aLayersId across process.
+ void MapLayerTreeId(uint64_t aLayersId, base::ProcessId aOwningId);
+
+ // Release compositor-thread resources referred to by |aID|.
+ //
+ // Must run on the content main thread.
+ void UnmapLayerTreeId(uint64_t aLayersId, base::ProcessId aOwningId);
+
+ // Checks to see if aLayersId and aRequestingPID have been mapped by MapLayerTreeId
+ bool IsLayerTreeIdMapped(uint64_t aLayersId, base::ProcessId aRequestingId);
+
+ // Allocate an ID that can be used to refer to a layer tree and
+ // associated resources that live only on the compositor thread.
+ //
+ // Must run on the content main thread.
+ uint64_t AllocateLayerTreeId();
+
+
+ void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
+ void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;
+ void OnProcessDeviceReset(GPUProcessHost* aHost) override;
+
+ // Notify the GPUProcessManager that a top-level PGPU protocol has been
+ // terminated. This may be called from any thread.
+ void NotifyRemoteActorDestroyed(const uint64_t& aProcessToken);
+
+ void AddListener(GPUProcessListener* aListener);
+ void RemoveListener(GPUProcessListener* aListener);
+
+ // Send a message to the GPU process observer service to broadcast. Returns
+ // true if the message was sent, false if not.
+ bool NotifyGpuObservers(const char* aTopic);
+
+ // Used for tests and diagnostics
+ void KillProcess();
+
+ // Returns -1 if there is no GPU process, or the platform pid for it.
+ base::ProcessId GPUProcessPid();
+
+ // Returns access to the PGPU protocol if a GPU process is present.
+ GPUChild* GetGPUChild() {
+ return mGPUChild;
+ }
+
+ // Returns whether or not a GPU process was ever launched.
+ bool AttemptedGPUProcess() const {
+ return mNumProcessAttempts > 0;
+ }
+
+private:
+ // Called from our xpcom-shutdown observer.
+ void OnXPCOMShutdown();
+
+ bool CreateContentCompositorBridge(base::ProcessId aOtherProcess,
+ ipc::Endpoint<PCompositorBridgeChild>* aOutEndpoint);
+ bool CreateContentImageBridge(base::ProcessId aOtherProcess,
+ ipc::Endpoint<PImageBridgeChild>* aOutEndpoint);
+ bool CreateContentVRManager(base::ProcessId aOtherProcess,
+ ipc::Endpoint<PVRManagerChild>* aOutEndpoint);
+ void CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
+ ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndPoint);
+
+ // Called from RemoteCompositorSession. We track remote sessions so we can
+ // notify their owning widgets that the session must be restarted.
+ void RegisterSession(RemoteCompositorSession* aSession);
+ void UnregisterSession(RemoteCompositorSession* aSession);
+
+private:
+ GPUProcessManager();
+
+ // Permanently disable the GPU process and record a message why.
+ void DisableGPUProcess(const char* aMessage);
+
+ // Shutdown the GPU process.
+ void CleanShutdown();
+ void DestroyProcess();
+
+ void HandleProcessLost();
+
+ void EnsureVsyncIOThread();
+ void ShutdownVsyncIOThread();
+
+ void EnsureImageBridgeChild();
+ void EnsureVRManager();
+
+ RefPtr<CompositorSession> CreateRemoteSession(
+ nsBaseWidget* aWidget,
+ LayerManager* aLayerManager,
+ const uint64_t& aRootLayerTreeId,
+ CSSToLayoutDeviceScale aScale,
+ bool aUseAPZ,
+ bool aUseExternalSurfaceSize,
+ const gfx::IntSize& aSurfaceSize);
+
+ DISALLOW_COPY_AND_ASSIGN(GPUProcessManager);
+
+ class Observer final : public nsIObserver {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+ explicit Observer(GPUProcessManager* aManager);
+
+ protected:
+ ~Observer() {}
+
+ GPUProcessManager* mManager;
+ };
+ friend class Observer;
+
+private:
+ RefPtr<Observer> mObserver;
+ ipc::TaskFactory<GPUProcessManager> mTaskFactory;
+ RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
+ uint64_t mNextLayerTreeId;
+ uint32_t mNumProcessAttempts;
+
+ nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;
+ nsTArray<GPUProcessListener*> mListeners;
+
+ uint32_t mDeviceResetCount;
+ TimeStamp mDeviceResetLastTime;
+
+ // Fields that are associated with the current GPU process.
+ GPUProcessHost* mProcess;
+ MOZ_INIT_OUTSIDE_CTOR uint64_t mProcessToken;
+ GPUChild* mGPUChild;
+ RefPtr<VsyncBridgeChild> mVsyncBridge;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // _include_mozilla_gfx_ipc_GPUProcessManager_h_