Bug 1445662 - Ensure ZoomToRect runs on the controller thread. r?rhunt
Currently the ZoomToRect function is only ever called on Android, on the
UI process main thread, which is neither the controller nor the sampler
thread. Instead of allowing "random" threads to run inside APZ, we
ensure that callers run it on the controller thread.
MozReview-Commit-ID: 64LkHaFLIOl
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1886,16 +1886,21 @@ APZCTreeManager::SetKeyboardMap(const Ke
mKeyboardMap = aKeyboardMap;
}
void
APZCTreeManager::ZoomToRect(const ScrollableLayerGuid& aGuid,
const CSSRect& aRect,
const uint32_t aFlags)
{
+ // We could probably move this to run on the sampler thread if needed, but
+ // either way we should restrict it to a single thread. For now let's use the
+ // controller thread.
+ APZThreadUtils::AssertOnControllerThread();
+
RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
if (apzc) {
apzc->ZoomToRect(aRect, aFlags);
}
}
void
APZCTreeManager::ContentReceivedInputBlock(uint64_t aInputBlockId, bool aPreventDefault)
--- a/gfx/layers/apz/util/ChromeProcessController.cpp
+++ b/gfx/layers/apz/util/ChromeProcessController.cpp
@@ -153,18 +153,24 @@ ChromeProcessController::HandleDoubleTap
const float resolution = presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f;
CSSPoint point(aPoint.x / resolution, aPoint.y / resolution);
CSSRect zoomToRect = CalculateRectToZoomTo(document, point);
uint32_t presShellId;
FrameMetrics::ViewID viewId;
if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(
document->GetDocumentElement(), &presShellId, &viewId)) {
- mAPZCTreeManager->ZoomToRect(
- ScrollableLayerGuid(aGuid.mLayersId, presShellId, viewId), zoomToRect);
+ APZThreadUtils::RunOnControllerThread(
+ NewRunnableMethod<ScrollableLayerGuid, CSSRect, uint32_t>(
+ "IAPZCTreeManager::ZoomToRect",
+ mAPZCTreeManager,
+ &IAPZCTreeManager::ZoomToRect,
+ ScrollableLayerGuid(aGuid.mLayersId, presShellId, viewId),
+ zoomToRect,
+ ZoomToRectBehavior::DEFAULT_BEHAVIOR));
}
}
void
ChromeProcessController::HandleTap(TapType aType,
const mozilla::LayoutDevicePoint& aPoint,
Modifiers aModifiers,
const ScrollableLayerGuid& aGuid,
--- a/gfx/layers/ipc/APZCTreeManagerParent.cpp
+++ b/gfx/layers/ipc/APZCTreeManagerParent.cpp
@@ -182,17 +182,22 @@ APZCTreeManagerParent::RecvZoomToRect(
const uint32_t& aFlags)
{
if (aGuid.mLayersId != mLayersId) {
// Guard against bad data from hijacked child processes
NS_ERROR("Unexpected layers id in RecvZoomToRect; dropping message...");
return IPC_FAIL_NO_REASON(this);
}
- mTreeManager->ZoomToRect(aGuid, aRect, aFlags);
+ APZThreadUtils::RunOnControllerThread(
+ NewRunnableMethod<ScrollableLayerGuid, CSSRect, uint32_t>(
+ "layers::IAPZCTreeManager::ZoomToRect",
+ mTreeManager,
+ &IAPZCTreeManager::ZoomToRect,
+ aGuid, aRect, aFlags));
return IPC_OK();
}
mozilla::ipc::IPCResult
APZCTreeManagerParent::RecvContentReceivedInputBlock(
const uint64_t& aInputBlockId,
const bool& aPreventDefault)
{
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1928,17 +1928,24 @@ nsBaseWidget::ZoomToRect(const uint32_t&
const FrameMetrics::ViewID& aViewId,
const CSSRect& aRect,
const uint32_t& aFlags)
{
if (!mCompositorSession || !mAPZC) {
return;
}
uint64_t layerId = mCompositorSession->RootLayerTreeId();
- mAPZC->ZoomToRect(ScrollableLayerGuid(layerId, aPresShellId, aViewId), aRect, aFlags);
+ APZThreadUtils::RunOnControllerThread(
+ NewRunnableMethod<ScrollableLayerGuid, CSSRect, uint32_t>(
+ "layers::IAPZCTreeManager::ZoomToRect",
+ mAPZC,
+ &IAPZCTreeManager::ZoomToRect,
+ ScrollableLayerGuid(layerId, aPresShellId, aViewId),
+ aRect,
+ aFlags));
}
#ifdef ACCESSIBILITY
a11y::Accessible*
nsBaseWidget::GetRootAccessible()
{
NS_ENSURE_TRUE(mWidgetListener, nullptr);