[Wayland] Enable full GL async rendering
Categories
(Core :: Widget: Gtk, enhancement, P3)
Tracking
()
People
(Reporter: stransky, Unassigned)
References
(Blocks 1 open bug)
Details
Right now we do synced stop/resume GL rendering when a window is hidden. It's because underlying wl_surface is deleted (Wayland hides surfaces by deleting them) and any rendering to it causes protocol error.
Let's investigate possibility to keep wl_subsurface live after unmap so we can keep rendering by GL to hidden (detached) wl_surface. We may reuse the same wl_surface again when a window becomes visible so we may not need to force resume GL rendering pipeline.
| Reporter | ||
Comment 1•1 year ago
|
||
In such case we'd need to update rendering to parent surface (D&D popup) as it doesn't supports subsurfaces - we may force SW rendering to it.
Comment 2•1 year ago
|
||
(In reply to Martin Stránský [:stransky] (ni? me) from comment #0)
Right now we do synced stop/resume GL rendering when a window is hidden. It's because underlying wl_surface is deleted (Wayland hides surfaces by deleting them) and any rendering to it causes protocol error.
Let's investigate possibility to keep wl_subsurface live after unmap so we can keep rendering by GL to hidden (detached) wl_surface.
Hiding a wl_surface doesn't require destroying it. Something like
wl_surface_attach(surface, NULL, 0, 0);
wl_surface_commit(surface);
should suffice to unmap / hide the surface.
Note that e.g. eglSwapBuffers will internally attach and commit a non-NULL buffer, which will map / unhide the surface again.
| Reporter | ||
Comment 3•1 year ago
|
||
Yeah, unfortunately Gtk3 deletes wl_surface attached to GtkWidget on unmap so the null buffer trick can't be used here. But that may affects D&D popups only which can be solved by SW rendering.
The null buffer trick doesn't work if sl_surface is used by more rendering threads for async rendering - it may be hid by main thread (UI) and then quickly repainted from rendering one and perhaps hidden again. Detached subsurface may be hidden even with valid wl_buffer attached which allows rendering thread to flush painting without flickering.
Comment 4•1 year ago
|
||
(In reply to Martin Stránský [:stransky] (ni? me) from comment #3)
The null buffer trick doesn't work if sl_surface is used by more rendering threads for async rendering - it may be hid by main thread (UI) and then quickly repainted from rendering one and perhaps hidden again.
Sounds like a synchronization issue. Per the Wayland design, a single entity must be responsible for submitting commits for a given wl_surface at any time. Trying to submit commits from multiple threads in parallel risks running into protocol errors sooner or later.
Detached subsurface may be hidden even with valid wl_buffer attached which allows rendering thread to flush painting without flickering.
Not sure what you mean by "detached subsurface".
FWIW, another possibility for hiding a sub-surface is to put it behind its parent surface using wl_subsurface_place_below.
| Reporter | ||
Comment 5•1 year ago
|
||
(In reply to Michel Dänzer from comment #4)
(In reply to Martin Stránský [:stransky] (ni? me) from comment #3)
The null buffer trick doesn't work if sl_surface is used by more rendering threads for async rendering - it may be hid by main thread (UI) and then quickly repainted from rendering one and perhaps hidden again.
Sounds like a synchronization issue. Per the Wayland design, a single entity must be responsible for submitting commits for a given
wl_surfaceat any time. Trying to submit commits from multiple threads in parallel risks running into protocol errors sooner or later.
Not in parallel, we use a lock to access the wl_surface.
Detached subsurface may be hidden even with valid wl_buffer attached which allows rendering thread to flush painting without flickering.
Not sure what you mean by "detached subsurface".
I mean to delete wl_subsurface interface of wl_surface (wl_subsurface::destroy). wl_surface may be unmapped but AFAIK still valid wayland object which can be accessed / referenced.
FWIW, another possibility for hiding a sub-surface is to put it behind its parent surface using
wl_subsurface_place_below.
Well, parent surface is deleted in this case by GtkWidget unmap.
Comment 6•1 year ago
|
||
(In reply to Martin Stránský [:stransky] (ni? me) from comment #5)
I mean to delete wl_subsurface interface of wl_surface (wl_subsurface::destroy). wl_surface may be unmapped but AFAIK still valid wayland object which can be accessed / referenced.
I see, yes AFAIK that should work, and a new wl_subsurface can later be created for the same wl_surface again. (This is uncommon usage, so might hit bugs in some compositors though)
| Reporter | ||
Updated•6 months ago
|
Description
•