PCompositorBridgeParent* CompositorManagerParent::AllocPCompositorBridgeParent( const CompositorBridgeOptions& aOpt) { switch (aOpt.type()) { case CompositorBridgeOptions::TContentCompositorOptions: { ContentCompositorBridgeParent* bridge = new ContentCompositorBridgeParent(this); bridge->AddRef(); return bridge; } case CompositorBridgeOptions::TWidgetCompositorOptions: { // Only the UI process is allowed to create widget compositors in the // compositor process. gfx::GPUParent* gpu = gfx::GPUParent::GetSingleton(); if (NS_WARN_IF(!gpu || OtherPid() != gpu->OtherPid())) { MOZ_ASSERT_UNREACHABLE("Child cannot create widget compositor!"); break; } const WidgetCompositorOptions& opt = aOpt.get_WidgetCompositorOptions(); CompositorBridgeParent* bridge = new CompositorBridgeParent( this, opt.scale(), opt.vsyncRate(), opt.options(), opt.useExternalSurfaceSize(), opt.surfaceSize()); bridge->AddRef(); return bridge; } case CompositorBridgeOptions::TSameProcessWidgetCompositorOptions: { // If the GPU and UI process are combined, we actually already created the // CompositorBridgeParent, so we need to reuse that to inject it into the // IPDL framework. if (NS_WARN_IF(OtherPid() != base::GetCurrentProcId())) { MOZ_ASSERT_UNREACHABLE("Child cannot create same process compositor!"); break; } // Note that the static mutex not only is used to protect sInstance, but // also mPendingCompositorBridges. StaticMutexAutoLock lock(sMutex); if (mPendingCompositorBridges.IsEmpty()) { break; } CompositorBridgeParent* bridge = mPendingCompositorBridges[0]; bridge->AddRef(); mPendingCompositorBridges.RemoveElementAt(0); return bridge; } default: break; } return nullptr; }
mozilla::ipc::IPCResult CrossProcessCompositorBridgeParent::RecvClearApproximatelyVisibleRegions(const uint64_t& aLayersId, const uint32_t& aPresShellId) { CompositorBridgeParent* parent; { // scope lock MonitorAutoLock lock(*sIndirectLayerTreesLock); parent = sIndirectLayerTrees[aLayersId].mParent; } if (parent) { parent->ClearApproximatelyVisibleRegions(aLayersId, Some(aPresShellId)); } return IPC_OK(); }
void CrossProcessCompositorBridgeParent::ForceComposite(LayerTransactionParent* aLayerTree) { uint64_t id = aLayerTree->GetId(); MOZ_ASSERT(id != 0); CompositorBridgeParent* parent; { // scope lock MonitorAutoLock lock(*sIndirectLayerTreesLock); parent = sIndirectLayerTrees[id].mParent; } if (parent) { parent->ForceComposite(aLayerTree); } }
bool CrossProcessCompositorBridgeParent::RecvNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid, const CSSIntRegion& aRegion) { CompositorBridgeParent* parent; { // scope lock MonitorAutoLock lock(*sIndirectLayerTreesLock); parent = sIndirectLayerTrees[aGuid.mLayersId].mParent; } if (parent) { return parent->RecvNotifyApproximatelyVisibleRegion(aGuid, aRegion); } return true; }
mozilla::ipc::IPCResult CrossProcessCompositorBridgeParent::RecvNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid, const CSSIntRegion& aRegion) { CompositorBridgeParent* parent; { // scope lock MonitorAutoLock lock(*sIndirectLayerTreesLock); parent = sIndirectLayerTrees[aGuid.mLayersId].mParent; } if (parent) { if (!parent->RecvNotifyApproximatelyVisibleRegion(aGuid, aRegion)) { return IPC_FAIL_NO_REASON(this); } return IPC_OK();; } return IPC_OK(); }
bool WebRenderBridgeParent::PushAPZStateToWR(nsTArray<wr::WrTransformProperty>& aTransformArray) { CompositorBridgeParent* cbp = GetRootCompositorBridgeParent(); if (!cbp) { return false; } if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) { TimeStamp animationTime = cbp->GetTestingTimeStamp().valueOr( mCompositorScheduler->GetLastComposeTime()); TimeDuration frameInterval = cbp->GetVsyncInterval(); // As with the non-webrender codepath in AsyncCompositionManager, we want to // use the timestamp for the next vsync when advancing animations. if (frameInterval != TimeDuration::Forever()) { animationTime += frameInterval; } return apzc->PushStateToWR(mApi, animationTime, aTransformArray); } return false; }
void WebRenderBridgeParent::UpdateAPZ() { CompositorBridgeParent* cbp = GetRootCompositorBridgeParent(); if (!cbp) { return; } uint64_t rootLayersId = cbp->RootLayerTreeId(); RefPtr<WebRenderBridgeParent> rootWrbp = cbp->GetWebRenderBridgeParent(); if (!rootWrbp) { return; } if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) { apzc->UpdateFocusState(rootLayersId, GetLayersId(), mScrollData.GetFocusTarget()); apzc->UpdateHitTestingTree(rootLayersId, rootWrbp->GetScrollData(), mScrollData.IsFirstPaint(), GetLayersId(), mScrollData.GetPaintSequenceNumber()); } }
PWebRenderBridgeParent* CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize, TextureFactoryIdentifier* aTextureFactoryIdentifier, uint32_t *aIdNamespace) { #ifndef MOZ_BUILD_WEBRENDER // Extra guard since this in the parent process and we don't want a malicious // child process invoking this codepath before it's ready MOZ_RELEASE_ASSERT(false); #endif uint64_t layersId = wr::AsUint64(aPipelineId); // Check to see if this child process has access to this layer tree. if (!LayerTreeOwnerTracker::Get()->IsMapped(layersId, OtherPid())) { NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message..."); return nullptr; } MonitorAutoLock lock(*sIndirectLayerTreesLock); MOZ_ASSERT(sIndirectLayerTrees.find(layersId) != sIndirectLayerTrees.end()); MOZ_ASSERT(sIndirectLayerTrees[layersId].mWrBridge == nullptr); CompositorBridgeParent* cbp = sIndirectLayerTrees[layersId].mParent; WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWrBridge.get(); WebRenderBridgeParent* parent = nullptr; RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI(); RefPtr<WebRenderCompositableHolder> holder = root->CompositableHolder(); parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder)); parent->AddRef(); // IPDL reference sIndirectLayerTrees[layersId].mCrossProcessParent = this; sIndirectLayerTrees[layersId].mWrBridge = parent; *aTextureFactoryIdentifier = parent->GetTextureFactoryIdentifier(); *aIdNamespace = parent->GetIdNameSpace(); return parent; }