malcolmstill / ulubis

A Wayland compositor written in Common Lisp
BSD 3-Clause "New" or "Revised" License
236 stars 19 forks source link

Janky animations #49

Open malcolmstill opened 6 years ago

malcolmstill commented 6 years ago

With the new virtual desktop slide animation I'm noticing that the animation is not entirely smooth, suffering from some jankiness. This definitely affects ulubis animations; I'm still investigating whether I see any jankiness when Wayland clients themselves are animation.

Possible reasons for this:

  1. we are simply taking too long to render a frame
  2. an issue with the animation code (an issue with timing say)
  3. related to the above, the animation code sets up a 60 FPS timer on the Wayland event loop. However this timer will not be synchronized to vblanks / page flips

As of https://github.com/malcolmstill/ulubis/commit/133479a7e32fd3378c90e95aa8c7c9fd721e393a, when the screen is drawn, a page flip callback is requested (scheduled). This sets a flag, which prevents further draw-screens happening. https://github.com/malcolmstill/ulubis/blob/133479a7e32fd3378c90e95aa8c7c9fd721e393a/ulubis.lisp#L66 When the page flip callback fires, the flag is set to false, allowing further draw-screen calls to occur (though when these next draw-screen calls we do not know).

I tried rethinking the DRM/KMS render loop in https://github.com/malcolmstill/ulubis/tree/main-loop-with-draw-screen-in-page-flip-callback and https://github.com/malcolmstill/ulubis-drm-gbm/tree/draw-screen-in-page-flip-callback. In these the page flip callback is fired and the next screen is immediately drawn. I didn't notice any improvement.

For point 2. I need to do some timing. I have had inconsistent results depending on how I do it ranging from around 1 millisecond up to 17 milliseconds (the former would be fine that latter not so much...60 FPS is 16 milliseconds per frame).

In terms of point 3., I wonder if instead of creating the 60 FPS Wayland timer, we simply set up a vblank callback when we have one or more animations queued. This would prevent aliasing (if that were an issue) between the Wayland timer and our screen refreshes.

malcolmstill commented 6 years ago

You can see we're dropping frames:

stuttering

The top row indicates the start / end of an animation. The middle row is render events. The bottom row is page flip callbacks.

malcolmstill commented 6 years ago

The draw times (OpenGL calls) range from around 1 - 4 milliseconds, which don't seem like long enough unless they occur close to vblanks.

malcolmstill commented 6 years ago

The draw times (OpenGL calls) range from around 1 - 4 milliseconds, which don't seem like long enough unless they occur close to vblanks.

The changes in https://github.com/malcolmstill/ulubis/tree/main-loop-with-draw-screen-in-page-flip-callback should start the draws immediately after a flip so shouldn't occur close to vblank. As that branch didn't show any improvement I'm doubting that this is the problem.