New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 645284 link

Starred by 3 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug

Blocked on:
issue 468310



Sign in to add a comment

Best effort sync scroll doesn't work on https://docs.python.org/2/library/re.html

Project Member Reported by esprehn@chromium.org, Sep 8 2016

Issue description

Google Chrome	52.0.2743.116 (Official Build) (64-bit)
Revision	9115ecad1cae66fd5fe52bd9120af643384fd6f3-refs/branch-heads/2743@{#728}
Platform	8350.68.0 (Official Build) stable-channel link

I see this on both a Pixel 1 and Pixel 2.

What steps will reproduce the problem?
(1) Load https://docs.python.org/2/library/re.html
(2) Scroll up and down.
(3) Notice the sidebar wiggle and drift.

What is the expected output?

The sidebar should not drift, the main thread time is ~6ms on my Pixel 2, there's plenty of time to hit the 16ms budget (lots of empty space in the frame).

What do you see instead?

The main thread is many frames behind the compositor thread, the sidebar seems to drift way off.
 
Cc: vmi...@chromium.org tdres...@chromium.org
From a trace I captured, on the very first frame after a scroll event the scheduler decides not to wait for the main thread because it thinks the main thread is not fast enough.

The relevant state from the scheduler state machine:
critical_begin_main_frame_to_activate_is_fast_: false,
scroll_handler_state: "SCROLL_AFFECTS_SCROLL_HANDLER",
tree_priority: "SMOOTHNESS_TAKES_PRIORITY",
needs_redraw: true

Also the latency recovery logic doesn't kick in here presumably because of the same reason as above.

I wonder if we should stop trying to guess what to do based on timing estimates (this is not the first bug of this kind). Here's what a simpler approach that could work:

1. If there are impl scrolls/animations the scheduler always waits for a fixed deadline relative to vsync. No latency recovery or "immediate" deadline happens.
2. If we're done with BeginMainFrame and activation by the deadline draw the new tree. If not draw the previous tree.

Note that the scheduler does not force the active tree to be drawn i.e. we might end up discarding a main thread frame if the main thread can catch up.

Comment 2 by ojan@chromium.org, Sep 14 2016

Cc: ojan@chromium.org
+1 to a simpler approach that doesn't rely on timing estimates.

Comment 3 Deleted

| 1. If there are impl scrolls/animations the scheduler always waits for a 
| fixed deadline relative to vsync. No latency recovery or "immediate" deadline 
| happens.
| 2. If we're done with BeginMainFrame and activation by the deadline draw the 
| new tree. If not draw the previous tree.

The amount of work the compositor has to do isn't constant, so using a constant offset from vsync will sometimes behave really badly, won't it?

If I understand correctly, we're proposing:
VSYNC -> WAIT N ms FOR MAIN -> DRAW

If we take > N ms on the compositor, than we'll consistently drop a frame, in a case where we could consistently hit the deadline, right?
Cc: skyos...@chromium.org
+Sami
Components: Blink>Scheduling
Status: Available (was: Untriaged)
IIRC last time we talked about this the problem was we couldn't set the deadline accurately enough to avoid regressing scroll latency in general -- especially on slower devices. I don't think anything has (yet) changed there, or?

I agree that timing estimates suck because they can be all over the place. Other ideas that come to mind:

1. Assume the main thread is fast but if it misses the deadline, switch it permanently to high latency mode.

2. Add logic to determine if the page is really trying to synchronize with scroll or not (as opposed to just observing the scroll offset).

3. Decide that they should really be using position:fixed (or sticky) for this.

WDYT?
I don't have a Pixel to test on right now, but on my desktop the page runs in low latency mode consistently and the sidebar is *still* jittery.

Firefox handles the page perfectly, so there's either a way to get this right or the page uses a different sync scroll method for Firefox.

Attaching a few traces. Scrolling with the mouse wheel injects scroll events mid frame, which we know is an issue and input buffering should solve. However, the page up/down animations are still jittery even though they always run at the beginning of a frame.

Maybe there are a few issues here.

For the small jitter: Could there be a bug in the content or Chrome regarding fractional scroll offsets?

For the large jitter: Can someone post a trace of when we enter high latency mode?
trace_python_org_low_latency_scroll_wheel_midframe.json.gz
2.1 MB Download
trace_python_org_low_latency_page_up_down_hold.json.gz
1.3 MB Download
trace_python_org_low_latency_page_up_down_tap.json.gz
888 KB Download
I think there are two modes in which this bug happens:
1. If BeginMainFrames are actually slow, the scheduler (rightly) enters high latency mode and the estimate prevents it from waiting for the main thread. This might be caused by FrameView::synchronizedPaint taking too long (see  issue 647840 ).
2. In Brian's traces BeginMainFrames are still slow but they always make the deadline. I collected a trace on Windows Chrome Canary (trace_canary_no_bug.json.gz in  issue 647840 *) where BeginMainFrames are relatively quick and make the deadline, but there are still visual artifacts while scrolling e.g. the dots used for bullet points jump around. Brian confirmed that he saw similar visual artifacts while testing. In contrast when BeginMainFrame is slow (case 1 above) we don't see artifacts but sidebar is not in sync with content i.e. sync scroll is broken.

* no bug means FrameView::synchronizedPaint is not slow not that there are no visual artifacts

One thing I've noticed from the traces is that the first BeginMainFrame after a scroll aborts and subsequent BeginMainFrames are slow.

I don't know what to make of this.

Comment 9 by ojan@chromium.org, Sep 17 2016

Re: comment #6, I think there's a variant on #1 that seems like a good balance to me.

For any given user gesture, assume the main thread is fast. If it misses the deadline that switch it into high latency mode for the remainder of that gesture (e.g. automatically go back into low latency mode when the user lifts their finger off the screen).

This way, the worst case scenario is that you miss one frame per user gesture. It's not awesome, but it's simple (no estimation necessary) and won't get the user stuck in either mode.
Blockedon: 468310
Project Member

Comment 11 by sheriffbot@chromium.org, Sep 18 2017

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue.

Sorry for the inconvenience if the bug really should have been left as Available. If you change it back, also remove the "Hotlist-Recharge-Cold" label.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Status: Available (was: Untriaged)
It's still waiting for someone to have free time. :)

Comment 13 by ojan@chromium.org, May 8 2018

Cc: -ojan@chromium.org
Components: Internals>Compositing

Sign in to add a comment