diff --git a/gfx/layers/apz/public/APZSampler.h b/gfx/layers/apz/public/APZSampler.h index 53aea769dcc9..e4630ed7dc5a 100644 --- a/gfx/layers/apz/public/APZSampler.h +++ b/gfx/layers/apz/public/APZSampler.h @@ -7,7 +7,10 @@ #ifndef mozilla_layers_APZSampler_h #define mozilla_layers_APZSampler_h +#include + #include "mozilla/layers/AsyncCompositionManager.h" // for AsyncTransform +#include "mozilla/StaticMutex.h" #include "nsTArray.h" #include "Units.h" @@ -18,6 +21,7 @@ class TimeStamp; namespace wr { class TransactionBuilder; struct WrTransformProperty; +struct WrWindowId; } // namespace wr namespace layers { @@ -37,6 +41,8 @@ class APZSampler { public: explicit APZSampler(const RefPtr& aApz); + void SetWebRenderWindowId(const wr::WindowId& aWindowId); + bool PushStateToWR(wr::TransactionBuilder& aTxn, const TimeStamp& aSampleTime); @@ -84,8 +90,18 @@ public: protected: virtual ~APZSampler(); + static already_AddRefed GetSampler(const wr::WrWindowId& aWindowId); + private: RefPtr mApz; + + // Used to manage the mapping from a WR window id to APZSampler. These are only + // used if WebRender is enabled. Both sWindowIdMap and mWindowId should only + // be used while holding the sWindowIdLock. + static StaticMutex sWindowIdLock; + static std::unordered_map sWindowIdMap; + Maybe mWindowId; + }; } // namespace layers diff --git a/gfx/layers/apz/src/APZSampler.cpp b/gfx/layers/apz/src/APZSampler.cpp index 819e227ac401..56c3956723eb 100644 --- a/gfx/layers/apz/src/APZSampler.cpp +++ b/gfx/layers/apz/src/APZSampler.cpp @@ -17,6 +17,10 @@ namespace mozilla { namespace layers { +StaticMutex APZSampler::sWindowIdLock; +std::unordered_map APZSampler::sWindowIdMap; + + APZSampler::APZSampler(const RefPtr& aApz) : mApz(aApz) { @@ -27,6 +31,20 @@ APZSampler::APZSampler(const RefPtr& aApz) APZSampler::~APZSampler() { mApz->SetSampler(nullptr); + + StaticMutexAutoLock lock(sWindowIdLock); + if (mWindowId) { + sWindowIdMap.erase(wr::AsUint64(*mWindowId)); + } +} + +void +APZSampler::SetWebRenderWindowId(const wr::WindowId& aWindowId) +{ + StaticMutexAutoLock lock(sWindowIdLock); + MOZ_ASSERT(!mWindowId); + mWindowId = Some(aWindowId); + sWindowIdMap[wr::AsUint64(aWindowId)] = this; } bool @@ -158,5 +176,17 @@ APZSampler::IsSamplerThread() const return CompositorThreadHolder::IsInCompositorThread(); } +/*static*/ already_AddRefed +APZSampler::GetSampler(const wr::WrWindowId& aWindowId) +{ + RefPtr sampler; + StaticMutexAutoLock lock(sWindowIdLock); + auto it = sWindowIdMap.find(wr::AsUint64(aWindowId)); + if (it != sWindowIdMap.end()) { + sampler = it->second; + } + return sampler.forget(); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index 2da570291ef9..3815d199dac4 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -1779,6 +1779,10 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel // that the callback from the updater thread can find the right APZUpdater. mApzUpdater->SetWebRenderWindowId(windowId); } + if (mApzSampler) { + // Same as for mApzUpdater, but for the sampler thread. + mApzSampler->SetWebRenderWindowId(windowId); + } RefPtr api = wr::WebRenderAPI::Create(this, Move(widget), windowId, aSize); if (!api) { mWrBridge = WebRenderBridgeParent::CreateDestroyed(aPipelineId);