Commit Graph

128 Commits

Author SHA1 Message Date
Yuxuan Shui
db9b808bfb vblank: add GLX_SGI_video_sync based scheduler
Present extension based scheduler doesn't work well on NVIDIA drivers.
GLX_SGI_video_sync is less accurate, but is rumoured to work. See
[kwin's usage](https://invent.kde.org/plasma/kwin/-/blob/master/src/
backends/x11/standalone/x11_standalone_sgivideosyncvsyncmonitor.cpp)

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 23:27:12 +00:00
Yuxuan Shui
db6ed75b60 core: don't always delay schedule_render to vblank
It's kind of dumb anyway. If we get damage event right after a vblank
event, we would waste the whole vblank.

Instead improve the frame scheduling logic to target the right vblank
interval. This only affects smart_frame_pacing anyway.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 23:27:11 +00:00
Yuxuan Shui
dd83f550e1 core: always check if render is finished at next vblank
Right now we rely on `reschedule_render_at_vblank` being scheduled for
the render finish check. Which means we will only know if a frame has
finished rendering the next time we queue a render. And we only check at
vblank boundary, which means when a render is queued we have to wait for
the next vblank, when had we checked earlier, we will be able to start
rendering immediately

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 23:27:10 +00:00
Yuxuan Shui
3838b45e2c core: simplify pacing logic a bit more
Also, vblank event callback should call schedule_render to queue renders
instead of starting the draw timer directly, so that the CPU time
calculation will be correct.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 23:27:06 +00:00
Yuxuan Shui
4b57e3aa4c config: add debug options to enable timing based pacing
Disable timing estimation based pacing by default, as it might not work
well across drivers, and might have subtle bugs.

You can try setting `PICOM_DEBUG=smart_frame_pacing` if you want to try
it out.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 23:27:04 +00:00
Yuxuan Shui
1430d28116 core: refactor frame pacing
Factored out vblank event generation, add abstraction over how vblank
events are generated. The goal is so we can request vblank events in
different ways based on the driver we are running on.

Tried to simplify the frame scheduling logic, we will see if I succeeded
or not.

Also, the logic to exclude vblank events for vblank interval estimation
when the screen off is dropped. It's too hard to get right, we need to
find something robust.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 23:26:59 +00:00
Yuxuan Shui
23eb3d5f52 core: don't unredir when display is turned off
We unredirect because we receive bad vblank events, and also vblank
events at a different interval compared to when the screen is on. But it
is enough to just not record the vblank interval statistics when the
screen is off.

Although, unredirecting when display is off can also fix the problem
where use-damage causes the screen to flicker when the display is turned
off then back on. So we need something else for that.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 22:36:32 +00:00
Yuxuan Shui
2e1c4e51b3 core: don't request vblank events when we are not rendering
Previously everytime we receive a vblank event, we always request a new
one. This made the logic somewhat simpler. But this generated many
useless vblank events, and wasted power. We only need vblank events for
two things:

1. after we rendered a frame, we need to know when it has been displayed
   on the screen.
2. estimating the refresh rate.

This commit makes sure we only request vblank events when it's actually
needed.

Fixes #1079

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 22:36:31 +00:00
Yuxuan Shui
827380e1e3 core: simplify the pacing logic a little bit
Make it simpler to stop requesting PresentCompleteNotify when there is
nothing to render.

Related: #1079

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 22:36:28 +00:00
Yuxuan Shui
8d98b7d639 core: don't call schedule_render too early
I mistakenly assumed that PresentCompleteNotify event signifies the end
of a vblank (or the start of scanout). But actually this event can in
theory in sent at any point during a vblank, with its timestamp pointing
to when the end of vblank is. (that's why we often find the timestamp to
be in the future).

Add a delay so schedule_render is actually called at the end of vblank,
so it doesn't mistakenly think the render is too slow to complete.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-19 22:36:17 +00:00
Yuxuan Shui
7366553be2 core: distinguish preprocess failure and no window to render
paint_process would return NULL for both of these cases, but we should exit in
the failure case, and continue going in the other.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-17 23:44:56 +00:00
Yuxuan Shui
268e1d890a core: exit if paint_preprocess fails
This usually means there is another compositor running. If we don't do
this picom will spin forever.

Fixes #1104

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-17 23:34:34 +00:00
Yuxuan Shui
e92745671b compiler: use C23 auto when available
One annoying thing is C23 still defines auto as a storage class despite
it now being used for type inference. As a consequence we must write
"auto const" instead of the more natural "const auto".

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-12-17 08:55:23 +00:00
Maxim Solovyov
249f681857 backend: make target window a parameter of the init backend operation
to address a todo
2023-09-24 01:14:55 +03:00
Maxim Solovyov
34024092d7 picom: address some clang-tidy issues 2023-08-11 01:38:22 +03:00
Yuxuan Shui
1307d9ec70 core: isolate X connection with error handling into a struct
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>
2023-07-04 16:24:53 +01:00
Yuxuan Shui
f8cdc81635 core: add comment to set_rr_scheduling
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-06-26 13:25:53 +01:00
Yuxuan Shui
e0c14f63c6 core: don't use pthread functions
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>
2023-06-24 02:59:04 +01:00
Yuxuan Shui
9295f7e4c7 core: don't check RLIMIT_RTPRIO
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>
2023-06-24 02:51:07 +01:00
Yuxuan Shui
d0c121ec83 core: print some timing info from draw_callback_impl
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-06-10 23:23:24 +01:00
Yuxuan Shui
6a69cdb002 options: add a no-frame-pacing option
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-06-10 14:33:57 +01:00
Yuxuan Shui
7d9692360b 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>
2023-06-10 14:33:45 +01:00
Yuxuan Shui
b6e7ea5639 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>
2023-06-10 14:33:36 +01:00
Yuxuan Shui
8e1f3c92f5 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>
2023-06-10 14:33:24 +01:00
Yuxuan Shui
336cb0917a 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>
2023-06-08 20:35:33 +01:00
Yuxuan Shui
fcb9dc8cfd 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>
2023-06-08 20:35:31 +01:00
Yuxuan Shui
edeb17ad46 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>
2023-06-08 20:35:30 +01:00
Yuxuan Shui
1899ef0d49 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>
2023-06-08 20:35:29 +01:00
Yuxuan Shui
480fd24da6 core: stop sending NotifyMsc if frame pacing is disabled
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-06-08 20:35:28 +01:00
Yuxuan Shui
a4fae2b60a core: better frame pacing function
Details explained in the comments on schedule_render().

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-06-08 20:35:26 +01:00
Yuxuan Shui
47ffaf0a38 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>
2023-06-08 20:35:25 +01:00
Yuxuan Shui
86d3739374 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>
2023-06-08 20:35:24 +01:00
Yuxuan Shui
2a4e32babf 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>
2023-06-08 20:35:23 +01:00
Yuxuan Shui
64a97b57b5 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>
2023-06-08 20:35:21 +01:00
Yuxuan Shui
62fcfe5d1a backend: remove unused parameter 'ignore_damage'
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2023-06-08 20:35:16 +01:00
Maxim Solovyov
986b3c1cb3 core: drop xinerama
there are two x extensions for working with monitors (especially
multiple): xinerama and randr. xinerama is old, feature-poor and in
general isn't used anymore compared to the randr: new, feature-rich and
widely-used. for some reason we were using both of them, so let's drop
xinerama to keep things simple, clean and small. and to be modern.

the drop was done in three steps:
* first step was to replace all the xinerama-based code with the
  randr-based one and to replace or remove all the xinerama mentions;
* second step was to replace the xinerama's terminology with the
  randr's one. xinerama was referring only to the word "screen", while
  randr refers to multiple words and i think the word "monitor" is the
  most suitable for us and, hopefully, clear both to a contributor and
  to an end user;
* third step was to refactor the new randr-based code if needed and to
  address related todo's (mostly about moving related functions
  elsewhere).

all the steps were done well except addressing a leftover todo about
moving the win_update_monitor function to the x.c which wasn't done.

the xinerama-shadow-crop option was renamed to crop-shadow-to-monitor,
but it's previous name is still accepted, has effect and the
deprecation message is printed to preserve backwards-compatibility.
2023-01-29 10:51:12 +03:00
Yuxuan Shui
7ac80f980d Merge pull request #992 from absolutelynothelix/xcb_request_check_memory_leaks 2023-01-13 16:52:22 +00:00
Yuxuan Shui
e18a42ebd0 Merge pull request #985 from absolutelynothelix/free-root-image-properly
fixes https://github.com/yshui/picom/issues/982
2023-01-13 16:51:41 +00:00
Maxim Solovyov
81f2bf4c07 picom: fix xcb_request_check memory leaks 2023-01-11 12:35:03 +03:00
Maxim Solovyov
ca64654256 use _checked functions with xcb_request_check 2023-01-10 00:15:49 +03:00
Maxim Solovyov
91828be79d picom: free root image properly
fixes #982
2022-12-30 06:16:46 +03:00
Yuxuan Shui
37ecb4b496 core: detect screen off
Use the DPMS extension to detect if screen is turned off, and unredirect
if it is. This also helps working around the problem where OpenGL
buffers lose data when screen is turned off, causing screen to flicker
later when it turns back on if use-damage is enabled.

Unfortunately the DPMS extension doesn't define an event, so we have to
periodically poll the screen state.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2022-12-19 08:52:18 +00:00
Yuxuan Shui
aca3fdcef7 core: expand X error handling
We used to have a list of X errors we should ignore in case they do
occur. This commit expands that functionality to also allow us aborting
on certain errors.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2022-12-14 14:23:55 +00:00
Yuxuan Shui
3b342afa95 general: fix compiler warning about unused results
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2022-12-14 13:47:38 +00:00
Yuxuan Shui
8b189bc5ec core: print error with full_sequence
ev->sequence was just the lower 16 bits of the sequence number.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2022-12-14 12:35:37 +00:00
Omar Polo
5580f461dc fix log_debug call 2022-11-18 10:13:49 +00:00
Yuxuan Shui
9f04d824b7 Rename COMPTON_VERSION to PICOM_VERSION
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2022-10-29 19:31:12 +01:00
Stefan Radziuk
2328b97c23 Exclude transparent-clipping-excluded windows from updating the ignored region
Transparent clipping interacts poorly with programs whose transparent
interface elements must show windows below them for functionality,
for example screenshot utilities.
2022-10-23 23:28:26 +01:00
Yuxuan Shui
5a72b5755d backends: add egl backend
This needs the EGL_KHR_image_pixmap and the GL_EXT_EGL_image_storage
extensions, which unfortunately aren't available on NVIDIA cards.

Don't add documentation for these, for now.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2022-09-29 08:03:12 +01:00
Yuxuan Shui
84407099a9 backend: give backends more flexibility regarding shadow creation
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2022-08-26 05:42:51 +01:00