Re: Best practices for client side buffer management

2020-06-19 Thread Brad Robinson
Hi Carsten,


> i assume GetTempPath() will be looking at /tmp ... and /tmp may not be a
> ramdisk. it may be a real disk... in which case your buffers may be getting
> written to an actual disk. don't use /tmp.
>

That's kind of what was in the back of my head when I decided to post this,
but being new to Linux dev thought it might have been a silly question and
wasn't sure how to express it.  Going to switch to memfd_create for now.


> resizes of windows are less common (in general) than rendering to them.
> here
> i'd go for a scheme of N buffers in a ring per window. so you have buffers
> A,
> B, C and you first render to A then display it, then next frame B, then C,
> then
> A, then B, then C. You could get away without C. as the buffers retain
> their
> state you can take advantage of this and only partially render part of a
> buffer for updates "since 1 or 2 frames ago" (depending if you do double or
> triple buffering). as its predictable ABCABCABC you can just keep a
> "Sliding
> window of the update regions of the past N frames" and merge those into the
> "current amount to update" but always store per-frame update rectangle
> regions
> before this merge-at-render-time. 3 buffers allows you to be rendering a
> 3rd
> buffer while 1 buffer is queued to be displayed and one is still being
> displayed. if you find you need a 4th buffer, perhaps just overdraw the
> 3rd on
> you just did and "update it" ... or just block or don't update yet as you
> are
> getting too far ahead of the compositor.
>
> > 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?
>
> no. never do that. always have more than 1 and update a buffer that is not
> being displayed or queued to be displayed. the above sliding window allows
> your
> partial rendering to work as you can depend on previous content still being
> there where you left it from N frames ago.
>
>
OK thanks - that's pointing me in the right direction.  I have questions
about all this, but I don't want to waste your time until I've had time to
dig into it myself first.

(I'm a bit slow with all this because it's an evening side project and I'm
doing it in C# and trying to get the protocol bindings and libc pinvoke
functions all wired up at the same time as figuring out how it all works).

Brad
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: Best practices for client side buffer management

2020-06-19 Thread Brad Robinson
Hi Scott,

Thanks - memfd_create looks like a good option.  I think I'll switch to
that and fall back if it's not available.

Sounds like one pool per window is the way to go...  really didn't feel
like implementing a heap allocator.

Brad


On Fri, Jun 19, 2020 at 1:55 PM Scott Anderson 
wrote:

> 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(),
> > "mmXX"));
> >  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
>
>
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: Best practices for client side buffer management

2020-06-19 Thread The Rasterman
On Fri, 19 Jun 2020 13:24:12 +1000 Brad Robinson 
said:

> 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(),
> "mmXX"));
> int fd = mkstemp(sb);
> ftruncate(fd, (ulong)capacity);

i assume GetTempPath() will be looking at /tmp ... and /tmp may not be a
ramdisk. it may be a real disk... in which case your buffers may be getting
written to an actual disk. don't use /tmp.

you might wan to to loop at shm_open or memfd or libdrm for specific drivr
allocation calls like drm_intel_bo_alloc_tiled, drm_intel_bo_map/unmap etc. the
latter libdrm ones wo9uld allow your buffers to possibly be scanned out
directly to the screen or used as textures directly without copies, but will
need careful handling, so do this only as an advanced step.

> // 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());
> 
> 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?

resizes of windows are less common (in general) than rendering to them. here
i'd go for a scheme of N buffers in a ring per window. so you have buffers A,
B, C and you first render to A then display it, then next frame B, then C, then
A, then B, then C. You could get away without C. as the buffers retain their
state you can take advantage of this and only partially render part of a
buffer for updates "since 1 or 2 frames ago" (depending if you do double or
triple buffering). as its predictable ABCABCABC you can just keep a "Sliding
window of the update regions of the past N frames" and merge those into the
"current amount to update" but always store per-frame update rectangle regions
before this merge-at-render-time. 3 buffers allows you to be rendering a 3rd
buffer while 1 buffer is queued to be displayed and one is still being
displayed. if you find you need a 4th buffer, perhaps just overdraw the 3rd on
you just did and "update it" ... or just block or don't update yet as you are
getting too far ahead of the compositor.

> 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?

no. never do that. always have more than 1 and update a buffer that is not
being displayed or queued to be displayed. the above sliding window allows your
partial rendering to work as you can depend on previous content still being
there where you left it from N frames ago.

> Any advice appreciated...
> 
> Brad


-- 
- Codito, ergo sum - "I code, therefore I am" --
Carsten Haitzler - ras...@rasterman.com

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH libinput 4/4] touchpad: change manual calculations of dimensions to helper functions

2020-06-19 Thread deb ackman
What that means??
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel