Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve latency, fix rectangular "tearing", better performance metrics with frame pacing #968

Merged
merged 16 commits into from
Jun 12, 2023

Commits on Jun 8, 2023

  1. backend: remove unused parameter 'ignore_damage'

    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    62fcfe5 View commit details
    Browse the repository at this point in the history
  2. core: collect frame timing information.

    Needed to estimate refresh rate, and for us to stay in phase with
    vblank.
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    64a97b5 View commit details
    Browse the repository at this point in the history
  3. backend: add last_render_time interface.

    Used for querying how long render takes to complete, used for frame
    pacing.
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    2a4e32b View commit details
    Browse the repository at this point in the history
  4. core: frame pacing

    Use frame timing and render time statistic to pace frames.
    
    Right now the criteria are simple:
    
    * Don't render multiple frames in one vblank cycle. Otherwise the
      rendered frame will be delay multiple cycles, which isn't ideal.
    * Start rendering as late as possible while still hitting vblank.
    
    Refresh rate is estimated from a rolling average of frame timing. Render
    time is predicted from the rolling maximum of past 128 frames. The
    window size still needs to be investigated.
    
    Remove glFinish calls and GL_MaxFramesAllowed=1, frame pacing superseeds
    them.
    
    Professionals might laugh at how rudimentary this is, but hopefully this
    is better than what we had before. Which is absolutely nothing at all.
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    86d3739 View commit details
    Browse the repository at this point in the history
  5. core: workaround X present event quirk

    When the screen turns off, X sometimes sends present complete notify for
    the same frame multiple times, or even events with invalid msc/ust
    number.
    
    This will cause us to ignore it and not send a subsequent NotifyMsc
    request, causing the complete notify to stop.
    
    Now we send NotifyMsc regardless to keep the events going.
    
    Also detect when the complete notifies skip frames, divide the interval
    by frame count to estimate frame time in that case.
    
    Upstream bug report:
    https://gitlab.freedesktop.org/xorg/xserver/-/issues/1418
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    47ffaf0 View commit details
    Browse the repository at this point in the history
  6. core: better frame pacing function

    Details explained in the comments on schedule_render().
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    a4fae2b View commit details
    Browse the repository at this point in the history
  7. core: stop sending NotifyMsc if frame pacing is disabled

    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    480fd24 View commit details
    Browse the repository at this point in the history
  8. core: only check present timer alignment in the first frame

    Timer can sometimes drift randomly, like when the system is suspended.
    we don't want to disable frame pacing for that
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    1899ef0 View commit details
    Browse the repository at this point in the history
  9. core: don't fully trust msc from present complete notify

    Sometimes X sends bogus complete notifies with invalid msc number.
    Instead use a saved msc number to get the next complete notify.
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    edeb17a View commit details
    Browse the repository at this point in the history
  10. core: make sure unredirection happens when screen is off

    So when the screen is off, we calls queue_redraw, hoping draw_callback
    will be called and unredirects the screen. However, queue_redraw doesn't
    queue another redraw when one is already queued. Redraws can be queued
    in two ways: one is timer based, which is fine, because it will be
    triggered no matter what; the other is frame based, which is triggered
    by Present events.
    
    When the screen is off, X server, depends on the driver, could send
    abnormal Present events, which we ignore. But that also means queued
    frame based redraw will stop being triggered.
    
    Those two factors combined means sometimes unredirection does not happen
    when the screen is off. Which means we aren't going to free the GL
    context, which are still receiving Present events, but can't handle
    them, because we are not rendering anything with GL. In the end all
    these causes memory usage to balloon, until the screen is turned on and
    we start rendering again.
    
    And all these is not caught by leak checkers because this technically is
    not a leak, as everything is eventually freed.
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    fcb9dc8 View commit details
    Browse the repository at this point in the history
  11. core: check we have both frame time and render time before pacing

    We only checked render time. If we don't have frame time estimates, we
    would divide by zero and end up with wild scheduling delays.
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 8, 2023
    Configuration menu
    Copy the full SHA
    336cb09 View commit details
    Browse the repository at this point in the history

Commits on Jun 10, 2023

  1. core: factor out code for estimating the rendering time budget

    Add a render_statistics type to encapsulate all the statistics done on
    rendering times. And use that to estimate the time budget for rendering
    and frame pacing.
    
    Tweak the rolling window utilities a bit so we can reuse one rolling
    window for multiple statistics.
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 10, 2023
    Configuration menu
    Copy the full SHA
    8e1f3c9 View commit details
    Browse the repository at this point in the history
  2. core: don't update render statistics if we didn't actually render

    Sometimes a scheduled render can end up doing nothing, e.g. if the
    damage region is empty. In that case we don't have valid data to
    collect and thus shouldn't update the statistics.
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 10, 2023
    Configuration menu
    Copy the full SHA
    b6e7ea5 View commit details
    Browse the repository at this point in the history
  3. core: use SCHED_RR scheduling

    Make picom realtime to reduce latency, and make rendering times more
    predictable to help pacing.
    
    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 10, 2023
    Configuration menu
    Copy the full SHA
    7d96923 View commit details
    Browse the repository at this point in the history
  4. options: add a no-frame-pacing option

    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 10, 2023
    Configuration menu
    Copy the full SHA
    6a69cdb View commit details
    Browse the repository at this point in the history
  5. core: print some timing info from draw_callback_impl

    Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
    yshui committed Jun 10, 2023
    Configuration menu
    Copy the full SHA
    d0c121e View commit details
    Browse the repository at this point in the history