<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'><br><br><div>> Date: Thu, 26 Nov 2015 10:40:20 +0200<br>> From: ppaalanen@gmail.com<br>> To: rdp.effort@gmail.com; mikeyj001@hotmail.com<br>> CC: wayland-devel@lists.freedesktop.org; daniel@fooishbar.org<br>> Subject: Re: Process for implementing a double buffer on Wayland<br>> <br>> On Wed, 25 Nov 2015 21:43:49 +0100<br>> Hardening <rdp.effort@gmail.com> wrote:<br>> <br>> > Le 25/11/2015 17:18, Daniel Stone a écrit :<br>> > > Hi Mike,<br>> > > <br>> > > On 25 November 2015 at 16:06, Mike Johnson <mikeyj001@hotmail.com> wrote: <br>> > >> I've created 2 buffers of the same size (800x600 pixels). So I want the<br>> > >> input buffer to get filled off-screen, while the output buffer will show the<br>> > >> content on-screen.<br>> > >><br>> > >> First of all what sort of content could be used to illustrate this<br>> > >> technique, and secondly, what mechanisms are available to:<br>> > >><br>> > >> a) Notify that the input buffer is full<br>> > >> b) Copy the content to the output buffer so that it shows on-screen <br>> > > <br>> > > It's quite simple. wl_surface_attach(surf, buf) +<br>> > > wl_surface_commit(surf) will display 'buf' for that surface. At that<br>> > > point, the compositor owns that buffer, so you should stop drawing on<br>> > > it. When the compositor has finished with a buffer, it will send you a<br>> > > wl_buffer.release event. You can sync your paint clock to the<br>> > > compositor's repaint loop with wl_surface_frame.<br>> > > <br>> > > So, the normal workflow is:<br>> > > - create surface S, buffer A, buffer B<br>> > > - draw first frame into buffer A<br>> > > - call wl_surface_frame(S) + wl_surface_attach(S, A) +<br>> > > wl_surface_commit(S) + wl_display_flush()<br>> > > - go to sleep<br>> > > - receive completion for wl_surface_frame callback<br>> > > - draw second frame into buffer B<br>> > > - call wl_surface_frame(S) + wl_surface_attach(S, B) +<br>> > > wl_surface_commit(S) + wl_display_flush()<br>> > > - compositor now owns both buffers, so don't touch any<br>> > > - receive wl_buffer.release event for buffer A - now unused<br>> > > - receive completion for wl_surface_frame callback<br>> > > - draw third frame into buffer A<br>> > > - ...<br>> > > <br>> > <br>> > I may be wrong, but there's no guaranty that the compositor sends<br>> > wl_buffer.release event on buffer A. I think I have experimented this<br>> > when the renderer in weston is the pixman renderer.<br>> > IIRC I have been told on IRC that the compositor decides when the buffer<br>> > is not used, so you may not receive the release message immediately. I<br>> > have hit that kind of bug when coding libUWAC.<br>> <br>> You are definitely right if you don't commit buffer B.<br>> <br>> When you have committed buffer B, the compositor eventually will<br>> release buffer A if it had not already, but there are some exceptions<br>> too. One is on certain circumstances when using a sub-surface.<br>> <br>> <br>> Mike,<br>> <br>> essentially one should decouple the buffer management from the repaint<br>> cycle, like simple-shm.c does.<br>> <br>> The reply to wl_surface.frame tells you when it is appropriate to draw<br>> a new frame after the previous one. Whenever you decide to draw a new<br>> frame, check your buffer pool for available buffers (I mean a collection<br>> of wl_buffers, not wl_shm_pool). If none are available, create a new<br>> buffer to draw into, or in some cases you can wait for a buffer become<br>> available again.<br>> <br>> When a buffer is created, it is naturally available to be drawn into.<br>> Using wl_surface.attach and wl_surface.commit with the buffer makes it<br>> reserved by the server, unavailable, until you receive a<br>> wl_buffer.release event making it available again.<br>> <br>> When you follow these rules, you get adaptive buffering. You'll only<br>> ever use just one buffer if possible, and use more if necessary to<br>> achieve glitch-free output. Double-buffering in the client is not<br>> always mandatory to achieve the effect of double-buffering, because the<br>> server might be buffering too.<br>> <br>> <br>> Thanks,<br>> pq<br></div><div><br></div><div>Hi Pekka,</div><div><br></div><div>Thanks for your input. If I understand you correctly, you recommend creating buffers dynamically in the event there aren't any available to use in the shm pool. I can see how that would help the frame rate.</div><div><br></div><div>Thanks again for your comments guys. I have the info I need.</div><div>Best regards</div><div>Mike</div> </div></body>
</html>