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