xwayland/window-buffers: Use synchronization from GLAMOR/GBM

Now that we have the buffer synchronization implemented in the
GLAMOR/GBM code, switch to use that code.

At this point, there is still not functional change intended, this is
still preparation work for a fix that is still to come.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1571>
This commit is contained in:
Olivier Fourdan 2024-06-18 11:26:26 +02:00 committed by Marge Bot
parent cc021aca99
commit 256cef8b20

View File

@ -31,6 +31,7 @@
#include "xwayland-window.h"
#include "xwayland-pixmap.h"
#include "xwayland-screen.h"
#include "xwayland-glamor-gbm.h"
#include "xwayland-window-buffers.h"
#ifdef XWL_HAS_GLAMOR
#include "glamor.h"
@ -47,11 +48,6 @@ struct xwl_window_buffer {
struct xwl_window *xwl_window;
PixmapPtr pixmap;
RegionPtr damage_region;
#ifdef XWL_HAS_GLAMOR
struct dri3_syncobj *syncobj;
uint64_t timeline_point;
int efd;
#endif /* XWL_HAS_GLAMOR */
int refcnt;
uint32_t time;
struct xorg_list link_buffer;
@ -90,9 +86,6 @@ xwl_window_buffer_new(struct xwl_window *xwl_window)
xwl_window_buffer->damage_region = RegionCreate(NullBox, 1);
xwl_window_buffer->pixmap = NullPixmap;
xwl_window_buffer->refcnt = 1;
#ifdef XWL_HAS_GLAMOR
xwl_window_buffer->efd = -1;
#endif /* XWL_HAS_GLAMOR */
xorg_list_init(&xwl_window_buffer->link_buffer);
@ -119,18 +112,12 @@ xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
RegionDestroy(xwl_window_buffer->damage_region);
if (xwl_window_buffer->pixmap)
xwl_window_buffer_destroy_pixmap (xwl_window_buffer);
if (xwl_window_buffer->pixmap) {
#ifdef XWL_HAS_GLAMOR
if (xwl_window_buffer->syncobj)
xwl_window_buffer->syncobj->free(xwl_window_buffer->syncobj);
if (xwl_window_buffer->efd >= 0) {
SetNotifyFd(xwl_window_buffer->efd, NULL, 0, NULL);
close(xwl_window_buffer->efd);
}
xwl_glamor_gbm_dispose_syncpts(xwl_window_buffer->pixmap);
#endif /* XWL_HAS_GLAMOR */
xwl_window_buffer_destroy_pixmap (xwl_window_buffer);
}
xorg_list_del(&xwl_window_buffer->link_buffer);
free(xwl_window_buffer);
@ -244,20 +231,6 @@ xwl_window_buffer_release(struct xwl_window_buffer *xwl_window_buffer)
xwl_window_buffer_release_callback(xwl_window_buffer);
}
#ifdef XWL_HAS_GLAMOR
static void
xwl_window_buffers_release_fence_avail(int fd, int xevents, void *data)
{
struct xwl_window_buffer *xwl_window_buffer = data;
SetNotifyFd(fd, NULL, 0, NULL);
close(fd);
xwl_window_buffer->efd = -1;
xwl_window_buffer_release_callback(data);
}
#endif /* XWL_HAS_GLAMOR */
void
xwl_window_buffers_init(struct xwl_window *xwl_window)
{
@ -376,46 +349,6 @@ xwl_window_realloc_pixmap(struct xwl_window *xwl_window)
screen->DestroyPixmap(window_pixmap);
}
#ifdef XWL_HAS_GLAMOR
static Bool
xwl_window_buffers_set_syncpts(struct xwl_window_buffer *xwl_window_buffer)
{
struct xwl_window *xwl_window = xwl_window_buffer->xwl_window;
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
uint64_t acquire_point = ++xwl_window_buffer->timeline_point;
uint64_t release_point = ++xwl_window_buffer->timeline_point;
if (!xwl_window_buffer->syncobj) {
struct dri3_syncobj *syncobj = xwl_glamor_dri3_syncobj_create(xwl_screen);
if (!syncobj)
goto fail;
xwl_window_buffer->syncobj = syncobj;
}
int fence_fd = xwl_glamor_get_fence(xwl_screen);
if (fence_fd >= 0)
xwl_window_buffer->syncobj->import_fence(xwl_window_buffer->syncobj,
acquire_point, fence_fd);
else
goto fail;
xwl_glamor_dri3_syncobj_passthrough(xwl_window,
xwl_window_buffer->syncobj,
xwl_window_buffer->syncobj,
acquire_point,
release_point);
return TRUE;
fail:
/* can't use explicit sync, we will do a glFinish() before presenting */
if (xwl_window_buffer->syncobj) {
xwl_window_buffer->syncobj->free(xwl_window_buffer->syncobj);
xwl_window_buffer->syncobj = NULL;
}
return FALSE;
}
#endif /* XWL_HAS_GLAMOR */
PixmapPtr
xwl_window_swap_pixmap(struct xwl_window *xwl_window)
{
@ -434,17 +367,9 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
RegionPtr full_damage = xwl_window_buffer->damage_region;
BoxPtr pBox = RegionRects(full_damage);
int nBox = RegionNumRects(full_damage);
#ifdef XWL_HAS_GLAMOR
if (xwl_window_buffer->syncobj) {
int fence_fd =
xwl_window_buffer->syncobj->export_fence(xwl_window_buffer->syncobj,
xwl_window_buffer->timeline_point);
xwl_glamor_wait_fence(xwl_screen, fence_fd);
close(fence_fd);
}
xwl_glamor_gbm_wait_syncpts(xwl_window_buffer->pixmap);
#endif /* XWL_HAS_GLAMOR */
while (nBox--) {
copy_pixmap_area(window_pixmap,
xwl_window_buffer->pixmap,
@ -485,22 +410,18 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
#ifdef XWL_HAS_GLAMOR
if (!xwl_glamor_supports_implicit_sync(xwl_screen)) {
if (xwl_screen->explicit_sync && xwl_window_buffers_set_syncpts(xwl_window_buffer)) {
if (xwl_screen->explicit_sync && xwl_glamor_gbm_set_syncpts(xwl_window, window_pixmap)) {
implicit_sync = FALSE;
/* wait until the release fence is available before re-using this buffer */
xwl_window_buffer->efd = eventfd(0, EFD_CLOEXEC);
SetNotifyFd(xwl_window_buffer->efd, xwl_window_buffers_release_fence_avail,
X_NOTIFY_READ, xwl_window_buffer);
xwl_window_buffer->syncobj->submitted_eventfd(xwl_window_buffer->syncobj,
xwl_window_buffer->timeline_point,
xwl_window_buffer->efd);
} else
xwl_glamor_gbm_wait_release_fence(xwl_window, window_pixmap, xwl_window_buffer);
} else {
/* If glamor does not support implicit sync and we can't use
* explicit sync, wait for the GPU to be idle before presenting.
* Note that buffer re-use will still be unsynchronized :(
*/
glamor_finish(xwl_screen->screen);
}
}
#endif /* XWL_HAS_GLAMOR */
if (implicit_sync) {