Closed Bug 1943518 Opened 1 year ago Closed 6 months ago

[Wayland] Enable full GL async rendering

Categories

(Core :: Widget: Gtk, enhancement, P3)

enhancement

Tracking

()

RESOLVED DUPLICATE of bug 1739232

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.

Flags: needinfo?(stransky)

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.

(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.

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.

(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.

(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_surface at 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.

(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)

See Also: → 1986262
Status: NEW → RESOLVED
Closed: 6 months ago
Duplicate of bug: 1739232
Flags: needinfo?(stransky)
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.