the corresponding regions need to be resized once for each window in the
stack above the damaged window including the damaged window itself. we
were off by one.
Part of the long running effort to reduce the prevalence of `session_t`.
After this, functions that communicate with X can make use of the error
handling machinary (set_ignore_cookie, set_cant_fail_cookie) without
needing to take a `session_t` parameter.
This commit converts everything to use the new struct `x_connection`,
most of the conversions are mechanical.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Don't use pthread_{set,get}schedparam, which requires -lpthread. Use
sched_setscheduler/sched_getparam instead, which is provided by libc.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
FreeBSD doesn't have RLIMIT_RTPRIO. So instead we skip this check and
just always try to set our priority to the lowest SCHED_RR priority
available.
Fixes#1082
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
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>
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>
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>
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>
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>
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>
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>
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>