diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index a7b096d16b8d..0e2bc8e31cfb 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -28,7 +28,7 @@ include JavaScriptTypes; include URIParams; include PPrintingTypes; include PTabContext; - +include "mozilla/layers/WebRenderMessageUtils.h"; using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; using class mozilla::gfx::Matrix from "mozilla/gfx/Matrix.h"; @@ -83,6 +83,7 @@ using mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h"; using class mozilla::NativeEventData from "ipc/nsGUIEventIPC.h"; using mozilla::FontRange from "ipc/nsGUIEventIPC.h"; using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h"; +using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h"; namespace mozilla { namespace dom { @@ -555,6 +556,8 @@ parent: async AccessKeyNotHandled(WidgetKeyboardEvent event); + async AllocPipelineId() returns (PipelineId pipelineId); + child: async NativeSynthesisResponse(uint64_t aObserverId, nsCString aResponse); diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index b439f0265a52..47e809812760 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -3310,6 +3310,18 @@ TabParent::RecvRequestCrossBrowserNavigation(const uint32_t& aGlobalIndex) return IPC_OK(); } +mozilla::ipc::IPCResult +TabParent::RecvAllocPipelineId(RefPtr&& aPromise) +{ + GPUProcessManager* pm = GPUProcessManager::Get(); + if (!pm) { + aPromise->Reject(PromiseRejectReason::HandlerRejected, __func__); + return IPC_OK(); + } + aPromise->Resolve(wr::AsPipelineId(pm->AllocateLayerTreeId()), __func__); + return IPC_OK(); +} + void TabParent::LiveResizeStarted() { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index c3b82953e38a..d985269ec270 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -630,6 +630,8 @@ protected: virtual mozilla::ipc::IPCResult RecvRequestCrossBrowserNavigation(const uint32_t& aGlobalIndex) override; + virtual mozilla::ipc::IPCResult RecvAllocPipelineId(RefPtr&& aPromise) override; + ContentCacheInParent mContentCache; nsIntRect mRect; diff --git a/gfx/layers/wr/WebRenderImageLayer.cpp b/gfx/layers/wr/WebRenderImageLayer.cpp index 613042bc149c..778e69267d17 100644 --- a/gfx/layers/wr/WebRenderImageLayer.cpp +++ b/gfx/layers/wr/WebRenderImageLayer.cpp @@ -28,6 +28,7 @@ WebRenderImageLayer::WebRenderImageLayer(WebRenderLayerManager* aLayerManager) WebRenderImageLayer::~WebRenderImageLayer() { MOZ_COUNT_DTOR(WebRenderImageLayer); + mPipelineIdRequest.DisconnectIfExists(); if (mKey.isSome()) { WrManager()->AddImageKeyForDiscard(mKey.value()); } @@ -95,6 +96,21 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) MOZ_ASSERT(GetImageClientType() != CompositableType::UNKNOWN); + // Allocate PipelineId if necessary + if (GetImageClientType() == CompositableType::IMAGE_BRIDGE && + mPipelineId.isNothing() && !mPipelineIdRequest.Exists()) { + RefPtr self = this; + Manager()->AllocPipelineId() + ->Then(AbstractThread::GetCurrent(), __func__, + [self] (const wr::PipelineId& aPipelineId) { + self->mPipelineIdRequest.Complete(); + self->mPipelineId = Some(aPipelineId); + }, + [self] (const ipc::PromiseRejectReason &aReason) { + self->mPipelineIdRequest.Complete(); + })->Track(mPipelineIdRequest); + } + if (GetImageClientType() == CompositableType::IMAGE && !mImageClient) { mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE, WrBridge(), diff --git a/gfx/layers/wr/WebRenderImageLayer.h b/gfx/layers/wr/WebRenderImageLayer.h index 13fc04f9522b..091e61b196f3 100644 --- a/gfx/layers/wr/WebRenderImageLayer.h +++ b/gfx/layers/wr/WebRenderImageLayer.h @@ -22,6 +22,7 @@ public: virtual already_AddRefed GetAsSourceSurface() override; virtual void ClearCachedResources() override; + protected: virtual ~WebRenderImageLayer(); @@ -30,6 +31,9 @@ protected: return static_cast(mManager); } + void OnPipelineIdAllocated() {} + void OnPipelineIdFailed() {} + public: Layer* GetLayer() override { return this; } void RenderLayer(wr::DisplayListBuilder& aBuilder) override; @@ -42,6 +46,8 @@ protected: Maybe mKey; RefPtr mImageClient; CompositableType mImageClientTypeContainer; + Maybe mPipelineId; + MozPromiseRequestHolder mPipelineIdRequest; }; } // namespace layers diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index 579949064719..32214431418f 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -9,6 +9,7 @@ #include "gfxPrefs.h" #include "LayersLogging.h" #include "mozilla/dom/TabChild.h" +#include "mozilla/gfx/GPUProcessManager.h" #include "mozilla/layers/APZCTreeManager.h" #include "mozilla/layers/AsyncCompositionManager.h" #include "mozilla/layers/CompositorBridgeChild.h" @@ -678,6 +679,25 @@ WebRenderLayerManager::Composite() WrBridge()->SendForceComposite(); } +RefPtr +WebRenderLayerManager::AllocPipelineId() +{ + if (XRE_IsParentProcess()) { + GPUProcessManager* pm = GPUProcessManager::Get(); + if (!pm) { + return PipelineIdPromise::CreateAndReject(ipc::PromiseRejectReason::HandlerRejected, __func__); + } + return PipelineIdPromise::CreateAndResolve(wr::AsPipelineId(pm->AllocateLayerTreeId()), __func__);; + } + + MOZ_ASSERT(XRE_IsContentProcess()); + TabChild* tabChild = mWidget ? mWidget->GetOwningTabChild() : nullptr; + if (!tabChild) { + return PipelineIdPromise::CreateAndReject(ipc::PromiseRejectReason::HandlerRejected, __func__); + } + return tabChild->SendAllocPipelineId(); +} + void WebRenderLayerManager::SetRoot(Layer* aLayer) { diff --git a/gfx/layers/wr/WebRenderLayerManager.h b/gfx/layers/wr/WebRenderLayerManager.h index 9fd8989172f2..7d226a1abca7 100644 --- a/gfx/layers/wr/WebRenderLayerManager.h +++ b/gfx/layers/wr/WebRenderLayerManager.h @@ -7,8 +7,10 @@ #define GFX_WEBRENDERLAYERMANAGER_H #include "Layers.h" +#include "mozilla/ipc/MessageChannel.h" #include "mozilla/layers/CompositorController.h" #include "mozilla/layers/TransactionIdAllocator.h" +#include "mozilla/MozPromise.h" #include "mozilla/webrender/webrender_ffi.h" #include "mozilla/webrender/WebRenderTypes.h" #include "mozilla/webrender/WebRenderAPI.h" @@ -26,6 +28,9 @@ class WebRenderBridgeChild; class WebRenderLayerManager; class APZCTreeManager; +typedef MozPromise PipelineIdPromise; + + class WebRenderLayer { public: @@ -171,6 +176,8 @@ public: void SetTransactionIncomplete() { mTransactionIncomplete = true; } bool IsMutatedLayer(Layer* aLayer); + RefPtr AllocPipelineId(); + private: /** * Take a snapshot of the parent context, and copy