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

X11 shell uses sleep to sync rendering. #932

Closed
luleyleo opened this issue May 15, 2020 · 8 comments · Fixed by #989 or #1072
Closed

X11 shell uses sleep to sync rendering. #932

luleyleo opened this issue May 15, 2020 · 8 comments · Fixed by #989 or #1072
Labels
bug does not behave the way it is supposed to help wanted has no one working on it yet shell/x11 concerns the X11 backend

Comments

@luleyleo
Copy link
Collaborator

From #475:

  • Currently we figure out the screen's refresh rate and sleep (!) for however long based on the refresh rate, which is probably not what we want to do. Better way to sync draws?
  • This might also be what's causing the window to blink a lot during re-rendering

The code referred to is here

@luleyleo luleyleo added bug does not behave the way it is supposed to shell/x11 concerns the X11 backend help wanted has no one working on it yet labels May 15, 2020
@luleyleo luleyleo changed the title Fix X11 animation refresh rate hack X11 uses sleep to sync rendering May 15, 2020
@luleyleo luleyleo changed the title X11 uses sleep to sync rendering X11 shell uses sleep to sync rendering. May 15, 2020
@jneem
Copy link
Collaborator

jneem commented May 20, 2020

This is a bit outside my current comfort zone, but if y'all don't mind answer lots of questions then I'd like to look into it.

@xStrom
Copy link
Member

xStrom commented May 20, 2020

Yeah this is going to be rather tricky, because we want to sync the rendering to V-Sync as well.

Some improvement may be possible as a side-effect of the timers work I want to do in #934, which may give a wake-up system of sorts. But the real question is going to be figuring out how to detect V-Sync timings and how to guarantee syncing to them.

Some sort of V-Sync testing example/tool would be beneficial for druid in general. Something like vsynctester.com which could be used to test correctness on all platforms.

@jneem
Copy link
Collaborator

jneem commented May 21, 2020

I did some basic googling over the last day or two, and it seems like there are two common choices for syncing: glx and present. Metacity, mutter and xfwm seem to support both methods; I'm not sure if one is preferable (or more likely to be available) than the other.

However, there is something more basic about request_anim that's bothering me -- I'll start a topic on zulip...

@jneem
Copy link
Collaborator

jneem commented May 21, 2020

So I've been playing around with Present, and it seems as though it has what we need. It works like this (apologies if this is known to everyone already, but it's new to me...):

  • we keep track of our own buffers, which are stored as pixmaps in the X server
  • calling present on a pixmap schedules it to be displayed at the next vsync
  • when the vsync is done, the X server sends a notification event that we can use as a signal to start rendering the next frame (or if we really want to aim for lower latency, we could use it as a signal for wait for some time before rendering the next frame)
  • we also get a notification when the pixmaps are ready for re-use (which seems to happen before we get the other notification)

@xStrom
Copy link
Member

xStrom commented May 21, 2020

apologies if this is known to everyone already, but it's new to me...

Always good to have info written down, because even if the current participants know it - future ones might not. Also in this specific case I didn't know the X pixmap specifics.

Regarding low latency, it's tricky. Yeah we could wait with rendering and do it at the last moment and that would allow the frame to contain the latest info. On the flip side if the frame render time varies then if we wait too long we can start missing vsync timings because of spikes in render time.

@luleyleo
Copy link
Collaborator Author

apologies if this is known to everyone already, but it's new to me...

Well, I did not know any of this 😂

If we want to get low latency it would probably require that we can reliably predict how long paint takes, which would have to happen at runtime and it would demand that the time needed for rendering does not vary to much. I don't know much about this but I would expect it to be rather difficult to get right, especially with partial invalidation it could vary quite a lot.

For now I think it would be enough to get basic vsync working, we can always get fancy afterwards.

@jneem jneem mentioned this issue May 26, 2020
jneem added a commit that referenced this issue Jun 30, 2020
This switches to using the X11 Present extension as the primary means of presenting frames in the x11 backend. In case the Present extension is unavailable, it falls back to a double-buffering strategy: it renders to a pixmap and then copies that pixmap to the screen.

This improves #932, although the sleep path is still present in the fallback.

Co-authored-by: Leopold Luley <[email protected]>
@jneem
Copy link
Collaborator

jneem commented Jun 30, 2020

Looks like my comment in #989 auto-closed this. Re-opening because the sleeping still exists in the fallback method.

@jneem jneem reopened this Jun 30, 2020
@luleyleo
Copy link
Collaborator Author

Just for reference, this is the code in question:

// We aren't using the present extension, so fall back to sleeping for scheduling
// redraws. Sleeping is a terrible way to schedule redraws, but hopefully we don't
// have to fall back to this very often.
// TODO: once we have an idle handler, we should use that. Sleeping causes lots of
// problems when windows are dragged to resize.
if anim && self.refresh_rate.is_some() {
let sleep_amount_ms = (1000.0 / self.refresh_rate.unwrap()) as u64;
std::thread::sleep(std::time::Duration::from_millis(sleep_amount_ms));
self.invalidate_rect(size.to_rect());
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug does not behave the way it is supposed to help wanted has no one working on it yet shell/x11 concerns the X11 backend
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants