When using the GPU process, combine layer ownership and window mapping into a single IPC message. (bug 1350660 part 1, r=rhunt, r=billm)

This commit is contained in:
David Anderson 2017-04-03 15:13:37 -07:00
parent dfbf7fe0d0
commit 0f3b97ed9c
9 changed files with 78 additions and 5 deletions

View File

@ -869,6 +869,31 @@ GPUProcessManager::AllocateLayerTreeId()
return ++mNextLayerTreeId;
}
bool
GPUProcessManager::AllocateAndConnectLayerTreeId(PCompositorBridgeChild* aCompositorBridge,
base::ProcessId aOtherPid,
uint64_t* aOutLayersId)
{
uint64_t layersId = AllocateLayerTreeId();
*aOutLayersId = layersId;
if (!mGPUChild || !aCompositorBridge) {
// If we're not remoting to another process, or there is no compositor,
// then we'll send at most one message. In this case we can just keep
// the old behavior of making sure the mapping occurs, and maybe sending
// a creation notification.
MapLayerTreeId(layersId, aOtherPid);
if (!aCompositorBridge) {
return false;
}
return aCompositorBridge->SendNotifyChildCreated(layersId);
}
// Use the combined message path.
LayerTreeOwnerTracker::Get()->Map(layersId, aOtherPid);
return aCompositorBridge->SendMapAndNotifyChildCreated(layersId, aOtherPid);
}
void
GPUProcessManager::EnsureVsyncIOThread()
{

View File

@ -116,9 +116,18 @@ public:
// 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.
// Must run on the browser main thread.
uint64_t AllocateLayerTreeId();
// 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,
uint64_t* aOutLayersId);
void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;

View File

@ -1554,6 +1554,20 @@ CompositorBridgeParent::NotifyChildCreated(uint64_t aChild)
sIndirectLayerTrees[aChild].mLayerManager = mLayerManager;
}
mozilla::ipc::IPCResult
CompositorBridgeParent::RecvMapAndNotifyChildCreated(const uint64_t& aChild, const base::ProcessId& aOwnerPid)
{
// We only use this message when the remote compositor is in the GPU process.
// It is harmless to call it, though.
MOZ_ASSERT(XRE_IsGPUProcess());
LayerTreeOwnerTracker::Get()->Map(aChild, aOwnerPid);
MonitorAutoLock lock(*sIndirectLayerTreesLock);
NotifyChildCreated(aChild);
return IPC_OK();
}
mozilla::ipc::IPCResult
CompositorBridgeParent::RecvAdoptChild(const uint64_t& child)
{

View File

@ -189,6 +189,7 @@ public:
virtual mozilla::ipc::IPCResult RecvPause() override;
virtual mozilla::ipc::IPCResult RecvResume() override;
virtual mozilla::ipc::IPCResult RecvNotifyChildCreated(const uint64_t& child) override;
virtual mozilla::ipc::IPCResult RecvMapAndNotifyChildCreated(const uint64_t& child, const base::ProcessId& pid) override;
virtual mozilla::ipc::IPCResult RecvNotifyChildRecreated(const uint64_t& child) override;
virtual mozilla::ipc::IPCResult RecvAdoptChild(const uint64_t& child) override;
virtual mozilla::ipc::IPCResult RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,

View File

@ -264,6 +264,14 @@ CrossProcessCompositorBridgeParent::RecvNotifyChildCreated(const uint64_t& child
return IPC_FAIL_NO_REASON(this);
}
mozilla::ipc::IPCResult
CrossProcessCompositorBridgeParent::RecvMapAndNotifyChildCreated(const uint64_t& child, const base::ProcessId& pid)
{
// This can only be called from the browser process, as the mapping
// ensures proper window ownership of layer trees.
return IPC_FAIL_NO_REASON(this);
}
void
CrossProcessCompositorBridgeParent::ShadowLayersUpdated(
LayerTransactionParent* aLayerTree,

View File

@ -56,6 +56,7 @@ public:
virtual mozilla::ipc::IPCResult RecvResume() override { return IPC_OK(); }
virtual mozilla::ipc::IPCResult RecvForceIsFirstPaint() override { return IPC_OK(); }
virtual mozilla::ipc::IPCResult RecvNotifyChildCreated(const uint64_t& child) override;
virtual mozilla::ipc::IPCResult RecvMapAndNotifyChildCreated(const uint64_t& child, const base::ProcessId& pid) override;
virtual mozilla::ipc::IPCResult RecvNotifyChildRecreated(const uint64_t& child) override { return IPC_FAIL_NO_REASON(this); }
virtual mozilla::ipc::IPCResult RecvAdoptChild(const uint64_t& child) override { return IPC_FAIL_NO_REASON(this); }
virtual mozilla::ipc::IPCResult RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,

View File

@ -36,6 +36,7 @@ using class mozilla::layers::FrameUniformityData from "mozilla/layers/FrameUnifo
using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
using base::ProcessId from "base/process.h";
namespace mozilla {
namespace layers {
@ -175,6 +176,12 @@ parent:
// there are ordering issues with SendPLayerTransactionConstructor.
sync NotifyChildCreated(uint64_t id);
// This version of NotifyChildCreated also performs a layer tree mapping.
//
// See bug 1316632 comment #33 for why this has to be sync. Otherwise,
// there are ordering issues with SendPLayerTransactionConstructor.
sync MapAndNotifyChildCreated(uint64_t id, ProcessId owner);
async AdoptChild(uint64_t id);
// Same as NotifyChildCreated, but used when child processes need to

View File

@ -992,6 +992,8 @@ description =
description =
[PCompositorBridge::NotifyChildCreated]
description =
[PCompositorBridge::MapAndNotifyChildCreated]
description = bug 1350660
[PCompositorBridge::NotifyChildRecreated]
description =
[PCompositorBridge::MakeSnapshot]

View File

@ -114,12 +114,18 @@ RenderFrameParent::Init(nsFrameLoader* aFrameLoader)
TabParent* browser = TabParent::GetFrom(mFrameLoader);
if (XRE_IsParentProcess()) {
PCompositorBridgeChild* compositor = nullptr;
if (lm) {
compositor = lm->GetCompositorBridgeChild();
}
// Our remote frame will push layers updates to the compositor,
// and we'll keep an indirect reference to that tree.
browser->Manager()->AsContentParent()->AllocateLayerTreeId(browser, &mLayersId);
if (lm && lm->GetCompositorBridgeChild()) {
mLayersConnected = lm->GetCompositorBridgeChild()->SendNotifyChildCreated(mLayersId);
}
GPUProcessManager* gpm = GPUProcessManager::Get();
mLayersConnected = gpm->AllocateAndConnectLayerTreeId(
compositor,
browser->Manager()->AsContentParent()->OtherPid(),
&mLayersId);
} else if (XRE_IsContentProcess()) {
ContentChild::GetSingleton()->SendAllocateLayerTreeId(browser->Manager()->ChildID(), browser->GetTabId(), &mLayersId);
mLayersConnected = CompositorBridgeChild::Get()->SendNotifyChildCreated(mLayersId);