commit 856977b3ed32805d992f62c7bdb1497288a63c84
parent a08ead36b243d8adeea116f9787fdadf15ba3e4a
Author: Hiroyuki Ikezoe <hikezoe.birchill@mozilla.com>
Date: Mon, 8 Dec 2025 21:39:57 +0000
Bug 2003706 - Propagate the compositor fixed layers margins to root content APZCs. r=botond
Differential Revision: https://phabricator.services.mozilla.com/D274870
Diffstat:
4 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -449,6 +449,8 @@ std::vector<LayersId> APZCTreeManager::UpdateHitTestingTree(
TreeBuildingState state(mRootLayersId, aOriginatingLayersId, testData,
aPaintSequenceNumber, testLoggingEnabled);
+ mRootContentApzcs.ClearAndRetainStorage();
+
// We do this business with collecting the entire tree into an array because
// otherwise it's very hard to determine which APZC instances need to be
// destroyed. In the worst case, there are two scenarios: (a) a layer with an
@@ -573,6 +575,10 @@ std::vector<LayersId> APZCTreeManager::UpdateHitTestingTree(
}
if (apzc && node->IsPrimaryHolder()) {
state.mScrollTargets[apzc->GetGuid()] = node;
+ if (aLayerMetrics.Metrics().IsRootContent()) {
+ mTreeLock.AssertCurrentThreadIn(); // for threadsafety analysis
+ mRootContentApzcs.AppendElement(apzc);
+ }
}
// Accumulate the CSS transform between layers that have an APZC.
@@ -753,6 +759,8 @@ std::vector<LayersId> APZCTreeManager::UpdateHitTestingTree(
state.mNodesToDestroy[i]->Destroy();
}
+ SetFixedLayerMarginsOnRootContentApzcs(lock);
+
APZCTM_LOG("APZCTreeManager (%p)\n", this);
if (mRootNode && MOZ_LOG_TEST(sLog, LogLevel::Debug)) {
mRootNode->Dump(" ");
@@ -2772,6 +2780,7 @@ void APZCTreeManager::ClearTree() {
nodesToDestroy.AppendElement(aNode);
});
+ mRootContentApzcs.Clear();
for (size_t i = 0; i < nodesToDestroy.Length(); i++) {
nodesToDestroy[i]->Destroy();
}
@@ -3851,9 +3860,23 @@ void APZCTreeManager::SendSubtreeTransformsToChromeMainThread(
void APZCTreeManager::SetFixedLayerMargins(ScreenIntCoord aTop,
ScreenIntCoord aBottom) {
- MutexAutoLock lock(mMapLock);
- mCompositorFixedLayerMargins.top = ScreenCoord(aTop);
- mCompositorFixedLayerMargins.bottom = ScreenCoord(aBottom);
+ {
+ MutexAutoLock lock(mMapLock);
+ mCompositorFixedLayerMargins.top = ScreenCoord(aTop);
+ mCompositorFixedLayerMargins.bottom = ScreenCoord(aBottom);
+ }
+ {
+ RecursiveMutexAutoLock lock(mTreeLock);
+ SetFixedLayerMarginsOnRootContentApzcs(lock);
+ }
+}
+
+void APZCTreeManager::SetFixedLayerMarginsOnRootContentApzcs(
+ const RecursiveMutexAutoLock& aProofOfTreeLock) {
+ ScreenMargin margins = GetCompositorFixedLayerMargins();
+ for (auto* apzc : mRootContentApzcs) {
+ apzc->SetFixedLayerMargins(margins);
+ }
}
ScreenPoint APZCTreeManager::ComputeFixedMarginsOffset(
diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h
@@ -540,6 +540,9 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
virtual already_AddRefed<AsyncPanZoomController> NewAPZCInstance(
LayersId aLayersId, GeckoContentController* aController);
+ void SetFixedLayerMarginsOnRootContentApzcs(
+ const RecursiveMutexAutoLock& aProofOfTreeLock) MOZ_REQUIRES(mTreeLock);
+
public:
// Public hook for gtests subclass
virtual SampleTime GetFrameTime();
@@ -1133,6 +1136,9 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
friend class IAPZHitTester;
UniquePtr<IAPZHitTester> mHitTester;
+ // An array of root content APZCs in this tree.
+ nsTArray<AsyncPanZoomController*> mRootContentApzcs MOZ_GUARDED_BY(mTreeLock);
+
// NOTE: This ScrollGenerationCounter needs to be per APZCTreeManager since
// the generation is bumped up on the sampler theread which is per
// APZCTreeManager.
diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -7151,6 +7151,16 @@ CSSPoint AsyncPanZoomController::MaybeFillOutOverscrollGutter(
return Metrics().GetVisualScrollOffset() - origin;
}
+ScreenMargin AsyncPanZoomController::GetFixedLayerMargins(
+ const RecursiveMutexAutoLock& aProofOfLock) const {
+ return mCompositorFixedLayerMargins;
+}
+
+void AsyncPanZoomController::SetFixedLayerMargins(const ScreenMargin& aMargin) {
+ RecursiveMutexAutoLock lock(mRecursiveMutex);
+ mCompositorFixedLayerMargins = aMargin;
+}
+
std::ostream& operator<<(std::ostream& aOut,
const AsyncPanZoomController::PanZoomState& aState) {
switch (aState) {
diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -1937,6 +1937,8 @@ class AsyncPanZoomController {
return mState == PINCHING || mState == ANIMATING_ZOOM;
}
+ void SetFixedLayerMargins(const ScreenMargin& aMargins);
+
private:
// The timestamp of the latest touch start event.
TimeStamp mTouchStartTime;
@@ -1958,6 +1960,8 @@ class AsyncPanZoomController {
Maybe<ParentLayerCoord> mMinimumVelocityDuringPan;
// This variable needs to be protected by |mRecursiveMutex|.
ScrollSnapTargetIds mLastSnapTargetIds;
+ // This variable needs to be protected by |mRecursiveMutex|.
+ ScreenMargin mCompositorFixedLayerMargins;
// Extra offset to add to the async scroll position for testing
CSSPoint mTestAsyncScrollOffset;
// Extra zoom to include in the aync zoom for testing
@@ -2054,6 +2058,9 @@ class AsyncPanZoomController {
CSSPoint MaybeFillOutOverscrollGutter(
const RecursiveMutexAutoLock& aProofOfLock);
+ ScreenMargin GetFixedLayerMargins(
+ const RecursiveMutexAutoLock& aProofOfLock) const;
+
friend std::ostream& operator<<(
std::ostream& aOut, const AsyncPanZoomController::PanZoomState& aState);
};