Bug 1449982 - Maintain a map from WrWindowId to APZUpdater. r=botond

This will allow callbacks from rust code to get a handle to the
necessary APZUpdater instance on which to invoke functions.

MozReview-Commit-ID: 13XdzZrrtI5

--HG--
extra : rebase_source : 137af2a4c738a6e9294972be9e0566c9fdef58ac
This commit is contained in:
Kartikaya Gupta 2018-04-10 12:29:55 -04:00
Родитель 164909dbed
Коммит 7dd62afca0
3 изменённых файлов: 58 добавлений и 4 удалений

Просмотреть файл

@ -7,12 +7,20 @@
#ifndef mozilla_layers_APZUpdater_h
#define mozilla_layers_APZUpdater_h
#include <unordered_map>
#include "LayersTypes.h"
#include "mozilla/layers/APZTestData.h"
#include "mozilla/StaticMutex.h"
#include "nsThreadUtils.h"
#include "Units.h"
namespace mozilla {
namespace wr {
struct WrWindowId;
} // namespace wr
namespace layers {
class APZCTreeManager;
@ -34,6 +42,7 @@ public:
explicit APZUpdater(const RefPtr<APZCTreeManager>& aApz);
bool HasTreeManager(const RefPtr<APZCTreeManager>& aApz);
void SetWebRenderWindowId(const wr::WindowId& aWindowId);
void ClearTree();
void UpdateFocusState(LayersId aRootLayerTreeId,
@ -97,6 +106,13 @@ protected:
private:
RefPtr<APZCTreeManager> mApz;
// Used to manage the mapping from a WR window id to APZUpdater. 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, APZUpdater*> sWindowIdMap;
Maybe<wr::WrWindowId> mWindowId;
};
} // namespace layers

Просмотреть файл

@ -13,10 +13,15 @@
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/SynchronousTask.h"
#include "mozilla/layers/WebRenderScrollData.h"
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla {
namespace layers {
StaticMutex APZUpdater::sWindowIdLock;
std::unordered_map<uint64_t, APZUpdater*> APZUpdater::sWindowIdMap;
APZUpdater::APZUpdater(const RefPtr<APZCTreeManager>& aApz)
: mApz(aApz)
{
@ -27,6 +32,12 @@ APZUpdater::APZUpdater(const RefPtr<APZCTreeManager>& aApz)
APZUpdater::~APZUpdater()
{
mApz->SetUpdater(nullptr);
StaticMutexAutoLock lock(sWindowIdLock);
if (mWindowId) {
// Ensure that ClearTree was called and the task got run
MOZ_ASSERT(sWindowIdMap.find(wr::AsUint64(*mWindowId)) == sWindowIdMap.end());
}
}
bool
@ -35,14 +46,35 @@ APZUpdater::HasTreeManager(const RefPtr<APZCTreeManager>& aApz)
return aApz.get() == mApz.get();
}
void
APZUpdater::SetWebRenderWindowId(const wr::WindowId& aWindowId)
{
StaticMutexAutoLock lock(sWindowIdLock);
MOZ_ASSERT(!mWindowId);
mWindowId = Some(aWindowId);
sWindowIdMap[wr::AsUint64(aWindowId)] = this;
}
void
APZUpdater::ClearTree()
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
RunOnUpdaterThread(NewRunnableMethod(
"APZUpdater::ClearTree",
mApz,
&APZCTreeManager::ClearTree));
RefPtr<APZUpdater> self = this;
RunOnUpdaterThread(NS_NewRunnableFunction(
"APZUpdater::ClearTree",
[=]() {
self->mApz->ClearTree();
// Once ClearTree is called on the APZCTreeManager, we are in a shutdown
// phase. After this point it's ok if WebRender cannot get a hold of the
// updater via the window id, and it's a good point to remove the mapping
// and avoid leaving a dangling pointer to this object.
StaticMutexAutoLock lock(sWindowIdLock);
if (self->mWindowId) {
sWindowIdMap.erase(wr::AsUint64(*(self->mWindowId)));
}
}
));
}
void

Просмотреть файл

@ -1767,6 +1767,12 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel
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);
}
RefPtr<wr::WebRenderAPI> api = wr::WebRenderAPI::Create(this, Move(widget), windowId, aSize);
if (!api) {
mWrBridge = WebRenderBridgeParent::CreateDestroyed(aPipelineId);