Process for implementing a double buffer on Wayland

Pekka Paalanen ppaalanen at gmail.com
Thu Nov 26 00:40:20 PST 2015


On Wed, 25 Nov 2015 21:43:49 +0100
Hardening <rdp.effort at gmail.com> wrote:

> Le 25/11/2015 17:18, Daniel Stone a écrit :
> > Hi Mike,
> > 
> > On 25 November 2015 at 16:06, Mike Johnson <mikeyj001 at hotmail.com> wrote:  
> >> I've created 2 buffers of the same size (800x600 pixels).  So I want the
> >> input buffer to get filled off-screen, while the output buffer will show the
> >> content on-screen.
> >>
> >> First of all what sort of content could be used to illustrate this
> >> technique, and secondly, what mechanisms are available to:
> >>
> >> a) Notify that the input buffer is full
> >> b) Copy the content to the output buffer so that it shows on-screen  
> > 
> > It's quite simple. wl_surface_attach(surf, buf) +
> > wl_surface_commit(surf) will display 'buf' for that surface. At that
> > point, the compositor owns that buffer, so you should stop drawing on
> > it. When the compositor has finished with a buffer, it will send you a
> > wl_buffer.release event. You can sync your paint clock to the
> > compositor's repaint loop with wl_surface_frame.
> > 
> > So, the normal workflow is:
> >   - create surface S, buffer A, buffer B
> >   - draw first frame into buffer A
> >   - call wl_surface_frame(S) + wl_surface_attach(S, A) +
> > wl_surface_commit(S) + wl_display_flush()
> >   - go to sleep
> >   - receive completion for wl_surface_frame callback
> >   - draw second frame into buffer B
> >   - call wl_surface_frame(S) + wl_surface_attach(S, B) +
> > wl_surface_commit(S) + wl_display_flush()
> >   - compositor now owns both buffers, so don't touch any
> >   - receive wl_buffer.release event for buffer A - now unused
> >   - receive completion for wl_surface_frame callback
> >   - draw third frame into buffer A
> >   - ...
> >   
> 
> I may be wrong, but there's no guaranty that the compositor sends
> wl_buffer.release event on buffer A. I think I have experimented this
> when the renderer in weston is the pixman renderer.
> IIRC I have been told on IRC that the compositor decides when the buffer
> is not used, so you may not receive the release message immediately. I
> have hit that kind of bug when coding libUWAC.

You are definitely right if you don't commit buffer B.

When you have committed buffer B, the compositor eventually will
release buffer A if it had not already, but there are some exceptions
too. One is on certain circumstances when using a sub-surface.


Mike,

essentially one should decouple the buffer management from the repaint
cycle, like simple-shm.c does.

The reply to wl_surface.frame tells you when it is appropriate to draw
a new frame after the previous one. Whenever you decide to draw a new
frame, check your buffer pool for available buffers (I mean a collection
of wl_buffers, not wl_shm_pool). If none are available, create a new
buffer to draw into, or in some cases you can wait for a buffer become
available again.

When a buffer is created, it is naturally available to be drawn into.
Using wl_surface.attach and wl_surface.commit with the buffer makes it
reserved by the server, unavailable, until you receive a
wl_buffer.release event making it available again.

When you follow these rules, you get adaptive buffering. You'll only
ever use just one buffer if possible, and use more if necessary to
achieve glitch-free output. Double-buffering in the client is not
always mandatory to achieve the effect of double-buffering, because the
server might be buffering too.


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 811 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20151126/c0c5dffc/attachment.sig>


More information about the wayland-devel mailing list