Bug 1451469 - Maintain a map from WrWindowId to APZSampler. r?botond
MozReview-Commit-ID: Bfkfs6FTOQ6
--- a/gfx/layers/apz/public/APZSampler.h
+++ b/gfx/layers/apz/public/APZSampler.h
@@ -2,27 +2,31 @@
/* vim: set ts=8 sts=2 et sw=2 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_APZSampler_h
#define mozilla_layers_APZSampler_h
+#include <unordered_map>
+
#include "mozilla/layers/AsyncCompositionManager.h" // for AsyncTransform
+#include "mozilla/StaticMutex.h"
#include "nsTArray.h"
#include "Units.h"
namespace mozilla {
class TimeStamp;
namespace wr {
class TransactionBuilder;
struct WrTransformProperty;
+struct WrWindowId;
} // namespace wr
namespace layers {
class APZCTreeManager;
class LayerMetricsWrapper;
struct ScrollbarData;
@@ -32,16 +36,18 @@ struct ScrollbarData;
* the sampler thread.
*/
class APZSampler {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZSampler)
public:
explicit APZSampler(const RefPtr<APZCTreeManager>& aApz);
+ void SetWebRenderWindowId(const wr::WindowId& aWindowId);
+
bool PushStateToWR(wr::TransactionBuilder& aTxn,
const TimeStamp& aSampleTime);
bool SampleAnimations(const LayerMetricsWrapper& aLayer,
const TimeStamp& aSampleTime);
/**
* Compute the updated shadow transform for a scroll thumb layer that
@@ -79,16 +85,26 @@ public:
/**
* Returns true if currently on the APZSampler's "sampler thread".
*/
bool IsSamplerThread() const;
protected:
virtual ~APZSampler();
+ static already_AddRefed<APZSampler> GetSampler(const wr::WrWindowId& aWindowId);
+
private:
RefPtr<APZCTreeManager> 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<uint64_t, APZSampler*> sWindowIdMap;
+ Maybe<wr::WrWindowId> mWindowId;
+
};
} // namespace layers
} // namespace mozilla
#endif // mozilla_layers_APZSampler_h
--- a/gfx/layers/apz/src/APZSampler.cpp
+++ b/gfx/layers/apz/src/APZSampler.cpp
@@ -12,26 +12,44 @@
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/LayerMetricsWrapper.h"
#include "mozilla/layers/SynchronousTask.h"
#include "TreeTraversal.h"
namespace mozilla {
namespace layers {
+StaticMutex APZSampler::sWindowIdLock;
+std::unordered_map<uint64_t, APZSampler*> APZSampler::sWindowIdMap;
+
+
APZSampler::APZSampler(const RefPtr<APZCTreeManager>& aApz)
: mApz(aApz)
{
MOZ_ASSERT(aApz);
mApz->SetSampler(this);
}
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
APZSampler::PushStateToWR(wr::TransactionBuilder& aTxn,
const TimeStamp& aSampleTime)
{
// This function will be removed eventually since we'll have WR pull
// the transforms from APZ instead.
@@ -153,10 +171,22 @@ APZSampler::AssertOnSamplerThread() cons
}
bool
APZSampler::IsSamplerThread() const
{
return CompositorThreadHolder::IsInCompositorThread();
}
+/*static*/ already_AddRefed<APZSampler>
+APZSampler::GetSampler(const wr::WrWindowId& aWindowId)
+{
+ RefPtr<APZSampler> 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
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1771,16 +1771,20 @@ CompositorBridgeParent::AllocPWebRenderB
RefPtr<widget::CompositorWidget> widget = mWidget;
wr::WrWindowId windowId = wr::NewWindowId();
if (mApzUpdater) {
// If APZ is enabled, we need to register the APZ updater with the window id
// before the updater thread is created in WebRenderAPI::Create, so
// 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<wr::WebRenderAPI> api = wr::WebRenderAPI::Create(this, Move(widget), windowId, aSize);
if (!api) {
mWrBridge = WebRenderBridgeParent::CreateDestroyed(aPipelineId);
mWrBridge.get()->AddRef(); // IPDL reference
*aIdNamespace = mWrBridge->GetIdNamespace();
*aTextureFactoryIdentifier = TextureFactoryIdentifier(LayersBackend::LAYERS_NONE);
return mWrBridge;
}