зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1445662 - Ensure UpdateZoomConstraints runs on the sampler thread. r=rhunt
Without this patch, UpdateZoomConstraints can get called on: a) the compositor/sampler thread (over PAPZCTreeManager) b) the controller thread which is also the UI process main thread (on desktop platforms without a GPU process) c) the UI process main thread when it's *not* the controller thread (on Android). Instead of having to reason about all these scenarios separately, we can try to unify them a little bit by ensuring the function contents always run on the sampler thread, which is the thread that seems to make the most sense for it.
This commit is contained in:
Родитель
cfbe8bb66a
Коммит
bb580f89fa
|
@ -1935,6 +1935,24 @@ void
|
|||
APZCTreeManager::UpdateZoomConstraints(const ScrollableLayerGuid& aGuid,
|
||||
const Maybe<ZoomConstraints>& aConstraints)
|
||||
{
|
||||
if (!APZThreadUtils::IsSamplerThread()) {
|
||||
// This can happen if we're in the UI process and got a call directly from
|
||||
// nsBaseWidget (as opposed to over PAPZCTreeManager). We want this function
|
||||
// to run on the sampler thread, so bounce it over.
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
APZThreadUtils::RunOnSamplerThread(
|
||||
NewRunnableMethod<ScrollableLayerGuid, Maybe<ZoomConstraints>>(
|
||||
"APZCTreeManager::UpdateZoomConstraints",
|
||||
this,
|
||||
&APZCTreeManager::UpdateZoomConstraints,
|
||||
aGuid,
|
||||
aConstraints));
|
||||
return;
|
||||
}
|
||||
|
||||
APZThreadUtils::AssertOnSamplerThread();
|
||||
|
||||
RecursiveMutexAutoLock lock(mTreeLock);
|
||||
RefPtr<HitTestingTreeNode> node = GetTargetNode(aGuid, nullptr);
|
||||
MOZ_ASSERT(!node || node->GetApzc()); // any node returned must have an APZC
|
||||
|
|
|
@ -691,12 +691,13 @@ private:
|
|||
* isolation (that is, if its tree pointers are not being accessed or mutated). The
|
||||
* lock also needs to be held when accessing the mRootNode instance variable, as that
|
||||
* is considered part of the APZC tree management state.
|
||||
* Finally, the lock needs to be held when accessing mZoomConstraints.
|
||||
* IMPORTANT: See the note about lock ordering at the top of this file. */
|
||||
mutable mozilla::RecursiveMutex mTreeLock;
|
||||
RefPtr<HitTestingTreeNode> mRootNode;
|
||||
|
||||
/* Holds the zoom constraints for scrollable layers, as determined by the
|
||||
* the main-thread gecko code. */
|
||||
* the main-thread gecko code. This can only be accessed on the sampler
|
||||
* thread. */
|
||||
std::unordered_map<ScrollableLayerGuid, ZoomConstraints, ScrollableLayerGuidHash> mZoomConstraints;
|
||||
/* A list of keyboard shortcuts to use for translating keyboard inputs into
|
||||
* keyboard actions. This is gathered on the main thread from XBL bindings.
|
||||
|
|
|
@ -42,14 +42,6 @@ APZThreadUtils::AssertOnControllerThread() {
|
|||
MOZ_ASSERT(sControllerThread == MessageLoop::current());
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
APZThreadUtils::AssertOnSamplerThread()
|
||||
{
|
||||
if (GetThreadAssertionsEnabled()) {
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
APZThreadUtils::RunOnControllerThread(already_AddRefed<Runnable> aTask)
|
||||
{
|
||||
|
@ -74,6 +66,39 @@ APZThreadUtils::IsControllerThread()
|
|||
return sControllerThread == MessageLoop::current();
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
APZThreadUtils::AssertOnSamplerThread()
|
||||
{
|
||||
if (GetThreadAssertionsEnabled()) {
|
||||
MOZ_ASSERT(IsSamplerThread());
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
APZThreadUtils::RunOnSamplerThread(already_AddRefed<Runnable> aTask)
|
||||
{
|
||||
RefPtr<Runnable> task = aTask;
|
||||
|
||||
MessageLoop* loop = CompositorThreadHolder::Loop();
|
||||
if (!loop) {
|
||||
// Could happen during startup
|
||||
NS_WARNING("Dropping task posted to sampler thread");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsSamplerThread()) {
|
||||
task->Run();
|
||||
} else {
|
||||
loop->PostTask(task.forget());
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
APZThreadUtils::IsSamplerThread()
|
||||
{
|
||||
return CompositorThreadHolder::IsInCompositorThread();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(GenericNamedTimerCallbackBase, nsITimerCallback, nsINamed)
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -40,13 +40,6 @@ public:
|
|||
*/
|
||||
static void AssertOnControllerThread();
|
||||
|
||||
/**
|
||||
* This can be used to assert that the current thread is the
|
||||
* sampler thread (which samples the async transform).
|
||||
* This does nothing if thread assertions are disabled.
|
||||
*/
|
||||
static void AssertOnSamplerThread();
|
||||
|
||||
/**
|
||||
* Run the given task on the APZ "controller thread" for this platform. If
|
||||
* this function is called from the controller thread itself then the task is
|
||||
|
@ -58,6 +51,25 @@ public:
|
|||
* Returns true if currently on APZ "controller thread".
|
||||
*/
|
||||
static bool IsControllerThread();
|
||||
|
||||
/**
|
||||
* This can be used to assert that the current thread is the
|
||||
* sampler thread (which samples the async transform).
|
||||
* This does nothing if thread assertions are disabled.
|
||||
*/
|
||||
static void AssertOnSamplerThread();
|
||||
|
||||
/**
|
||||
* Runs the given task on the APZ "sampler thread" for this platform. If
|
||||
* this function is called from the sampler thread itself then the task is
|
||||
* run immediately without getting queued.
|
||||
*/
|
||||
static void RunOnSamplerThread(already_AddRefed<Runnable> aTask);
|
||||
|
||||
/**
|
||||
* Returns true if currently on the APZ "sampler thread".
|
||||
*/
|
||||
static bool IsSamplerThread();
|
||||
};
|
||||
|
||||
// A base class for GenericNamedTimerCallback<Function>.
|
||||
|
|
Загрузка…
Ссылка в новой задаче