Abort APZC animations when content updates the scroll offset

RESOLVED WORKSFORME

Status

()

Core
Panning and Zooming
RESOLVED WORKSFORME
4 years ago
3 years ago

People

(Reporter: jimm, Unassigned)

Tracking

Trunk
x86_64
Windows 8.1
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [defect] p=0)

(Reporter)

Description

4 years ago
Spin off from bug 907100.

There are a lot of ways to scroll content. The most common (touch on tablets) is currently handled directly by the apz through events sent via widget. Another common input method is mouse wheel scroll, which will also go directly to the apz (bug 907100).

However there are other cases where content can scroll (keyboard input, content calling scrollBy) that do not get directed to the apz directly. These changes are picked up in the metro fx front end [1], forwarded down to widget [2][3], and passed to the apz [4].

[1] http://mxr.mozilla.org/mozilla-central/source/browser/metro/base/content/bindings/browser.js#550
[2] http://mxr.mozilla.org/mozilla-central/source/browser/metro/base/content/apzc.js#136
[3] http://mxr.mozilla.org/mozilla-central/source/widget/windows/winrt/MetroWidget.cpp#1535
[4] http://mxr.mozilla.org/mozilla-central/source/gfx/layers/ipc/AsyncPanZoomController.cpp#1437

A problem here is that UpdateScrollOffset doesn't update the display port via a call to RequestContentRepaint(). 

In metrofx the display port is currently updated in the front end code thanks to our older fennec based code base. For B2G this is currently handled in TabChild, logic we'll inherit when we move back to remote content.

RequestContentRepaint calls RequestContentRepaint on the GeckoContentController [1], which is picked up down in widget [2]. This forwards an observer up to chrome [3] which forward over to content [4], which updates the display port.

[1] http://mxr.mozilla.org/mozilla-central/source/gfx/layers/ipc/AsyncPanZoomController.cpp#979
[2] http://mxr.mozilla.org/mozilla-central/source/widget/windows/winrt/APZController.cpp#32
[3] http://mxr.mozilla.org/mozilla-central/source/browser/metro/base/content/apzc.js#89
[4] http://mxr.mozilla.org/mozilla-central/source/browser/metro/base/content/bindings/browser.js#589

So about this bug, I've tested calling RequestContentRepaint() in UpdateScrollOffset and it does fix the redraw problem we have for various forms of scroll. However, SetCacheViewport also calls scrollBy on the browser to update it's position, and this breaks smooth scroll in cases like mouse wheel.

If we can get all the input that triggers smooth scrolling going straight to the apz via widget (making existing smooth scroll obsolete) We can then add RequestContentRepaint to UpdateScrollOffset. This bug is about adding that or potentially figuring out some way to avoid calling scrollBy in cases where we know smooth scroll is active.
(Reporter)

Comment 1

4 years ago
An additional optimization to consider here would be to look for a way to move the call to update the display port down closer to the apz. This would be temporary in nature, since as I mentioned we'll get this for free with remote content. The overhead here is pretty large though, so it might be worth looking at.
(Reporter)

Comment 2

4 years ago
s/scrollBy/scrollTo 

http://mxr.mozilla.org/mozilla-central/source/browser/metro/base/content/bindings/browser.js#577
(Reporter)

Updated

4 years ago
No longer blocks: 915723
(Reporter)

Updated

4 years ago
No longer blocks: 920687
(Reporter)

Updated

4 years ago
Blocks: 915723
Note that the displayport when set in layout is already relative to the scroll position. This means that in theory you shouldn't need to re-set the displayport when other scrolling mechanisms trigger. So for example, say your visible region is x=100 y=100 w=200 h=200 and you set a displayport of x=50 y=50 w=300 h=300. This displayport is actually stored as relative to the scroll position, so it would be x=-50 y=-50 w=300 h=300. Let's say then content does a scrollTo to x=100 y=500. The next paint that Gecko does will be of the area x=50 y=450 w=300 h=300.

For the purposes of this bug, the only potential problem I see is that if you are in the middle of a fling, the APZC heuristics might be projecting the displayport out (based on current velocity and expected paint time) so that it doesn't fully encompass the currently visible region (i.e. the relative displayport coordinates might have positive x or y). If at that point content does a scrollTo and the fling is aborted, the displayport might end up stuck at the projected position. So we should only need to set the displayport explicitly if UpdateScrollOffset is called while the APZC's mState != NOTHING, or something along those lines. As an aside it also looks like when UpdateScrollOffset is called it should clear any fling animations in progress and reset mState.

I'm going to narrow the scope of this bug to be to "modify the UpdateScrollOffset implementation to be more complete." In terms of what the Fennec code currently does, the code that needs to be added here is roughly JavaPanZoomController.abortAnimation().
Component: Pan and Zoom → Panning and Zooming
Product: Firefox for Metro → Core
(Reporter)

Updated

4 years ago
No longer depends on: 907100
(Reporter)

Comment 4

4 years ago
I was guessing that the lack of a RequestContentRepaint() call was the cause of all the black rect problems we see from scroll activity that passes through the event state manager. Unfortunately after adding that and playing with it a bit in bug 907100, I'm still seeing redraw problems.

I think we could coalesce this bug with the other keyboard scroll bugs plus the dom scroll wheel problems in bug 907100 if we want. Seems all these issues are caused by the same problem we have with dom scroll and the way we message back the apz when it happens.
(Reporter)

Comment 5

4 years ago
(In reply to Jim Mathies [:jimm] from comment #4)
> I was guessing that the lack of a RequestContentRepaint() call was the cause
> of all the black rect problems we see from scroll activity that passes
> through the event state manager. Unfortunately after adding that and playing
> with it a bit in bug 907100, I'm still seeing redraw problems.
> 
> I think we could coalesce this bug with the other keyboard scroll bugs plus
> the dom scroll wheel problems in bug 907100 if we want. Seems all these
> issues are caused by the same problem we have with dom scroll and the way we
> message back the apz when it happens.

I've found a fix for these issues, will post to and dupe any open bugs to bug 907100. Leaving this to the issue kats describes in comment 3.
(Reporter)

Comment 6

4 years ago
Should the remaining issue here block roll out kats?
Flags: needinfo?(bugmail.mozilla)
No, the missing pieces I described in comment 3 are unlikely to be hit often and don't need to block 28.
Flags: needinfo?(bugmail.mozilla)
Whiteboard: [release28]
Updating title to match what this bug's new scope is, as per comment 3 and comment 5.
Summary: display port needs to be updated when content receives scroll → APZC::UpdateScrollOffset implementation needs to be more complete
(Reporter)

Updated

4 years ago
No longer blocks: 915723
(Reporter)

Updated

4 years ago
Blocks: 886321
(Reporter)

Updated

4 years ago
Whiteboard: [release28]

Updated

4 years ago
Blocks: 861680
No longer blocks: 886321
(Reporter)

Updated

4 years ago
Whiteboard: [defect]

Updated

4 years ago
Whiteboard: [defect] → [defect] p=0
Summary: APZC::UpdateScrollOffset implementation needs to be more complete → Abort APZC animations when content updates the scroll offset
Blocks: 973619
Bug 1014997 mostly addresses this. I think the only thing left is to normalize the viewport so that it's not left in (under|over)zoom or overscroll.
See Also: → bug 1014997
(Assignee)

Updated

3 years ago
OS: Windows 8 Metro → Windows 8.1
Overscroll clearing is also done now. We don't allow overzoom or underzoom, so i'm going to close this bug.
Status: NEW → RESOLVED
Last Resolved: 3 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.