<div dir="ltr">Hi Scott,<div><br></div><div>Thanks - memfd_create looks like a good option.  I think I'll switch to that and fall back if it's not available.</div><div><br></div><div>Sounds like one pool per window is the way to go...  really didn't feel like implementing a heap allocator.</div><div><br></div><div>Brad</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jun 19, 2020 at 1:55 PM Scott Anderson <<a href="mailto:scott.anderson@collabora.com">scott.anderson@collabora.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 19/06/20 3:24 pm, Brad Robinson wrote:<br>
> Hi All,<br>
> <br>
> I'm fairly new to Wayland and Linux GUI programming in general, but <br>
> doing some experiments to figure out how to integrate it into my custom <br>
> UI toolkit library and have a couple of questions about client side <br>
> buffer management.<br>
> <br>
> Firstly, this is how I'm allocating the backing memory for client side <br>
> buffer pools.  This is C# p-invoking to libc, and basically it's using <br>
> mkstemp() to get a temp file, ftruncate() to set its length, mmap() to <br>
> map it and then unlink() once mapped so temp files aren't left behind.  <br>
> Any issues with this approach?<br>
> <br>
>              // Get temp file<br>
>              var sb = new <br>
> StringBuilder(System.IO.Path.Join(System.IO.Path.GetTempPath(), <br>
> "mmXXXXXX"));<br>
>              int fd = mkstemp(sb);<br>
>              ftruncate(fd, (ulong)capacity);<br>
> <br>
>              // Map it<br>
>              var addr = mmap(IntPtr.Zero, (ulong)capacity, Prot.Read | <br>
> Prot.Write, Map.Shared, fd, 0);<br>
> <br>
>              // Unlink it (so temp files not left behind)<br>
>              unlink(sb.ToString());<br>
<br>
An alternative implementation would be to use memfd_create, but that is <br>
Linux-specific. Otherwise what you have there looks correct to me.<br>
<br>
> Secondly I'm wondering about practical strategies for managing client <br>
> side buffers.  The toolkit in question basically needs arbitrarily sized <br>
> buffers to render whatever size the window happens to be.  Seems like to <br>
> use a buffer pool for this would require some sort of heap manager to <br>
> manage what's in each pool.  I'm wondering if there's any <br>
> recommendations or best practices for how to deal with this.  eg: create <br>
> one big pool and explicitly manage what's in there as a heap, use lots <br>
> of little pools with one buffer in each, a combination of both, <br>
> something else?<br>
<br>
It would be possible to deal use heaps, but in practice most clients <br>
will just use a dedicated shared memory object (wl_shm_pool) for each <br>
buffer, which works perfectly fine. Shared memory clients usually only <br>
need 2 buffers, but it's a good idea to write your program in a way so <br>
that it can use up to 4, allocating the extra as needed, and freeing <br>
them when you're done.<br>
<br>
> Finally, the toolkit already maintains an off-screen buffer with the <br>
> window's current contents rendered into it.  I'll probably replace that <br>
> with a Wayland buffer, but wondering about partial updates.  eg: if the <br>
> client only needs to redraw a part of the window what's the correct <br>
> process to update just that part with Wayland.  Can I just update the <br>
> existing buffer and prompt Wayland to just redraw that part?<br>
<br>
There are requests in the protocol specifically for telling the <br>
compositor about partial updates, which are wl_surface.damage and <br>
wl_surface.damage_buffer. Using wl_surface.damage_buffer is generally a <br>
better idea.<br>
<br>
Here is a blog post that goes over some more general details: <br>
<a href="https://emersion.fr/blog/2019/intro-to-damage-tracking/" rel="noreferrer" target="_blank">https://emersion.fr/blog/2019/intro-to-damage-tracking/</a><br>
It's slightly more slanted to talking about the compositor side of <br>
things, but I still think could be helpful.<br>
<br>
Scott<br>
<br>
> Any advice appreciated...<br>
> <br>
> Brad<br>
<br>
</blockquote></div>