idle tasks starving in toytoolkit

Pekka Paalanen ppaalanen at
Fri Sep 27 00:26:36 PDT 2013

On Thu, 26 Sep 2013 16:59:13 +0200
Tomeu Vizoso <tomeu at> wrote:

> Hi,
> somewhat related to the issue of posting vs. queuing buffer.release event
> is a condition I have found that starves idle handlers in window.c.
> If the SwapBuffers implementation waits for buffer.release events to make
> sure that the GPU doesn't overwrite the front buffer and the client
> performs its rendering on the frame callback (for example, the subsurface
> example), the following happens:
> 1. window.c calls wl_display_dispatch, which in turn calls dispatch_queue
> and eventually the client's frame callback handler
> 2. client executes GL commands
> 3. client registers a new frame callback
> 4. client calls SwapBuffers
> 5. in SwapBuffers, wl_display_dispatch_queue is called while waiting for
> buffer.release
> 6. once buffer.release comes, a new frame event has been read from the fd
> and placed in the main queue
> 7. control is returned to dispatch_queue which dispatches the new frame
> event, going back to 2
> Thus control never returns to the main loop and no other idle tasks are
> ever ran.


I want to give some additional details of this specific case on RPi, in
case people want to know what is going on in the compositor, as it
might not be obvious.

All EGL buffers on RPi are always scanout buffers. This means that
buffers can only be released from finish_frame, if they have entered
the screen (repaint).

When a client does attach,damage,frame,commit on a surface, and the
compositor enters repaint, the new buffer is scheduled in the firmware
to go on screen, and the frame callback is sent. Later when the screen
update finishes (finish_frame), the old buffer is released. IOW, the
new frame callback is triggered always before the old buffer's release.

In the RPi EGL Wayland platform code (i.e. the EGL client side), the
number of buffers per EGLSurface is limited to two. I know there may be
some corner cases with sub-surfaces and swapinterval=0 where two might
not be enough, but in general two should suffice.

Having only two buffers, and the firmware requiring a new buffer every
time the old one is "finalized" (a firmware RPC similar to
eglSwapBuffers), means that eglSwapBuffers() must post the rendered
buffer and wait for the old buffer on screen to be released before it
can return.

All these "coincidences" together guarantee, that the current event
loop in toytoolkit will never reach the idle tasks, if EGL/GL rendering
happens from within the frame callback handler.

I guess the obvious question then is, why does subsurfaces demo render
in a frame callback handler? I'm starting to think the problem in this
specific case is in the application, but it still does not void the
concern about the dispatch loop possibly never returning.


More information about the wayland-devel mailing list