From 79fa9b6bdb441afc156f1646d385409bac5ad646 Mon Sep 17 00:00:00 2001 From: Ryan Hunt Date: Tue, 16 Aug 2016 13:59:13 -0700 Subject: [PATCH] Bug 1289650 - Check the owning PID when creating PAPZCTreeManager, PLayerTransaction. r=kats,dvander MozReview-Commit-ID: Kbti1O7qgtN --- dom/ipc/ContentParent.cpp | 42 +++-------- gfx/ipc/GPUParent.cpp | 10 +++ gfx/ipc/GPUParent.h | 1 + gfx/ipc/GPUProcessManager.cpp | 25 +++++++ gfx/ipc/GPUProcessManager.h | 7 ++ gfx/ipc/PGPU.ipdl | 4 + .../apz/util/ScrollLinkedEffectDetector.cpp | 1 + gfx/layers/ipc/APZCTreeManagerParent.cpp | 37 ++++++++- gfx/layers/ipc/APZCTreeManagerParent.h | 3 +- gfx/layers/ipc/CompositorBridgeChild.cpp | 37 +++++++++ gfx/layers/ipc/CompositorBridgeChild.h | 7 ++ gfx/layers/ipc/CompositorBridgeParent.cpp | 75 +++++++++++++++++++ gfx/layers/ipc/CompositorBridgeParent.h | 7 ++ gfx/layers/ipc/LayerTreeOwnerTracker.cpp | 64 ++++++++++++++++ gfx/layers/ipc/LayerTreeOwnerTracker.h | 62 +++++++++++++++ gfx/layers/ipc/PAPZCTreeManager.ipdl | 4 + gfx/layers/ipc/PCompositorBridge.ipdl | 8 ++ gfx/layers/moz.build | 2 + 18 files changed, 361 insertions(+), 35 deletions(-) create mode 100644 gfx/layers/ipc/LayerTreeOwnerTracker.cpp create mode 100644 gfx/layers/ipc/LayerTreeOwnerTracker.h diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 21a3a1cafe79..3eb9f64f6a8c 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -23,8 +23,6 @@ #include "chrome/common/process_watcher.h" -#include - #include "mozilla/a11y/PDocAccessible.h" #include "AppProcessChecker.h" #include "AudioChannelService.h" @@ -90,6 +88,7 @@ #include "mozilla/layers/PAPZParent.h" #include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/ImageBridgeParent.h" +#include "mozilla/layers/LayerTreeOwnerTracker.h" #include "mozilla/layers/SharedBufferManagerParent.h" #include "mozilla/layout/RenderFrameParent.h" #include "mozilla/LookAndFeel.h" @@ -1685,18 +1684,6 @@ ContentParent::ProcessingError(Result aCode, const char* aReason) KillHard(aReason); } -typedef std::pair > IDPair; - -namespace { -std::map >& -NestedBrowserLayerIds() -{ - MOZ_ASSERT(NS_IsMainThread()); - static std::map > sNestedBrowserIds; - return sNestedBrowserIds; -} -} // namespace - /* static */ bool ContentParent::AllocateLayerTreeId(TabParent* aTabParent, uint64_t* aId) @@ -1712,7 +1699,9 @@ ContentParent::AllocateLayerTreeId(ContentParent* aContent, uint64_t* aId) { GPUProcessManager* gpu = GPUProcessManager::Get(); + *aId = gpu->AllocateLayerTreeId(); + gpu->MapLayerTreeId(*aId, aContent->OtherPid()); if (!gfxPlatform::AsyncPanZoomEnabled()) { return true; @@ -1748,33 +1737,22 @@ ContentParent::RecvAllocateLayerTreeId(const ContentParentId& aCpId, cpm->GetTopLevelTabParentByProcessAndTabId(aCpId, aTabId); MOZ_ASSERT(contentParent && browserParent); - if (!AllocateLayerTreeId(contentParent, browserParent, aTabId, aId)) { - return false; - } - - auto iter = NestedBrowserLayerIds().find(this); - if (iter == NestedBrowserLayerIds().end()) { - std::set ids; - ids.insert(*aId); - NestedBrowserLayerIds().insert(IDPair(this, ids)); - } else { - iter->second.insert(*aId); - } - return true; + return AllocateLayerTreeId(contentParent, browserParent, aTabId, aId); } bool ContentParent::RecvDeallocateLayerTreeId(const uint64_t& aId) { - auto iter = NestedBrowserLayerIds().find(this); - if (iter != NestedBrowserLayerIds().end() && - iter->second.find(aId) != iter->second.end()) + GPUProcessManager* gpu = GPUProcessManager::Get(); + + if (!gpu->IsLayerTreeIdMapped(aId, this->OtherPid())) { - GPUProcessManager::Get()->DeallocateLayerTreeId(aId); - } else { // You can't deallocate layer tree ids that you didn't allocate KillHard("DeallocateLayerTreeId"); } + + gpu->DeallocateLayerTreeId(aId); + return true; } diff --git a/gfx/ipc/GPUParent.cpp b/gfx/ipc/GPUParent.cpp index a9a58861eedc..6cf9b453aa9d 100644 --- a/gfx/ipc/GPUParent.cpp +++ b/gfx/ipc/GPUParent.cpp @@ -15,6 +15,7 @@ #include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/ImageBridgeParent.h" #include "nsDebugImpl.h" +#include "mozilla/layers/LayerTreeOwnerTracker.h" #include "VRManager.h" #include "VRManagerParent.h" #include "VsyncBridgeParent.h" @@ -62,6 +63,7 @@ GPUParent::Init(base::ProcessId aParentPid, } CompositorThreadHolder::Start(); VRManager::ManagerInit(); + LayerTreeOwnerTracker::Initialize(); return true; } @@ -222,6 +224,13 @@ GPUParent::RecvDeallocateLayerTreeId(const uint64_t& aLayersId) return true; } +bool +GPUParent::RecvAddLayerTreeIdMapping(const uint64_t& aLayersId, const ProcessId& aOwnerId) +{ + LayerTreeOwnerTracker::Get()->Map(aLayersId, aOwnerId); + return true; +} + void GPUParent::ActorDestroy(ActorDestroyReason aWhy) { @@ -244,6 +253,7 @@ GPUParent::ActorDestroy(ActorDestroyReason aWhy) DeviceManagerDx::Shutdown(); DeviceManagerD3D9::Shutdown(); #endif + LayerTreeOwnerTracker::Shutdown(); gfxVars::Shutdown(); gfxConfig::Shutdown(); gfxPrefs::DestroySingleton(); diff --git a/gfx/ipc/GPUParent.h b/gfx/ipc/GPUParent.h index 28d977d690f6..6fefb731d660 100644 --- a/gfx/ipc/GPUParent.h +++ b/gfx/ipc/GPUParent.h @@ -43,6 +43,7 @@ public: bool RecvNewContentVRManager(Endpoint&& aEndpoint) override; bool RecvDeallocateLayerTreeId(const uint64_t& aLayersId) override; bool RecvGetDeviceStatus(GPUDeviceData* aOutStatus) override; + bool RecvAddLayerTreeIdMapping(const uint64_t& aLayersId, const ProcessId& aOwnerId) override; void ActorDestroy(ActorDestroyReason aWhy) override; diff --git a/gfx/ipc/GPUProcessManager.cpp b/gfx/ipc/GPUProcessManager.cpp index df5839cf2224..6c145ee81d85 100644 --- a/gfx/ipc/GPUProcessManager.cpp +++ b/gfx/ipc/GPUProcessManager.cpp @@ -6,10 +6,13 @@ #include "GPUProcessManager.h" #include "GPUProcessHost.h" #include "mozilla/StaticPtr.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/layers/APZCTreeManager.h" #include "mozilla/layers/CompositorBridgeParent.h" #include "mozilla/layers/ImageBridgeChild.h" #include "mozilla/layers/ImageBridgeParent.h" #include "mozilla/layers/InProcessCompositorSession.h" +#include "mozilla/layers/LayerTreeOwnerTracker.h" #include "mozilla/layers/RemoteCompositorSession.h" #include "mozilla/widget/PlatformWidgetTypes.h" #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING @@ -57,10 +60,14 @@ GPUProcessManager::GPUProcessManager() { mObserver = new Observer(this); nsContentUtils::RegisterShutdownObserver(mObserver); + + LayerTreeOwnerTracker::Initialize(); } GPUProcessManager::~GPUProcessManager() { + LayerTreeOwnerTracker::Shutdown(); + // The GPU process should have already been shut down. MOZ_ASSERT(!mProcess && !mGPUChild); @@ -505,6 +512,24 @@ GPUProcessManager::GetAPZCTreeManagerForLayers(uint64_t aLayersId) return CompositorBridgeParent::GetAPZCTreeManager(aLayersId); } +void +GPUProcessManager::MapLayerTreeId(uint64_t aLayersId, base::ProcessId aOwningId) +{ + LayerTreeOwnerTracker::Get()->Map(aLayersId, aOwningId); + + if (mGPUChild) { + mGPUChild->SendAddLayerTreeIdMapping( + aLayersId, + aOwningId); + } +} + +bool +GPUProcessManager::IsLayerTreeIdMapped(uint64_t aLayersId, base::ProcessId aRequestingId) +{ + return LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, aRequestingId); +} + uint64_t GPUProcessManager::AllocateLayerTreeId() { diff --git a/gfx/ipc/GPUProcessManager.h b/gfx/ipc/GPUProcessManager.h index 33e9868e9ec2..1ca8e8efa3ef 100644 --- a/gfx/ipc/GPUProcessManager.h +++ b/gfx/ipc/GPUProcessManager.h @@ -93,6 +93,13 @@ public: // pan/zoom-related events can be sent. already_AddRefed 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); + + // 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. // diff --git a/gfx/ipc/PGPU.ipdl b/gfx/ipc/PGPU.ipdl index 69b862216295..21e6daf9a827 100644 --- a/gfx/ipc/PGPU.ipdl +++ b/gfx/ipc/PGPU.ipdl @@ -9,6 +9,7 @@ include protocol PImageBridge; include protocol PVRManager; include protocol PVsyncBridge; +using base::ProcessId from "base/process.h"; using mozilla::TimeDuration from "mozilla/TimeStamp.h"; using mozilla::CSSToLayoutDeviceScale from "Units.h"; using mozilla::gfx::IntSize from "mozilla/gfx/2D.h"; @@ -58,6 +59,9 @@ parent: async DeallocateLayerTreeId(uint64_t layersId); + // Called to notify the GPU process of who owns a layersId. + sync AddLayerTreeIdMapping(uint64_t layersId, ProcessId ownerId); + // Request the current DeviceStatus from the GPU process. This blocks until // one is available (i.e., Init has completed). sync GetDeviceStatus() returns (GPUDeviceData status); diff --git a/gfx/layers/apz/util/ScrollLinkedEffectDetector.cpp b/gfx/layers/apz/util/ScrollLinkedEffectDetector.cpp index 56b593f300da..758b705a3615 100644 --- a/gfx/layers/apz/util/ScrollLinkedEffectDetector.cpp +++ b/gfx/layers/apz/util/ScrollLinkedEffectDetector.cpp @@ -6,6 +6,7 @@ #include "ScrollLinkedEffectDetector.h" #include "nsIDocument.h" +#include "nsThreadUtils.h" namespace mozilla { namespace layers { diff --git a/gfx/layers/ipc/APZCTreeManagerParent.cpp b/gfx/layers/ipc/APZCTreeManagerParent.cpp index c9af1ba0cdec..9c7b9a8fd1e5 100644 --- a/gfx/layers/ipc/APZCTreeManagerParent.cpp +++ b/gfx/layers/ipc/APZCTreeManagerParent.cpp @@ -12,8 +12,9 @@ namespace mozilla { namespace layers { -APZCTreeManagerParent::APZCTreeManagerParent(RefPtr aAPZCTreeManager) - : mTreeManager(aAPZCTreeManager) +APZCTreeManagerParent::APZCTreeManagerParent(uint64_t aLayersId, RefPtr aAPZCTreeManager) + : mLayersId(aLayersId) + , mTreeManager(aAPZCTreeManager) { MOZ_ASSERT(aAPZCTreeManager != nullptr); } @@ -138,6 +139,12 @@ APZCTreeManagerParent::RecvZoomToRect( const CSSRect& aRect, const uint32_t& aFlags) { + if (aGuid.mLayersId != mLayersId) { + // Guard against bad data from hijacked child processes + NS_ERROR("Unexpected layers id in RecvZoomToRect; dropping message..."); + return false; + } + mTreeManager->ZoomToRect(aGuid, aRect, aFlags); return true; } @@ -156,6 +163,14 @@ APZCTreeManagerParent::RecvSetTargetAPZC( const uint64_t& aInputBlockId, nsTArray&& aTargets) { + for (size_t i = 0; i < aTargets.Length(); i++) { + if (aTargets[i].mLayersId != mLayersId) { + // Guard against bad data from hijacked child processes + NS_ERROR("Unexpected layers id in RecvSetTargetAPZC; dropping message..."); + return false; + } + } + mTreeManager->SetTargetAPZC(aInputBlockId, aTargets); return true; } @@ -165,6 +180,12 @@ APZCTreeManagerParent::RecvUpdateZoomConstraints( const ScrollableLayerGuid& aGuid, const MaybeZoomConstraints& aConstraints) { + if (aGuid.mLayersId != mLayersId) { + // Guard against bad data from hijacked child processes + NS_ERROR("Unexpected layers id in RecvUpdateZoomConstraints; dropping message..."); + return false; + } + mTreeManager->UpdateZoomConstraints(aGuid, aConstraints); return true; } @@ -172,6 +193,12 @@ APZCTreeManagerParent::RecvUpdateZoomConstraints( bool APZCTreeManagerParent::RecvCancelAnimation(const ScrollableLayerGuid& aGuid) { + if (aGuid.mLayersId != mLayersId) { + // Guard against bad data from hijacked child processes + NS_ERROR("Unexpected layers id in RecvCancelAnimation; dropping message..."); + return false; + } + mTreeManager->CancelAnimation(aGuid); return true; } @@ -204,6 +231,12 @@ APZCTreeManagerParent::RecvStartScrollbarDrag( const ScrollableLayerGuid& aGuid, const AsyncDragMetrics& aDragMetrics) { + if (aGuid.mLayersId != mLayersId) { + // Guard against bad data from hijacked child processes + NS_ERROR("Unexpected layers id in RecvStartScrollbarDrag; dropping message..."); + return false; + } + mTreeManager->StartScrollbarDrag(aGuid, aDragMetrics); return true; } diff --git a/gfx/layers/ipc/APZCTreeManagerParent.h b/gfx/layers/ipc/APZCTreeManagerParent.h index a46cc50dc4da..855d462ea40f 100644 --- a/gfx/layers/ipc/APZCTreeManagerParent.h +++ b/gfx/layers/ipc/APZCTreeManagerParent.h @@ -19,7 +19,7 @@ class APZCTreeManagerParent { public: - explicit APZCTreeManagerParent(RefPtr aAPZCTreeManager); + explicit APZCTreeManagerParent(uint64_t aLayersId, RefPtr aAPZCTreeManager); virtual ~APZCTreeManagerParent() { } bool @@ -133,6 +133,7 @@ public: ActorDestroy(ActorDestroyReason aWhy) override { } private: + uint64_t mLayersId; RefPtr mTreeManager; }; diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index 94c3fa24c668..5ec651d141d8 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -13,6 +13,8 @@ #include "base/task.h" // for NewRunnableMethod, etc #include "gfxPrefs.h" #include "mozilla/layers/ImageBridgeChild.h" +#include "mozilla/layers/IAPZCTreeManager.h" +#include "mozilla/layers/APZCTreeManagerChild.h" #include "mozilla/layers/LayerTransactionChild.h" #include "mozilla/layers/PLayerTransactionChild.h" #include "mozilla/layers/TextureClient.h"// for TextureClient @@ -1007,6 +1009,41 @@ CompositorBridgeChild::DeallocPCompositorWidgetChild(PCompositorWidgetChild* aAc #endif } +RefPtr +CompositorBridgeChild::GetAPZCTreeManager(uint64_t aLayerTreeId) +{ + bool apzEnabled = false; + Unused << SendAsyncPanZoomEnabled(aLayerTreeId, &apzEnabled); + + if (!apzEnabled) { + return nullptr; + } + + PAPZCTreeManagerChild* child = SendPAPZCTreeManagerConstructor(aLayerTreeId); + if (!child) { + return nullptr; + } + APZCTreeManagerChild* parent = static_cast(child); + + return RefPtr(parent); +} + +PAPZCTreeManagerChild* +CompositorBridgeChild::AllocPAPZCTreeManagerChild(const uint64_t& aLayersId) +{ + APZCTreeManagerChild* child = new APZCTreeManagerChild(); + child->AddRef(); + return child; +} + +bool +CompositorBridgeChild::DeallocPAPZCTreeManagerChild(PAPZCTreeManagerChild* aActor) +{ + APZCTreeManagerChild* parent = static_cast(aActor); + parent->Release(); + return true; +} + void CompositorBridgeChild::ProcessingError(Result aCode, const char* aReason) { diff --git a/gfx/layers/ipc/CompositorBridgeChild.h b/gfx/layers/ipc/CompositorBridgeChild.h index 97c070283bb4..5a91dc095674 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.h +++ b/gfx/layers/ipc/CompositorBridgeChild.h @@ -34,6 +34,8 @@ namespace layers { using mozilla::dom::TabChild; +class IAPZCTreeManager; +class APZCTreeManagerChild; class ClientLayerManager; class CompositorBridgeParent; class TextureClient; @@ -209,6 +211,11 @@ public: PCompositorWidgetChild* AllocPCompositorWidgetChild(const CompositorWidgetInitData& aInitData) override; bool DeallocPCompositorWidgetChild(PCompositorWidgetChild* aActor) override; + RefPtr GetAPZCTreeManager(uint64_t aLayerTreeId); + + PAPZCTreeManagerChild* AllocPAPZCTreeManagerChild(const uint64_t& aLayersId) override; + bool DeallocPAPZCTreeManagerChild(PAPZCTreeManagerChild* aActor) override; + virtual ShmemAllocator* AsShmemAllocator() override { return this; } void ProcessingError(Result aCode, const char* aReason) override; diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index aa38525f1a17..b274800e11d4 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -32,6 +32,7 @@ #include "VRManager.h" // for VRManager #include "mozilla/ipc/Transport.h" // for Transport #include "mozilla/layers/APZCTreeManager.h" // for APZCTreeManager +#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent #include "mozilla/layers/APZThreadUtils.h" // for APZCTreeManager #include "mozilla/layers/AsyncCompositionManager.h" #include "mozilla/layers/BasicCompositor.h" // for BasicCompositor @@ -42,6 +43,7 @@ #include "mozilla/layers/FrameUniformityData.h" #include "mozilla/layers/ImageBridgeParent.h" #include "mozilla/layers/LayerManagerComposite.h" +#include "mozilla/layers/LayerTreeOwnerTracker.h" #include "mozilla/layers/LayersTypes.h" #include "mozilla/layers/PLayerTransactionParent.h" #include "mozilla/layers/RemoteContentController.h" @@ -1350,6 +1352,30 @@ CompositorBridgeParent::ForceComposeToTarget(DrawTarget* aTarget, const gfx::Int mCompositorScheduler->ForceComposeToTarget(aTarget, aRect); } +PAPZCTreeManagerParent* +CompositorBridgeParent::AllocPAPZCTreeManagerParent(const uint64_t& aLayersId) +{ + return nullptr; +} + +bool +CompositorBridgeParent::DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor) +{ + return false; +} + +bool +CompositorBridgeParent::RecvAsyncPanZoomEnabled(const uint64_t& aLayersId, bool* aHasAPZ) +{ + return false; +} + +RefPtr +CompositorBridgeParent::GetAPZCTreeManager() +{ + return mApzcTreeManager; +} + bool CompositorBridgeParent::CanComposite() { @@ -2169,6 +2195,11 @@ public: return false; } + virtual bool RecvAsyncPanZoomEnabled(const uint64_t& aLayersId, bool* aHasAPZ) override; + + virtual PAPZCTreeManagerParent* AllocPAPZCTreeManagerParent(const uint64_t& aLayersId) override; + virtual bool DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor) override; + virtual CompositorBridgeParentIPCAllocator* AsCompositorBridgeParentIPCAllocator() override { return this; } virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) override { @@ -2459,6 +2490,12 @@ CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent( { MOZ_ASSERT(aId != 0); + // Check to see if this child process has access to this layer tree. + if (!LayerTreeOwnerTracker::Get()->IsMapped(aId, OtherPid())) { + NS_ERROR("Unexpected layers id in AllocPLayerTransactionParent; dropping message..."); + return nullptr; + } + MonitorAutoLock lock(*sIndirectLayerTreesLock); CompositorBridgeParent::LayerTreeState* state = nullptr; @@ -2497,6 +2534,44 @@ CrossProcessCompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransac return true; } +bool +CrossProcessCompositorBridgeParent::RecvAsyncPanZoomEnabled(const uint64_t& aLayersId, bool* aHasAPZ) +{ + // Check to see if this child process has access to this layer tree. + if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) { + NS_ERROR("Unexpected layers id in RecvAsyncPanZoomEnabled; dropping message..."); + return false; + } + + MonitorAutoLock lock(*sIndirectLayerTreesLock); + CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId]; + + *aHasAPZ = state.mParent ? state.mParent->AsyncPanZoomEnabled() : false; + return true; +} + +PAPZCTreeManagerParent* +CrossProcessCompositorBridgeParent::AllocPAPZCTreeManagerParent(const uint64_t& aLayersId) +{ + // Check to see if this child process has access to this layer tree. + if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) { + NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message..."); + return nullptr; + } + + MonitorAutoLock lock(*sIndirectLayerTreesLock); + CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId]; + + MOZ_ASSERT(state.mParent); + return new APZCTreeManagerParent(aLayersId, state.mParent->GetAPZCTreeManager()); +} +bool +CrossProcessCompositorBridgeParent::DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor) +{ + delete aActor; + return true; +} + bool CrossProcessCompositorBridgeParent::RecvNotifyChildCreated(const uint64_t& child) { diff --git a/gfx/layers/ipc/CompositorBridgeParent.h b/gfx/layers/ipc/CompositorBridgeParent.h index 734b8f25f933..d1a941ef5ef3 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.h +++ b/gfx/layers/ipc/CompositorBridgeParent.h @@ -489,6 +489,13 @@ public: void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr); + PAPZCTreeManagerParent* AllocPAPZCTreeManagerParent(const uint64_t& aLayersId) override; + bool DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor) override; + + bool RecvAsyncPanZoomEnabled(const uint64_t& aLayersId, bool* aHasAPZ) override; + + RefPtr GetAPZCTreeManager(); + bool AsyncPanZoomEnabled() const { return !!mApzcTreeManager; } diff --git a/gfx/layers/ipc/LayerTreeOwnerTracker.cpp b/gfx/layers/ipc/LayerTreeOwnerTracker.cpp new file mode 100644 index 000000000000..7fc08c3edea0 --- /dev/null +++ b/gfx/layers/ipc/LayerTreeOwnerTracker.cpp @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "LayerTreeOwnerTracker.h" + +#include "mozilla/StaticPtr.h" // for StaticAutoPtr +#include "mozilla/dom/ContentParent.h" // for ContentParent +#include "mozilla/gfx/GPUChild.h" // for GPUChild +#include "mozilla/gfx/GPUProcessManager.h" // for GPUProcessManager + +#include // for std::make_pair + +namespace mozilla { +namespace layers { + +static StaticAutoPtr sSingleton; + +LayerTreeOwnerTracker::LayerTreeOwnerTracker() : + mLayerIdsLock("LayerTreeOwnerTrackerLock") +{ +} + +void +LayerTreeOwnerTracker::Initialize() +{ + MOZ_ASSERT(!sSingleton); + sSingleton = new LayerTreeOwnerTracker(); +} + +void +LayerTreeOwnerTracker::Shutdown() +{ + sSingleton = nullptr; +} + +LayerTreeOwnerTracker* +LayerTreeOwnerTracker::Get() +{ + return sSingleton; +} + +void +LayerTreeOwnerTracker::Map(uint64_t aLayersId, base::ProcessId aProcessId) +{ + MutexAutoLock lock(mLayerIdsLock); + + // Add the mapping to the list + mLayerIds[aLayersId] = aProcessId; +} + +bool +LayerTreeOwnerTracker::IsMapped(uint64_t aLayersId, base::ProcessId aProcessId) +{ + MutexAutoLock lock(mLayerIdsLock); + + auto iter = mLayerIds.find(aLayersId); + return iter != mLayerIds.end() && iter->second == aProcessId; +} + +} // namespace layers +} // namespace mozilla diff --git a/gfx/layers/ipc/LayerTreeOwnerTracker.h b/gfx/layers/ipc/LayerTreeOwnerTracker.h new file mode 100644 index 000000000000..67809e4e5c66 --- /dev/null +++ b/gfx/layers/ipc/LayerTreeOwnerTracker.h @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=4 ts=8 et tw=80 : */ +/* 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 mozilla_layers_LayerTreeOwnerTracker_h +#define mozilla_layers_LayerTreeOwnerTracker_h + +#include "base/process.h" // for base::ProcessId +#include "mozilla/Mutex.h" // for mozilla::Mutex + +#include + +namespace mozilla { + +namespace dom { + class ContentParent; +} + +namespace layers { + +/** + * A utility class for tracking which content processes should be allowed + * to access which layer trees. + * + * ProcessId's are used to track which content process can access the layer + * tree, and in the case of nested browser's we use the top level content + * processes' ProcessId. + * + * This class is only available in the main process and gpu process. Mappings + * are synced from main process to the gpu process. The actual syncing happens + * in GPUProcessManager, and so this class should not be used directly. + */ +class LayerTreeOwnerTracker final +{ +public: + static void Initialize(); + static void Shutdown(); + static LayerTreeOwnerTracker* Get(); + + /** + * Map aLayersId and aProcessId together so that that process + * can access that layer tree. + */ + void Map(uint64_t aLayersId, base::ProcessId aProcessId); + /** + * Checks whether it is okay for aProcessId to access aLayersId. + */ + bool IsMapped(uint64_t aLayersId, base::ProcessId aProcessId); + +private: + LayerTreeOwnerTracker(); + + mozilla::Mutex mLayerIdsLock; + std::map mLayerIds; +}; + +} // namespace layers +} // namespace mozilla + +#endif // mozilla_layers_LayerTreeOwnerTracker_h diff --git a/gfx/layers/ipc/PAPZCTreeManager.ipdl b/gfx/layers/ipc/PAPZCTreeManager.ipdl index 134460317b69..ee3b8cae57f1 100644 --- a/gfx/layers/ipc/PAPZCTreeManager.ipdl +++ b/gfx/layers/ipc/PAPZCTreeManager.ipdl @@ -6,6 +6,8 @@ include "mozilla/GfxMessageUtils.h"; include "ipc/nsGUIEventIPC.h"; +include protocol PCompositorBridge; + using CSSRect from "Units.h"; using LayoutDeviceIntPoint from "Units.h"; using ScreenPoint from "Units.h"; @@ -34,6 +36,8 @@ namespace layers { sync protocol PAPZCTreeManager { +manager PCompositorBridge; + parent: sync ReceiveMultiTouchInputEvent(MultiTouchInput aEvent) diff --git a/gfx/layers/ipc/PCompositorBridge.ipdl b/gfx/layers/ipc/PCompositorBridge.ipdl index 584d927034e7..6e02f3274a2d 100644 --- a/gfx/layers/ipc/PCompositorBridge.ipdl +++ b/gfx/layers/ipc/PCompositorBridge.ipdl @@ -8,6 +8,7 @@ include LayersSurfaces; include LayersMessages; include PlatformWidgetTypes; +include protocol PAPZCTreeManager; include protocol PBrowser; include protocol PCompositable; include protocol PCompositorWidget; @@ -46,6 +47,7 @@ namespace layers { */ sync protocol PCompositorBridge { + manages PAPZCTreeManager; // A Compositor manages a single Layer Manager (PLayerTransaction) manages PLayerTransaction; manages PTexture; @@ -119,6 +121,12 @@ parent: // When out-of-process, this must be called to finish initialization. sync Initialize(uint64_t rootLayerTreeId); + // Returns whether this Compositor has APZ enabled or not. + sync AsyncPanZoomEnabled(uint64_t layersId) returns (bool aHasAPZ); + + // Must be called after Initialize(), and only succeeds if AsyncPanZoomEnabled() is true. + async PAPZCTreeManager(uint64_t layersId); + /** * Confirmation callback for UpdatePluginConfigurations and HideAllPlugins. */ diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 9347d27cb22b..732449437002 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -173,6 +173,7 @@ EXPORTS.mozilla.layers += [ 'ipc/LayerAnimationUtils.h', 'ipc/LayerTransactionChild.h', 'ipc/LayerTransactionParent.h', + 'ipc/LayerTreeOwnerTracker.h', 'ipc/RemoteContentController.h', 'ipc/ShadowLayerChild.h', 'ipc/ShadowLayers.h', @@ -363,6 +364,7 @@ UNIFIED_SOURCES += [ 'ipc/LayerAnimationUtils.cpp', 'ipc/LayerTransactionChild.cpp', 'ipc/LayerTransactionParent.cpp', + 'ipc/LayerTreeOwnerTracker.cpp', 'ipc/RemoteContentController.cpp', 'ipc/ShadowLayerChild.cpp', 'ipc/ShadowLayerParent.cpp',