xwayland/glamor/gbm: Copy explicit sync code to GLAMOR/GBM
Copy the code to deal with synchronization objects from the window buffers to the GLAMOR/GBM code. The idea is to deal with synchronizations for all pixmaps, even when there is no window buffer involved. This is still preparation work for the following commits, no functional change intended at this point. v2: Use a "xwl_window_buffer *" instead of a "void *data" (Michel) v3: Bail early if there's no xwl_window_buffer (Michel) v4: Rename xwl_window_submit_pixmap() to xwl_glamor_gbm_wait_release_fence() (Michel) Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1571>
This commit is contained in:
parent
b5082073b0
commit
cc021aca99
|
@ -32,6 +32,8 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <sys/eventfd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
|
@ -55,6 +57,7 @@
|
||||||
#include "xwayland-glamor-gbm.h"
|
#include "xwayland-glamor-gbm.h"
|
||||||
#include "xwayland-pixmap.h"
|
#include "xwayland-pixmap.h"
|
||||||
#include "xwayland-screen.h"
|
#include "xwayland-screen.h"
|
||||||
|
#include "xwayland-window-buffers.h"
|
||||||
|
|
||||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||||
#include "linux-drm-syncobj-v1-client-protocol.h"
|
#include "linux-drm-syncobj-v1-client-protocol.h"
|
||||||
|
@ -82,6 +85,12 @@ struct xwl_pixmap {
|
||||||
unsigned int texture;
|
unsigned int texture;
|
||||||
struct gbm_bo *bo;
|
struct gbm_bo *bo;
|
||||||
Bool implicit_modifier;
|
Bool implicit_modifier;
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *syncobj;
|
||||||
|
uint64_t timeline_point;
|
||||||
|
int efd;
|
||||||
|
struct xwl_window_buffer *xwl_window_buffer;
|
||||||
|
#endif /* DRI3 */
|
||||||
};
|
};
|
||||||
|
|
||||||
static DevPrivateKeyRec xwl_gbm_private_key;
|
static DevPrivateKeyRec xwl_gbm_private_key;
|
||||||
|
@ -225,6 +234,9 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
|
||||||
xwl_pixmap->bo = bo;
|
xwl_pixmap->bo = bo;
|
||||||
xwl_pixmap->buffer = NULL;
|
xwl_pixmap->buffer = NULL;
|
||||||
xwl_pixmap->implicit_modifier = implicit_modifier;
|
xwl_pixmap->implicit_modifier = implicit_modifier;
|
||||||
|
#ifdef XWL_HAS_GLAMOR
|
||||||
|
xwl_pixmap->efd = -1;
|
||||||
|
#endif /* XWL_HAS_GLAMOR */
|
||||||
|
|
||||||
#ifdef GBM_BO_FD_FOR_PLANE
|
#ifdef GBM_BO_FD_FOR_PLANE
|
||||||
if (xwl_gbm->dmabuf_capable) {
|
if (xwl_gbm->dmabuf_capable) {
|
||||||
|
@ -445,6 +457,7 @@ xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap)
|
||||||
eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
|
eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
|
||||||
if (xwl_pixmap->bo)
|
if (xwl_pixmap->bo)
|
||||||
gbm_bo_destroy(xwl_pixmap->bo);
|
gbm_bo_destroy(xwl_pixmap->bo);
|
||||||
|
xwl_glamor_gbm_dispose_syncpts(pixmap);
|
||||||
free(xwl_pixmap);
|
free(xwl_pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1388,6 +1401,21 @@ xwl_glamor_gbm_has_egl_extension(void)
|
||||||
epoxy_has_egl_extension(NULL, "EGL_KHR_platform_gbm"));
|
epoxy_has_egl_extension(NULL, "EGL_KHR_platform_gbm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DRI3
|
||||||
|
static void
|
||||||
|
xwl_glamor_gbm_release_fence_avail(int fd, int xevents, void *data)
|
||||||
|
{
|
||||||
|
struct xwl_pixmap *xwl_pixmap = data;
|
||||||
|
struct xwl_window_buffer *xwl_window_buffer = xwl_pixmap->xwl_window_buffer;
|
||||||
|
|
||||||
|
SetNotifyFd(fd, NULL, 0, NULL);
|
||||||
|
close(fd);
|
||||||
|
xwl_pixmap->efd = -1;
|
||||||
|
|
||||||
|
xwl_window_buffer_release(xwl_window_buffer);
|
||||||
|
}
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen)
|
xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen)
|
||||||
{
|
{
|
||||||
|
@ -1403,6 +1431,122 @@ xwl_glamor_supports_syncobjs(struct xwl_screen *xwl_screen)
|
||||||
xwl_gbm_get(xwl_screen)->supports_syncobjs;
|
xwl_gbm_get(xwl_screen)->supports_syncobjs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
xwl_glamor_gbm_set_syncpts(struct xwl_window *xwl_window, PixmapPtr pixmap)
|
||||||
|
{
|
||||||
|
#ifdef DRI3
|
||||||
|
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
|
||||||
|
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||||
|
uint64_t acquire_point;
|
||||||
|
uint64_t release_point;
|
||||||
|
int fence_fd;
|
||||||
|
|
||||||
|
if (!xwl_screen->glamor)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!xwl_pixmap) {
|
||||||
|
ErrorF("XWAYLAND: Failed to set synchronization point, no backing xwl_pixmap!\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
acquire_point = ++xwl_pixmap->timeline_point;
|
||||||
|
release_point = ++xwl_pixmap->timeline_point;
|
||||||
|
|
||||||
|
if (!xwl_pixmap->syncobj) {
|
||||||
|
struct dri3_syncobj *syncobj = xwl_glamor_dri3_syncobj_create(xwl_screen);
|
||||||
|
if (!syncobj)
|
||||||
|
goto fail;
|
||||||
|
xwl_pixmap->syncobj = syncobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
fence_fd = xwl_glamor_get_fence(xwl_screen);
|
||||||
|
if (fence_fd >= 0)
|
||||||
|
xwl_pixmap->syncobj->import_fence(xwl_pixmap->syncobj, acquire_point, fence_fd);
|
||||||
|
else
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
xwl_glamor_dri3_syncobj_passthrough(xwl_window,
|
||||||
|
xwl_pixmap->syncobj,
|
||||||
|
xwl_pixmap->syncobj,
|
||||||
|
acquire_point,
|
||||||
|
release_point);
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
/* can't use explicit sync, we will do a glFinish() before presenting */
|
||||||
|
if (xwl_pixmap->syncobj) {
|
||||||
|
xwl_pixmap->syncobj->free(xwl_pixmap->syncobj);
|
||||||
|
xwl_pixmap->syncobj = NULL;
|
||||||
|
}
|
||||||
|
#endif /* DRI3 */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xwl_glamor_gbm_dispose_syncpts(PixmapPtr pixmap)
|
||||||
|
{
|
||||||
|
#ifdef DRI3
|
||||||
|
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
|
||||||
|
|
||||||
|
if (!xwl_screen->glamor || !xwl_pixmap)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (xwl_pixmap->syncobj) {
|
||||||
|
xwl_pixmap->syncobj->free(xwl_pixmap->syncobj);
|
||||||
|
xwl_pixmap->syncobj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xwl_pixmap->efd >= 0) {
|
||||||
|
SetNotifyFd(xwl_pixmap->efd, NULL, 0, NULL);
|
||||||
|
close(xwl_pixmap->efd);
|
||||||
|
}
|
||||||
|
#endif /* DRI3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xwl_glamor_gbm_wait_syncpts(PixmapPtr pixmap)
|
||||||
|
{
|
||||||
|
#ifdef DRI3
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
|
||||||
|
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||||
|
int fence_fd;
|
||||||
|
|
||||||
|
if (!xwl_screen->glamor || !xwl_pixmap)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (xwl_pixmap->syncobj) {
|
||||||
|
fence_fd = xwl_pixmap->syncobj->export_fence(xwl_pixmap->syncobj,
|
||||||
|
xwl_pixmap->timeline_point);
|
||||||
|
xwl_glamor_wait_fence(xwl_screen, fence_fd);
|
||||||
|
close(fence_fd);
|
||||||
|
}
|
||||||
|
#endif /* DRI3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xwl_glamor_gbm_wait_release_fence(struct xwl_window *xwl_window,
|
||||||
|
PixmapPtr pixmap,
|
||||||
|
struct xwl_window_buffer *xwl_window_buffer)
|
||||||
|
{
|
||||||
|
#ifdef DRI3
|
||||||
|
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
|
||||||
|
|
||||||
|
if (!xwl_screen->glamor || !xwl_pixmap || !xwl_window_buffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xwl_pixmap->xwl_window_buffer = xwl_window_buffer;
|
||||||
|
/* wait until the release fence is available before re-using this buffer */
|
||||||
|
xwl_pixmap->efd = eventfd(0, EFD_CLOEXEC);
|
||||||
|
SetNotifyFd(xwl_pixmap->efd, xwl_glamor_gbm_release_fence_avail, X_NOTIFY_READ,
|
||||||
|
xwl_pixmap);
|
||||||
|
xwl_pixmap->syncobj->submitted_eventfd(xwl_pixmap->syncobj,
|
||||||
|
xwl_pixmap->timeline_point,
|
||||||
|
xwl_pixmap->efd);
|
||||||
|
#endif /* DRI3 */
|
||||||
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
xwl_glamor_try_to_make_context_current(struct xwl_screen *xwl_screen)
|
xwl_glamor_try_to_make_context_current(struct xwl_screen *xwl_screen)
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,4 +42,12 @@ Bool xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen);
|
||||||
Bool xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen);
|
Bool xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen);
|
||||||
drmDevice *xwl_gbm_get_main_device(struct xwl_screen *xwl_screen);
|
drmDevice *xwl_gbm_get_main_device(struct xwl_screen *xwl_screen);
|
||||||
|
|
||||||
|
/* Explicit buffer synchronization points */
|
||||||
|
Bool xwl_glamor_gbm_set_syncpts(struct xwl_window *xwl_window, PixmapPtr pixmap);
|
||||||
|
void xwl_glamor_gbm_dispose_syncpts(PixmapPtr pixmap);
|
||||||
|
void xwl_glamor_gbm_wait_syncpts(PixmapPtr pixmap);
|
||||||
|
void xwl_glamor_gbm_wait_release_fence(struct xwl_window *xwl_window,
|
||||||
|
PixmapPtr pixmap,
|
||||||
|
struct xwl_window_buffer *xwl_window_buffer);
|
||||||
|
|
||||||
#endif /* XWAYLAND_GLAMOR_GBM_H */
|
#endif /* XWAYLAND_GLAMOR_GBM_H */
|
||||||
|
|
Loading…
Reference in New Issue