2017-10-28 02:10:06 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2016-05-23 10:27:01 +03:00
|
|
|
/* 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"
|
2016-05-23 10:28:51 +03:00
|
|
|
#include "base/process.h"
|
2016-05-23 10:27:01 +03:00
|
|
|
#include "Units.h"
|
2016-07-19 21:56:06 +03:00
|
|
|
#include "mozilla/UniquePtr.h"
|
2016-05-23 10:28:51 +03:00
|
|
|
#include "mozilla/dom/ipc/IdType.h"
|
2016-06-11 05:27:24 +03:00
|
|
|
#include "mozilla/gfx/GPUProcessHost.h"
|
2016-06-28 03:05:34 +03:00
|
|
|
#include "mozilla/gfx/Point.h"
|
2016-07-18 07:24:28 +03:00
|
|
|
#include "mozilla/ipc/ProtocolUtils.h"
|
2016-07-18 07:24:28 +03:00
|
|
|
#include "mozilla/ipc/TaskFactory.h"
|
2016-05-23 10:28:51 +03:00
|
|
|
#include "mozilla/ipc/Transport.h"
|
2017-08-30 03:10:22 +03:00
|
|
|
#include "mozilla/webrender/WebRenderTypes.h"
|
2016-06-11 05:27:24 +03:00
|
|
|
#include "nsIObserverService.h"
|
2016-07-19 21:56:07 +03:00
|
|
|
#include "nsThreadUtils.h"
|
|
|
|
class nsBaseWidget;
|
2016-05-23 10:27:01 +03:00
|
|
|
|
2016-07-18 07:24:28 +03:00
|
|
|
|
2016-05-23 10:27:01 +03:00
|
|
|
namespace mozilla {
|
2017-01-27 03:35:54 +03:00
|
|
|
class MemoryReportingProcess;
|
2016-05-23 10:27:01 +03:00
|
|
|
namespace layers {
|
2016-07-20 14:37:00 +03:00
|
|
|
class IAPZCTreeManager;
|
2017-01-13 01:29:41 +03:00
|
|
|
class CompositorOptions;
|
2016-05-23 10:27:01 +03:00
|
|
|
class CompositorSession;
|
2016-05-23 10:28:03 +03:00
|
|
|
class CompositorUpdateObserver;
|
2016-07-18 07:24:28 +03:00
|
|
|
class PCompositorBridgeChild;
|
2017-06-14 18:39:59 +03:00
|
|
|
class PCompositorManagerChild;
|
2016-07-20 10:18:30 +03:00
|
|
|
class PImageBridgeChild;
|
2016-09-20 11:16:03 +03:00
|
|
|
class RemoteCompositorSession;
|
2017-06-15 21:34:00 +03:00
|
|
|
class InProcessCompositorSession;
|
2017-04-06 01:42:50 +03:00
|
|
|
class UiCompositorControllerChild;
|
2016-05-23 10:27:01 +03:00
|
|
|
} // namespace layers
|
|
|
|
namespace widget {
|
2016-07-01 11:15:16 +03:00
|
|
|
class CompositorWidget;
|
2016-05-23 10:27:01 +03:00
|
|
|
} // namespace widget
|
2016-05-23 10:28:51 +03:00
|
|
|
namespace dom {
|
|
|
|
class ContentParent;
|
|
|
|
class TabParent;
|
2016-09-21 12:25:33 +03:00
|
|
|
class PVideoDecoderManagerChild;
|
2016-05-23 10:28:51 +03:00
|
|
|
} // namespace dom
|
|
|
|
namespace ipc {
|
|
|
|
class GeckoChildProcessHost;
|
|
|
|
} // namespace ipc
|
2016-05-23 10:27:01 +03:00
|
|
|
namespace gfx {
|
|
|
|
|
2016-06-11 05:27:24 +03:00
|
|
|
class GPUChild;
|
2016-09-20 11:18:50 +03:00
|
|
|
class GPUProcessListener;
|
2016-09-20 11:16:03 +03:00
|
|
|
class PVRManagerChild;
|
2016-07-19 21:56:06 +03:00
|
|
|
class VsyncBridgeChild;
|
|
|
|
class VsyncIOThreadHolder;
|
2016-06-11 05:27:24 +03:00
|
|
|
|
2016-05-23 10:27:01 +03:00
|
|
|
// 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.
|
2016-06-11 05:27:24 +03:00
|
|
|
class GPUProcessManager final : public GPUProcessHost::Listener
|
2016-05-23 10:27:01 +03:00
|
|
|
{
|
2016-09-20 11:16:03 +03:00
|
|
|
friend class layers::RemoteCompositorSession;
|
2017-06-15 21:34:00 +03:00
|
|
|
friend class layers::InProcessCompositorSession;
|
2016-09-20 11:16:03 +03:00
|
|
|
|
2017-01-13 01:29:41 +03:00
|
|
|
typedef layers::CompositorOptions CompositorOptions;
|
2016-07-18 07:24:28 +03:00
|
|
|
typedef layers::CompositorSession CompositorSession;
|
2016-05-23 10:28:03 +03:00
|
|
|
typedef layers::CompositorUpdateObserver CompositorUpdateObserver;
|
2016-11-08 18:42:19 +03:00
|
|
|
typedef layers::IAPZCTreeManager IAPZCTreeManager;
|
|
|
|
typedef layers::LayerManager LayerManager;
|
2016-07-18 07:24:28 +03:00
|
|
|
typedef layers::PCompositorBridgeChild PCompositorBridgeChild;
|
2017-06-14 18:39:59 +03:00
|
|
|
typedef layers::PCompositorManagerChild PCompositorManagerChild;
|
2016-07-20 10:18:30 +03:00
|
|
|
typedef layers::PImageBridgeChild PImageBridgeChild;
|
2016-09-20 11:16:03 +03:00
|
|
|
typedef layers::RemoteCompositorSession RemoteCompositorSession;
|
2017-06-15 21:34:00 +03:00
|
|
|
typedef layers::InProcessCompositorSession InProcessCompositorSession;
|
2017-04-06 01:42:50 +03:00
|
|
|
typedef layers::UiCompositorControllerChild UiCompositorControllerChild;
|
2016-05-23 10:27:51 +03:00
|
|
|
|
2016-05-23 10:27:01 +03:00
|
|
|
public:
|
|
|
|
static void Initialize();
|
|
|
|
static void Shutdown();
|
|
|
|
static GPUProcessManager* Get();
|
|
|
|
|
|
|
|
~GPUProcessManager();
|
|
|
|
|
2016-06-11 05:27:24 +03:00
|
|
|
// If not using a GPU process, launch a new GPU process asynchronously.
|
2016-09-30 11:21:21 +03:00
|
|
|
void LaunchGPUProcess();
|
2016-06-11 05:27:24 +03:00
|
|
|
|
|
|
|
// 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.
|
2017-03-30 04:23:24 +03:00
|
|
|
bool EnsureGPUReady();
|
2016-06-11 05:27:24 +03:00
|
|
|
|
2017-07-20 16:20:22 +03:00
|
|
|
already_AddRefed<CompositorSession> CreateTopLevelCompositor(
|
2016-07-19 21:56:07 +03:00
|
|
|
nsBaseWidget* aWidget,
|
2016-11-08 18:42:19 +03:00
|
|
|
LayerManager* aLayerManager,
|
2016-05-23 10:27:01 +03:00
|
|
|
CSSToLayoutDeviceScale aScale,
|
2017-01-13 01:29:41 +03:00
|
|
|
const CompositorOptions& aOptions,
|
2016-05-23 10:27:01 +03:00
|
|
|
bool aUseExternalSurfaceSize,
|
2017-07-20 16:20:22 +03:00
|
|
|
const gfx::IntSize& aSurfaceSize,
|
|
|
|
bool* aRetry);
|
2016-05-23 10:27:01 +03:00
|
|
|
|
2016-09-20 11:15:49 +03:00
|
|
|
bool CreateContentBridges(
|
|
|
|
base::ProcessId aOtherProcess,
|
2017-07-05 18:47:40 +03:00
|
|
|
mozilla::ipc::Endpoint<PCompositorManagerChild>* aOutCompositor,
|
|
|
|
mozilla::ipc::Endpoint<PImageBridgeChild>* aOutImageBridge,
|
|
|
|
mozilla::ipc::Endpoint<PVRManagerChild>* aOutVRBridge,
|
|
|
|
mozilla::ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutVideoManager,
|
2017-04-14 11:06:09 +03:00
|
|
|
nsTArray<uint32_t>* aNamespaces);
|
2016-07-20 10:18:30 +03:00
|
|
|
|
2016-05-23 10:27:51 +03:00
|
|
|
// This returns a reference to the APZCTreeManager to which
|
|
|
|
// pan/zoom-related events can be sent.
|
2016-07-20 14:37:00 +03:00
|
|
|
already_AddRefed<IAPZCTreeManager> GetAPZCTreeManagerForLayers(uint64_t aLayersId);
|
2016-05-23 10:27:51 +03:00
|
|
|
|
2016-08-16 23:59:13 +03:00
|
|
|
// 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);
|
|
|
|
|
2016-11-02 23:55:07 +03:00
|
|
|
// Release compositor-thread resources referred to by |aID|.
|
|
|
|
//
|
|
|
|
// Must run on the content main thread.
|
|
|
|
void UnmapLayerTreeId(uint64_t aLayersId, base::ProcessId aOwningId);
|
|
|
|
|
2016-08-16 23:59:13 +03:00
|
|
|
// Checks to see if aLayersId and aRequestingPID have been mapped by MapLayerTreeId
|
|
|
|
bool IsLayerTreeIdMapped(uint64_t aLayersId, base::ProcessId aRequestingId);
|
|
|
|
|
2016-05-23 10:27:57 +03:00
|
|
|
// Allocate an ID that can be used to refer to a layer tree and
|
|
|
|
// associated resources that live only on the compositor thread.
|
|
|
|
//
|
2017-04-04 01:13:37 +03:00
|
|
|
// Must run on the browser main thread.
|
2016-05-23 10:27:57 +03:00
|
|
|
uint64_t AllocateLayerTreeId();
|
|
|
|
|
2017-04-14 11:06:09 +03:00
|
|
|
// Allocate an ID that can be used as Namespace and
|
|
|
|
// Must run on the browser main thread.
|
|
|
|
uint32_t AllocateNamespace();
|
|
|
|
|
2017-04-04 01:13:37 +03:00
|
|
|
// Allocate a layers ID and connect it to a compositor. If the compositor is null,
|
|
|
|
// the connect operation will not be performed, but an ID will still be allocated.
|
|
|
|
// This must be called from the browser main thread.
|
|
|
|
//
|
|
|
|
// Note that a layer tree id is always allocated, even if this returns false.
|
|
|
|
bool AllocateAndConnectLayerTreeId(
|
|
|
|
PCompositorBridgeChild* aCompositorBridge,
|
|
|
|
base::ProcessId aOtherPid,
|
2017-04-10 00:30:27 +03:00
|
|
|
uint64_t* aOutLayersId,
|
|
|
|
CompositorOptions* aOutCompositorOptions);
|
2016-05-23 10:27:57 +03:00
|
|
|
|
2017-08-11 10:51:23 +03:00
|
|
|
// Destroy and recreate all of the compositors
|
|
|
|
void ResetCompositors();
|
|
|
|
|
2016-06-11 05:27:24 +03:00
|
|
|
void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
|
2016-06-11 05:37:03 +03:00
|
|
|
void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;
|
2017-07-11 05:30:52 +03:00
|
|
|
void SimulateDeviceReset();
|
2017-08-30 03:10:22 +03:00
|
|
|
void DisableWebRender(wr::WebRenderError aError);
|
|
|
|
void NotifyWebRenderError(wr::WebRenderError aError);
|
2017-06-15 21:34:00 +03:00
|
|
|
void OnInProcessDeviceReset();
|
|
|
|
void OnRemoteProcessDeviceReset(GPUProcessHost* aHost) override;
|
|
|
|
void NotifyListenersOnCompositeDeviceReset();
|
2016-06-11 05:27:24 +03:00
|
|
|
|
2016-07-18 07:24:28 +03:00
|
|
|
// 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);
|
|
|
|
|
2016-09-20 11:18:50 +03:00
|
|
|
void AddListener(GPUProcessListener* aListener);
|
|
|
|
void RemoveListener(GPUProcessListener* aListener);
|
|
|
|
|
2016-10-15 15:45:02 +03:00
|
|
|
// 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);
|
|
|
|
|
2016-10-31 22:44:40 +03:00
|
|
|
// Used for tests and diagnostics
|
|
|
|
void KillProcess();
|
|
|
|
|
|
|
|
// Returns -1 if there is no GPU process, or the platform pid for it.
|
|
|
|
base::ProcessId GPUProcessPid();
|
|
|
|
|
2017-01-27 03:35:54 +03:00
|
|
|
// If a GPU process is present, create a MemoryReportingProcess object.
|
|
|
|
// Otherwise, return null.
|
|
|
|
RefPtr<MemoryReportingProcess> GetProcessMemoryReporter();
|
|
|
|
|
2016-06-27 09:33:20 +03:00
|
|
|
// Returns access to the PGPU protocol if a GPU process is present.
|
|
|
|
GPUChild* GetGPUChild() {
|
|
|
|
return mGPUChild;
|
|
|
|
}
|
|
|
|
|
2016-10-31 08:35:57 +03:00
|
|
|
// Returns whether or not a GPU process was ever launched.
|
|
|
|
bool AttemptedGPUProcess() const {
|
|
|
|
return mNumProcessAttempts > 0;
|
|
|
|
}
|
|
|
|
|
2016-06-11 05:27:24 +03:00
|
|
|
private:
|
|
|
|
// Called from our xpcom-shutdown observer.
|
|
|
|
void OnXPCOMShutdown();
|
|
|
|
|
2017-06-14 18:39:59 +03:00
|
|
|
bool CreateContentCompositorManager(base::ProcessId aOtherProcess,
|
2017-07-05 18:47:40 +03:00
|
|
|
mozilla::ipc::Endpoint<PCompositorManagerChild>* aOutEndpoint);
|
2016-09-20 11:15:49 +03:00
|
|
|
bool CreateContentImageBridge(base::ProcessId aOtherProcess,
|
2017-07-05 18:47:40 +03:00
|
|
|
mozilla::ipc::Endpoint<PImageBridgeChild>* aOutEndpoint);
|
2016-09-20 11:15:49 +03:00
|
|
|
bool CreateContentVRManager(base::ProcessId aOtherProcess,
|
2017-07-05 18:47:40 +03:00
|
|
|
mozilla::ipc::Endpoint<PVRManagerChild>* aOutEndpoint);
|
2016-11-08 05:21:35 +03:00
|
|
|
void CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
|
2017-07-05 18:47:40 +03:00
|
|
|
mozilla::ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndPoint);
|
2016-09-20 11:15:49 +03:00
|
|
|
|
2016-09-20 11:16:03 +03:00
|
|
|
// Called from RemoteCompositorSession. We track remote sessions so we can
|
|
|
|
// notify their owning widgets that the session must be restarted.
|
2017-06-15 21:34:00 +03:00
|
|
|
void RegisterRemoteProcessSession(RemoteCompositorSession* aSession);
|
|
|
|
void UnregisterRemoteProcessSession(RemoteCompositorSession* aSession);
|
|
|
|
|
|
|
|
// Called from InProcessCompositorSession. We track in process sessino so we can
|
|
|
|
// notify their owning widgets that the session must be restarted
|
|
|
|
void RegisterInProcessSession(InProcessCompositorSession* aSession);
|
|
|
|
void UnregisterInProcessSession(InProcessCompositorSession* aSession);
|
2016-09-20 11:16:03 +03:00
|
|
|
|
2017-05-12 08:44:27 +03:00
|
|
|
void RebuildRemoteSessions();
|
2017-06-15 21:34:00 +03:00
|
|
|
void RebuildInProcessSessions();
|
2017-05-12 08:44:27 +03:00
|
|
|
|
2016-05-23 10:27:01 +03:00
|
|
|
private:
|
|
|
|
GPUProcessManager();
|
|
|
|
|
2016-06-11 05:27:24 +03:00
|
|
|
// Permanently disable the GPU process and record a message why.
|
|
|
|
void DisableGPUProcess(const char* aMessage);
|
|
|
|
|
|
|
|
// Shutdown the GPU process.
|
2016-07-19 21:56:06 +03:00
|
|
|
void CleanShutdown();
|
2016-06-11 05:27:24 +03:00
|
|
|
void DestroyProcess();
|
|
|
|
|
2016-11-10 05:57:04 +03:00
|
|
|
void HandleProcessLost();
|
|
|
|
|
2016-07-19 21:56:06 +03:00
|
|
|
void EnsureVsyncIOThread();
|
|
|
|
void ShutdownVsyncIOThread();
|
|
|
|
|
2017-06-28 21:31:42 +03:00
|
|
|
void EnsureProtocolsReady();
|
2017-06-14 18:39:59 +03:00
|
|
|
void EnsureCompositorManagerChild();
|
2016-07-20 10:17:28 +03:00
|
|
|
void EnsureImageBridgeChild();
|
2016-07-21 10:14:59 +03:00
|
|
|
void EnsureVRManager();
|
2017-04-06 01:42:50 +03:00
|
|
|
|
|
|
|
#if defined(MOZ_WIDGET_ANDROID)
|
|
|
|
already_AddRefed<UiCompositorControllerChild> CreateUiCompositorController(nsBaseWidget* aWidget, const uint64_t aId);
|
|
|
|
#endif // defined(MOZ_WIDGET_ANDROID)
|
2016-07-20 10:17:28 +03:00
|
|
|
|
2016-07-18 07:24:28 +03:00
|
|
|
RefPtr<CompositorSession> CreateRemoteSession(
|
2016-07-19 21:56:07 +03:00
|
|
|
nsBaseWidget* aWidget,
|
2016-11-08 18:42:19 +03:00
|
|
|
LayerManager* aLayerManager,
|
2016-07-18 07:24:28 +03:00
|
|
|
const uint64_t& aRootLayerTreeId,
|
|
|
|
CSSToLayoutDeviceScale aScale,
|
2017-01-13 01:29:41 +03:00
|
|
|
const CompositorOptions& aOptions,
|
2016-07-18 07:24:28 +03:00
|
|
|
bool aUseExternalSurfaceSize,
|
|
|
|
const gfx::IntSize& aSurfaceSize);
|
|
|
|
|
2016-05-23 10:27:01 +03:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(GPUProcessManager);
|
2016-06-11 05:27:24 +03:00
|
|
|
|
|
|
|
class Observer final : public nsIObserver {
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSIOBSERVER
|
|
|
|
explicit Observer(GPUProcessManager* aManager);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
~Observer() {}
|
|
|
|
|
|
|
|
GPUProcessManager* mManager;
|
|
|
|
};
|
|
|
|
friend class Observer;
|
|
|
|
|
|
|
|
private:
|
2017-04-15 00:34:01 +03:00
|
|
|
bool mDecodeVideoOnGpuProcess = true;
|
|
|
|
|
2016-06-11 05:27:24 +03:00
|
|
|
RefPtr<Observer> mObserver;
|
2017-07-05 18:47:40 +03:00
|
|
|
mozilla::ipc::TaskFactory<GPUProcessManager> mTaskFactory;
|
2016-07-19 21:56:06 +03:00
|
|
|
RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
|
2017-04-14 11:06:09 +03:00
|
|
|
uint32_t mNextNamespace;
|
2017-05-30 03:59:44 +03:00
|
|
|
uint32_t mIdNamespace;
|
|
|
|
uint32_t mResourceId;
|
2016-09-30 11:21:21 +03:00
|
|
|
uint32_t mNumProcessAttempts;
|
2016-07-18 07:24:28 +03:00
|
|
|
|
2016-09-20 11:16:03 +03:00
|
|
|
nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;
|
2017-06-15 21:34:00 +03:00
|
|
|
nsTArray<RefPtr<InProcessCompositorSession>> mInProcessSessions;
|
2016-09-20 11:18:50 +03:00
|
|
|
nsTArray<GPUProcessListener*> mListeners;
|
2016-09-20 11:16:03 +03:00
|
|
|
|
2016-11-10 05:57:04 +03:00
|
|
|
uint32_t mDeviceResetCount;
|
|
|
|
TimeStamp mDeviceResetLastTime;
|
|
|
|
|
2016-07-19 21:56:06 +03:00
|
|
|
// Fields that are associated with the current GPU process.
|
2016-06-11 05:27:24 +03:00
|
|
|
GPUProcessHost* mProcess;
|
2016-07-28 11:33:17 +03:00
|
|
|
MOZ_INIT_OUTSIDE_CTOR uint64_t mProcessToken;
|
2016-06-11 05:27:24 +03:00
|
|
|
GPUChild* mGPUChild;
|
2016-07-19 21:56:06 +03:00
|
|
|
RefPtr<VsyncBridgeChild> mVsyncBridge;
|
2016-05-23 10:27:01 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace gfx
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // _include_mozilla_gfx_ipc_GPUProcessManager_h_
|