[PATCH weston v3 07/13] window: implement shm triple-buffering

Pekka Paalanen ppaalanen at gmail.com
Fri Apr 26 00:47:24 PDT 2013


On Thu, 25 Apr 2013 12:34:13 -0700
Bill Spitzak <spitzak at gmail.com> wrote:

> Pekka Paalanen wrote:
> 
> > Triple-buffering is especially for sub-surfaces, where the
> > compositor may have one wl_buffer busy on screen, and another
> > wl_buffer busy in the sub-surface cached state due to the
> > synchronized commit mode. To be able to forcibly repaint at that
> > situation for e.g. resize, we need a third buffer.
> 
> I cannot see any difference between a subsurface waiting for a commit
> on a parent and a normal surface that has not done a commit yet.
> There is no need for triple buffering, or if there is it is not a
> subsurface requirement.

In the server, there are three slots per sub-surface, that may hold a
wl_buffer reference: the current buffer on display, the pending buffer
waiting for commit, and the cached buffer waiting for the parent commit.

Having a buffer in the pending slot does not actually count as the
buffer being reserved for the server. Instead, the current slot may
temporarily hold two buffers at the same time: before compositor
refresh cycle completes, the old current buffer may be kept by the
renderer and backend, and the new current buffer is just waiting to get
on screen.

When a sub-surface is committed (wl_surface.commit), the buffer in
pending is moved to either the current or the cache slot, depending on
the effective commit mode, and the buffer becomes reserved by the
server.

This should be clear in the protocol specification.

If the target is the cache slot, the previous buffer (if any) in the
cache slot is released. If the target is the current slot, the previous
buffer (if any) in the current slot will be released when the
compositor refresh cycle completes.

When the parent's current buffer gets replaced (that is, when the new
surface state is _applied_), each of its sub-surfaces' cached buffer is
moved to the current slot (new state is applied), depending on the
effective commit mode.

Why we should not need *four* buffers is because the application should
throttle its resizing to the server refresh cycle by using the frame
callback on one of the window's surfaces. This guarantees that the old
current buffer gets released, before the application repaints again.

Just to clarify, the four buffer case would be this:
- buffer A is currently on screen, the old current, because the
  renderer or backend needs it continuously (e.g. directly scanned out)
- buffer B is going to screen, the new current
- buffer C is in the cache slot, because it is waiting for the parent
  commit to apply state, and this sub-surface is in synchronized mode
- buffer D is being drawn into
This is a temporary state, where buffer A is soon released, but the
unthrottled client decided to draw before that, so it needs buffer D.

> What do you mean by "forcibly repaint for resize"? Resizes of windows 
> cannot happen until the client produces a new buffer with the resized 
> contents and does a commit. Otherwise it has to keep showing the old 
> buffer. Unless you really want to reproduce the biggest ugliness
> problem with X?

This is all *inside* the client. This is a toolkit patch.

The canonical use case for a sub-surface is an application, which has a
main surface, and a component in a sub-surface. The forcing is about the
application forcing the component to redraw in a new size.


Thanks,
pq


More information about the wayland-devel mailing list