Closed Bug 1255338 Opened 10 years ago Closed 3 months ago

Change the way pointerlock works on e10s

Categories

(Core :: DOM: Core & HTML, defect, P3)

defect

Tracking

()

RESOLVED FIXED
154 Branch
Tracking Status
e10s + ---
firefox-esr153 --- wontfix
firefox153 --- fixed
firefox154 --- fixed

People

(Reporter: xidorn, Assigned: edgar)

References

(Blocks 2 open bugs, Regressed 1 open bug)

Details

(Whiteboard: btpp-fixlater)

Attachments

(4 files, 7 obsolete files)

48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
How pointerlock work in general: For each mouse move, if the pointer stops at a location other than the center of the window, we ask the system to move it back to the center. If we detect that an event is triggered by a mouse move we synthesized, we suppress it. In the current settings for e10s, all the logic above works inside the content process, which means, for each mouse move event, we would have at least two more IPC messages (one for synthesizing the mousemove, one for the additional to-be-suppressed mousemove event). This is very inefficient. We should move the main logic of pointerlock to the parent process, so that no additional IPC happens for mousemove events. In addition, issues like bug 1244546 is hard to fix for e10s due to coordinate alignment requirement of some platforms.
Blocks: pointer-lock
would love to see this api cleaned up, and the tests for it enabled. this is an enhancement though so doesn't block e10s.
Priority: -- → P3
Without this change, pointer lock would not work properly on HiDPI Linux with e10s. The pointer position will constantly move upward even the user doesn't touch the mouse at all. If we can live with this issue, sure, it is not a blocker. Note that it is not a regression. Before bug 1244546 gets fixed, pointer lock is not usable at all on Linux with HiDPI.
Well, we should disable pointerlock API on e10s-linux, if this wasn't fixed. It is just so broken. We could have done it for bug 1244546 too for non-e10s case.
It isn't broken for e10s-linux. It is only broken for e10s Linux with HiDPI. But yeah, if this isn't very high priority, we should probably disable pointer lock for HiDPI Linux with e10s enabled. But I still think we should fix pointer lock for e10s given it is currently so inefficient...
Xidorn, do you think this is something you'll get to in the next few months?
Flags: needinfo?(quanxunzhen)
Whiteboard: btpp-fixlater
Yes, it is currently in my Q2 plan.
Flags: needinfo?(quanxunzhen)
Depends on: 1273351
Depends on: 1285069
No longer depends on: 1273351
It seems to me the HiDPI issue appears on OS X as well, when in fullscreen mode.
I used to use pointer-lock-demo for testing pointer lock, but I just realized that the demo itself is poorly coded. So I guess we don't actually have any serious performance issue on PointerLock. (If there is really any performance difference for pointer-lock-demo between e10s and non-e10s, that should be because of handling tons of rAFs, not PointerLock).
But we may still want to fix this, both for an even better performance, and for correceness on HiDPI Linux and Mac.
Component: DOM → DOM: Core & HTML

quote from bug 853160 comment# 13:

The issue here is that we are just repeatedly trying to move the pointer back to the center of the window, but we never really restrict the pointer within the window area.

IIRC all desktop platforms provide some kind of mouse movement restriction API, for example on macOS we may use CGAssociateMouseAndMouseCursorPosition to forbid the mouse cursor from being moved at all.

Severity: normal → S3

Using this API prevents the mouse pointer from escaping from
PointerLocked windows.

Depends on D195726

by factoring out PointerLockManager::DispatchPointerLockChange() from
PointerLockManager::ChangePointerLockedElement().

This is needed for subsequent patches which tries to setup pointer lock in
chrome document as well when content request pointer lock and we don't want to
trigger pointerlock change event in chrome document in this case.

And this should not change currrent behavior.

Depends on D195728

Attachment #9367375 - Attachment is obsolete: true
Attachment #9367377 - Attachment description: Bug 1255338 - Part 2: Remove unused member from UIEvent; → WIP: Bug 1255338 - Part 1: Remove unused member from UIEvent;
Attachment #9368168 - Attachment description: Bug 1255338 - Part 3: Make PointerLockManager::SetPointerLock won't dispatch pointerlockchange event; → WIP: Bug 1255338 - Part 2: Make PointerLockManager::SetPointerLock won't dispatch pointerlockchange event;

Comment on attachment 9367377 [details]
WIP: Bug 1255338 - Part 1: Remove unused member from UIEvent;

Revision D195728 was moved to bug 1880187. Setting attachment 9367377 [details] to obsolete.

Attachment #9367377 - Attachment is obsolete: true
See Also: → 1889999
Depends on: 1896402
Depends on: 1882274
Depends on: 1866173
No longer blocks: CVE-2024-6608
Blocks: 1971833
Assignee: nobody → echen
Blocks: 1630462
Attachment #9368168 - Attachment description: WIP: Bug 1255338 - Part 2: Make PointerLockManager::SetPointerLock won't dispatch pointerlockchange event; → Bug 1255338 - Part 1: Make PointerLockManager::SetPointerLock won't dispatch pointerlockchange event;
Attachment #9368168 - Attachment description: Bug 1255338 - Part 1: Make PointerLockManager::SetPointerLock won't dispatch pointerlockchange event; → WIP: Bug 1255338 - Part 1: Make PointerLockManager::SetPointerLock won't dispatch pointerlockchange event;
Attachment #9378577 - Attachment description: WIP: Bug 1255338 - Part 3: Use Maybe for sPreLockScreenPoint; → WIP: Bug 1255338 - Part 2: Use (-1, -1) as default value of sPreLockScreenPoint;
Attachment #9378577 - Attachment description: WIP: Bug 1255338 - Part 2: Use (-1, -1) as default value of sPreLockScreenPoint; → Bug 1255338 - Part 1: Use (-1, -1) as default value of sPreLockScreenPoint;
Attachment #9368168 - Attachment is obsolete: true
Attachment #9378578 - Attachment description: WIP: Bug 1255338 - Part 4: Lock in parent; → Bug 1255338 - Part 2: Capture pointer in parent process when pointer is locked;
Attachment #9573420 - Attachment description: WIP: Bug 1255338 - Part 3: Reset pointer position from parent process; → Bug 1255338 - Part 3: Reset pointer position for pointer lock from parent process;

Hmm, Wayland currently has quite different setup on Pointer Lock, I need to think about how to make this change support that as well.

Depends on: 2036028
No longer depends on: 1882274
Attachment #9573420 - Attachment description: Bug 1255338 - Part 3: Reset pointer position for pointer lock from parent process; → WIP: Bug 1255338 - Part 3: Reset pointer position for pointer lock from parent process;
Attachment #9573420 - Attachment description: WIP: Bug 1255338 - Part 3: Reset pointer position for pointer lock from parent process; → Bug 1255338 - Part 3: Reset pointer position for pointer lock from parent process;
Attachment #9573420 - Attachment description: Bug 1255338 - Part 3: Reset pointer position for pointer lock from parent process; → Bug 1255338 - Part 2: Reset pointer position for pointer lock from parent process;
Attachment #9378578 - Attachment is obsolete: true
Attachment #9378577 - Attachment description: Bug 1255338 - Part 1: Use (-1, -1) as default value of sPreLockScreenPoint; → Bug 1255338 - Part 1: Use (-1, -1) as default value of sPreLockScreenPoint; r?smaug
Attachment #9573420 - Attachment description: Bug 1255338 - Part 2: Reset pointer position for pointer lock from parent process; → Bug 1255338 - Part 2: Reset pointer position for pointer lock from parent process; r?smaug
Attachment #9573420 - Attachment description: Bug 1255338 - Part 2: Reset pointer position for pointer lock from parent process; r?smaug → WIP: Bug 1255338 - Part 2: Reset pointer position for pointer lock from parent process; r?smaug

Recentering the pointer on every mousemove causes too much overhead when it is
handled in the parent process, as it prevents mousemove events from being
compressed or coalesced.

This patch introduces an optimization that recenters the pointer only when it
moves within a 25% boundary buffer near the edge of the window, reducing the
number of recentering operations. Since each platform now uses a native API to
"lock" the pointer, we do not need to worry as much about the pointer escaping
pointer lock by moving outside the browser window at high speed.

Attachment #9573420 - Attachment description: WIP: Bug 1255338 - Part 2: Reset pointer position for pointer lock from parent process; r?smaug → Bug 1255338 - Part 2: Reset pointer position for pointer lock from parent process; r?smaug
Attachment #9592564 - Attachment is obsolete: true
Pushed by asilaghi@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/bcaab0fc91e0 https://hg.mozilla.org/integration/autoland/rev/8524bfbd843e Revert "Bug 1255338 - Part 2: Reset pointer position for pointer lock from parent process; r=smaug" for causing bp-nu bustages at /base/Document.h

Backed out for causing bp-nu bustages at /base/Document.h and mochitests failures
Backout Link
Push with failures
Failure Log
mochitests
Failure line /builds/worker/checkouts/gecko/dom/base/Document.h:1254:25: error: inline function 'mozilla::dom::Document::GetPresContext' is not defined [-Werror,-Wundefined-inline]

Flags: needinfo?(echen)
Blocks: 1752138
Pushed by sstanca@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/b228dc82abc6 https://hg.mozilla.org/integration/autoland/rev/7944f8890ca2 Revert "Bug 1255338 - Part 2: Reset pointer position for pointer lock from parent process; r=smaug" for causing wpt failures in pointerlock-maintains-mousedown.html.

Reverted this because it was causing wpt failures in pointerlock-maintains-mousedown.html.

  • Revert link
  • Push with failures
  • Failure Log
  • Failure line: TEST-UNEXPECTED-PASS | /pointerlock/pointerlock-maintains-mousedown.html?unadjustedmovement=false | Tests that mousemove events during pointer lock report correct button state - expected FAIL
Flags: needinfo?(echen)

(In reply to Serban Stanca [:SerbanS] from comment #31)

  • Failure line: TEST-UNEXPECTED-PASS | /pointerlock/pointerlock-maintains-mousedown.html?unadjustedmovement=false | Tests that mousemove events during pointer lock report correct button state - expected FAIL

Oh, this patch surprisingly fixes a test.
I think the test failed because there was an initial zero-movement mousemove event right after the pointer was locked. With recentering from the parent process, we no longer generate that initial zero-movement mousemove event.

Blocks: 2046714
Flags: needinfo?(echen)
Status: NEW → RESOLVED
Closed: 3 months ago
Resolution: --- → FIXED
Target Milestone: --- → 154 Branch
Duplicate of this bug: 1971833
Duplicate of this bug: 1630462
Duplicate of this bug: 1752138
No longer duplicate of this bug: 1630462
Attachment #9356745 - Attachment is obsolete: true
Attachment #9356709 - Attachment is obsolete: true
Attachment #9613754 - Flags: approval-mozilla-release?

firefox-release Uplift Approval Request

  • User impact if declined/Reason for urgency: This makes pointer lock works better on Windows.
  • Code covered by automated testing?: yes
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: no
  • Steps to reproduce for manual QE testing: None
  • Risk associated with taking this patch: medium
  • Explanation of risk level: This changes how pointer lock is handled. The changes have been in Nightly for a while, have been tested by several people, and no regressions have been reported. So I don't think this would be too risky.
  • String changes made/needed?: None
  • Is Android affected?: yes
Attachment #9613755 - Flags: approval-mozilla-release?

This is gated behind a new pref: dom.pointer-lock.reset-to-center-from-parent.enabled.
The patch preserves the original behavior as much as possible when the pref is off.
There are some changes that affect both code paths, but they are minor and
should not affect the main logic.

Here are some major change when the pref is enabled:

  • Pointer recentering and computation of the center point are now handled in the parent process.
  • Locking native pointer is initiated from parent process as well.
  • When a remote target requests pointer lock, the parent process captures the mouse
    on the top-level browser element. This is necessary because the center of the
    chrome window may not correspond to the web page (for example, when a DevTools
    panel is open and resized to be very large).
  • This patch introduces an optimization that recenters the pointer only when it
    moves within a 25% boundary buffer near the edge of the window, reducing the
    number of recentering operations. Since each platform now uses a native API to
    "lock" the pointer, we do not need to worry as much about the pointer escaping
    pointer lock by moving outside the browser window at high speed.

Original Revision: https://phabricator.services.mozilla.com/D296321

Edgar, this is a fix for a 10 year old bug marked as P3/S3 and there is some risk of regression, is there a specific business need to have it uplifted to production now instead of letting it ship with 154 mid-August?

Flags: needinfo?(echen)
Attachment #9613754 - Flags: approval-mozilla-release? → approval-mozilla-release+
Attachment #9613755 - Flags: approval-mozilla-release? → approval-mozilla-release+
Flags: needinfo?(echen)
Regressions: 2051017
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: