Recursive call of wl_display_iterate via frame callback
krh at bitplanet.net
Tue Jun 21 08:10:29 PDT 2011
On Tue, Jun 21, 2011 at 10:15 AM, Fiedler, Mathias
<Mathias.Fiedler at xse.de> wrote:
> while playing around with wayland and the simple-client demo (using EGL) i ran into issues where simple-client were caught in an endless loop in wl_display_iterate. The issue seems to be a recursive call of wl_display_iterate.
> The simple-client registers redraw() as a callback function to key event. This function gets called during wl_display_iterate when corresponding key event arrives. The redraw function itself calls eglSwapBuffers. Since eglSwapBuffers() might need to synchronize with the compositor, it might also call wl_display_iterate.
> -> handle_event
> -> wl_closure_invoke
> -> display_handle_key
> -> redraw
> -> eglSwapBuffers
> -> wl_display_iterate
> As long as the key event is the last message in input buffer the while loop in the former call to wl_display_iterate will terminate. But if another message is pending this message will be processed by the latter call to wl_display_iterate and the local variable len in former call to wl_display_iterate won't decrement to zero.
> Is this a bug, or did i miss something?
> What should be the correct usage of wl_display_frame_callback() and wl_display_iterate()?
Calling wl_display_iterate() from within EGL is a little problematic
and something we may have to find a better solution to. But typically
you shouldn't get into that case, as you shouldn't immediately redraw.
Toolkits normally draw in an "idle handler" (you can use
wl_event_loop_add_idle), which triggers when there is no more IO (ie
events) to process. That means that the redraw function is called
directly from the event loop and not the mouse or keyboard handler.
This breaks the recursion and additionally lets the app queue up
several input events (ie, you act on the final position of a series of
motion events instead of each of them).
The other important point is that repainting should be throttled to
the compositor repaint loop. The compositor sends out the frame event
every time it draws a frame, and there's no point in the application
drawing faster than that. So scheduling a repaint in response to
input events using an idle handler is fine, but if you're doing an
animation, you need to use wl_display_frame_callback() to schedule a
callback per frame.
More information about the wayland-devel