Bug 1451469 - Maintain a map from WrWindowId to APZSampler. r?botond draft
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 16 Apr 2018 17:39:13 -0400
changeset 783269 19e8e3e000d45c5d43752d6f826b03c610bc4db3
parent 783268 6d90300b9417e79bb52a9072e79b14dc27cd9985
child 783270 ba7e3de7c05b6f9e9c22bc2e32985a6938fcba3d
push id106651
push userkgupta@mozilla.com
push dateMon, 16 Apr 2018 21:40:40 +0000
reviewersbotond
bugs1451469
milestone61.0a1
Bug 1451469 - Maintain a map from WrWindowId to APZSampler. r?botond MozReview-Commit-ID: Bfkfs6FTOQ6
gfx/layers/apz/public/APZSampler.h
gfx/layers/apz/src/APZSampler.cpp
gfx/layers/ipc/CompositorBridgeParent.cpp
--- 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;
   }