Best practices for client side buffer management

Scott Anderson scott.anderson at collabora.com
Fri Jun 19 03:55:00 UTC 2020


On 19/06/20 3:24 pm, Brad Robinson wrote:
> Hi All,
> 
> I'm fairly new to Wayland and Linux GUI programming in general, but 
> doing some experiments to figure out how to integrate it into my custom 
> UI toolkit library and have a couple of questions about client side 
> buffer management.
> 
> Firstly, this is how I'm allocating the backing memory for client side 
> buffer pools.  This is C# p-invoking to libc, and basically it's using 
> mkstemp() to get a temp file, ftruncate() to set its length, mmap() to 
> map it and then unlink() once mapped so temp files aren't left behind.  
> Any issues with this approach?
> 
>              // Get temp file
>              var sb = new 
> StringBuilder(System.IO.Path.Join(System.IO.Path.GetTempPath(), 
> "mmXXXXXX"));
>              int fd = mkstemp(sb);
>              ftruncate(fd, (ulong)capacity);
> 
>              // Map it
>              var addr = mmap(IntPtr.Zero, (ulong)capacity, Prot.Read | 
> Prot.Write, Map.Shared, fd, 0);
> 
>              // Unlink it (so temp files not left behind)
>              unlink(sb.ToString());

An alternative implementation would be to use memfd_create, but that is 
Linux-specific. Otherwise what you have there looks correct to me.

> Secondly I'm wondering about practical strategies for managing client 
> side buffers.  The toolkit in question basically needs arbitrarily sized 
> buffers to render whatever size the window happens to be.  Seems like to 
> use a buffer pool for this would require some sort of heap manager to 
> manage what's in each pool.  I'm wondering if there's any 
> recommendations or best practices for how to deal with this.  eg: create 
> one big pool and explicitly manage what's in there as a heap, use lots 
> of little pools with one buffer in each, a combination of both, 
> something else?

It would be possible to deal use heaps, but in practice most clients 
will just use a dedicated shared memory object (wl_shm_pool) for each 
buffer, which works perfectly fine. Shared memory clients usually only 
need 2 buffers, but it's a good idea to write your program in a way so 
that it can use up to 4, allocating the extra as needed, and freeing 
them when you're done.

> Finally, the toolkit already maintains an off-screen buffer with the 
> window's current contents rendered into it.  I'll probably replace that 
> with a Wayland buffer, but wondering about partial updates.  eg: if the 
> client only needs to redraw a part of the window what's the correct 
> process to update just that part with Wayland.  Can I just update the 
> existing buffer and prompt Wayland to just redraw that part?

There are requests in the protocol specifically for telling the 
compositor about partial updates, which are wl_surface.damage and 
wl_surface.damage_buffer. Using wl_surface.damage_buffer is generally a 
better idea.

Here is a blog post that goes over some more general details: 
https://emersion.fr/blog/2019/intro-to-damage-tracking/
It's slightly more slanted to talking about the compositor side of 
things, but I still think could be helpful.

Scott

> Any advice appreciated...
> 
> Brad



More information about the wayland-devel mailing list