xwayland: support DRI3 1.4 and Present 1.4
Together, DRI3 1.4 and Present 1.4 allow clients to explicitly synchronize GPU rendering with presentation using DRM syncobjs. Here we add the necessary support to Xwayland's glamor and Present infrastructure to enable this functionality. Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
This commit is contained in:
parent
ac0bc0b3b6
commit
6f85ce4d4e
|
@ -66,6 +66,7 @@ struct xwl_gbm_private {
|
||||||
Bool dmabuf_capable;
|
Bool dmabuf_capable;
|
||||||
Bool glamor_gles;
|
Bool glamor_gles;
|
||||||
Bool implicit_sync;
|
Bool implicit_sync;
|
||||||
|
Bool supports_syncobjs;
|
||||||
|
|
||||||
/* Set if wl_drm is available */
|
/* Set if wl_drm is available */
|
||||||
struct wl_drm *drm;
|
struct wl_drm *drm;
|
||||||
|
@ -960,7 +961,192 @@ xwl_glamor_dmabuf_import_sync_file(PixmapPtr pixmap, int sync_file)
|
||||||
close(sync_file);
|
close(sync_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const dri3_screen_info_rec xwl_dri3_info = {
|
struct xwl_dri3_syncobj
|
||||||
|
{
|
||||||
|
struct dri3_syncobj base;
|
||||||
|
uint32_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
xwl_dri3_check_syncobj(struct dri3_syncobj *syncobj, uint64_t point, Bool check_avail)
|
||||||
|
{
|
||||||
|
struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
|
||||||
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
|
||||||
|
return !drmSyncobjTimelineWait(xwl_gbm->drm_fd,
|
||||||
|
&xwl_syncobj->handle, &point, 1,
|
||||||
|
0 /* timeout */,
|
||||||
|
check_avail ?
|
||||||
|
DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE :
|
||||||
|
DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
|
||||||
|
NULL /* first_signaled */);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
xwl_dri3_syncobj_has_fence(struct dri3_syncobj *syncobj, uint64_t point)
|
||||||
|
{
|
||||||
|
return xwl_dri3_check_syncobj(syncobj, point, TRUE /* check_avail */);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
xwl_dri3_syncobj_is_signaled(struct dri3_syncobj *syncobj, uint64_t point)
|
||||||
|
{
|
||||||
|
return xwl_dri3_check_syncobj(syncobj, point, FALSE /* check_avail */);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xwl_dri3_syncobj_export_fence(struct dri3_syncobj *syncobj, uint64_t point)
|
||||||
|
{
|
||||||
|
struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
|
||||||
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
uint32_t temp_syncobj;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
drmSyncobjCreate(xwl_gbm->drm_fd, 0, &temp_syncobj);
|
||||||
|
drmSyncobjTransfer(xwl_gbm->drm_fd, temp_syncobj, 0,
|
||||||
|
xwl_syncobj->handle, point, 0);
|
||||||
|
drmSyncobjExportSyncFile(xwl_gbm->drm_fd, temp_syncobj, &fd);
|
||||||
|
drmSyncobjDestroy(xwl_gbm->drm_fd, temp_syncobj);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xwl_dri3_syncobj_import_fence(struct dri3_syncobj *syncobj,
|
||||||
|
uint64_t point, int fd)
|
||||||
|
{
|
||||||
|
struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
|
||||||
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
uint32_t temp_syncobj;
|
||||||
|
|
||||||
|
drmSyncobjCreate(xwl_gbm->drm_fd, 0, &temp_syncobj);
|
||||||
|
drmSyncobjImportSyncFile(xwl_gbm->drm_fd, temp_syncobj, fd);
|
||||||
|
drmSyncobjTransfer(xwl_gbm->drm_fd, xwl_syncobj->handle, point,
|
||||||
|
temp_syncobj, 0, 0);
|
||||||
|
drmSyncobjDestroy(xwl_gbm->drm_fd, temp_syncobj);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xwl_dri3_signal_syncobj(struct dri3_syncobj *syncobj, uint64_t point)
|
||||||
|
{
|
||||||
|
struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
|
||||||
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
|
||||||
|
drmSyncobjTimelineSignal(xwl_gbm->drm_fd, &xwl_syncobj->handle, &point, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xwl_dri3_free_syncobj(struct dri3_syncobj *syncobj)
|
||||||
|
{
|
||||||
|
struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
|
||||||
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
|
||||||
|
if (xwl_syncobj->handle)
|
||||||
|
drmSyncobjDestroy(xwl_gbm->drm_fd, xwl_syncobj->handle);
|
||||||
|
|
||||||
|
free(xwl_syncobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xwl_dri3_syncobj_eventfd(struct dri3_syncobj *syncobj, uint64_t point,
|
||||||
|
int efd, Bool wait_avail)
|
||||||
|
{
|
||||||
|
struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
|
||||||
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
|
||||||
|
drmSyncobjEventfd(xwl_gbm->drm_fd, xwl_syncobj->handle, point, efd,
|
||||||
|
wait_avail ? DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xwl_dri3_syncobj_submitted_eventfd(struct dri3_syncobj *syncobj,
|
||||||
|
uint64_t point, int efd)
|
||||||
|
{
|
||||||
|
xwl_dri3_syncobj_eventfd(syncobj, point, efd, TRUE /* wait_avail */);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xwl_dri3_syncobj_signaled_eventfd(struct dri3_syncobj *syncobj,
|
||||||
|
uint64_t point, int efd)
|
||||||
|
{
|
||||||
|
xwl_dri3_syncobj_eventfd(syncobj, point, efd, FALSE /* wait_avail */);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dri3_syncobj *
|
||||||
|
xwl_dri3_create_syncobj(struct xwl_screen *xwl_screen, uint32_t handle)
|
||||||
|
{
|
||||||
|
struct xwl_dri3_syncobj *syncobj = calloc(1, sizeof (*syncobj));
|
||||||
|
|
||||||
|
if (!syncobj)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
syncobj->handle = handle;
|
||||||
|
syncobj->base.screen = xwl_screen->screen;
|
||||||
|
syncobj->base.refcount = 1;
|
||||||
|
|
||||||
|
syncobj->base.free = xwl_dri3_free_syncobj;
|
||||||
|
syncobj->base.has_fence = xwl_dri3_syncobj_has_fence;
|
||||||
|
syncobj->base.is_signaled = xwl_dri3_syncobj_is_signaled;
|
||||||
|
syncobj->base.export_fence = xwl_dri3_syncobj_export_fence;
|
||||||
|
syncobj->base.import_fence = xwl_dri3_syncobj_import_fence;
|
||||||
|
syncobj->base.signal = xwl_dri3_signal_syncobj;
|
||||||
|
syncobj->base.signaled_eventfd = xwl_dri3_syncobj_signaled_eventfd;
|
||||||
|
syncobj->base.submitted_eventfd = xwl_dri3_syncobj_submitted_eventfd;
|
||||||
|
return &syncobj->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dri3_syncobj *
|
||||||
|
xwl_dri3_import_syncobj(ClientPtr client, ScreenPtr screen, XID id, int fd)
|
||||||
|
{
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||||
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
struct xwl_dri3_syncobj *syncobj = NULL;
|
||||||
|
uint32_t handle;
|
||||||
|
|
||||||
|
if (drmSyncobjFDToHandle(xwl_gbm->drm_fd, fd, &handle))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
syncobj = (struct xwl_dri3_syncobj *)xwl_dri3_create_syncobj(xwl_screen, handle);
|
||||||
|
if (!syncobj) {
|
||||||
|
drmSyncobjDestroy(xwl_gbm->drm_fd, handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
syncobj->base.id = id;
|
||||||
|
|
||||||
|
return &syncobj->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
xwl_gbm_supports_syncobjs(struct xwl_screen *xwl_screen)
|
||||||
|
{
|
||||||
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
uint64_t syncobj_cap = 0;
|
||||||
|
|
||||||
|
if (drmGetCap(xwl_gbm->drm_fd, DRM_CAP_SYNCOBJ_TIMELINE,
|
||||||
|
&syncobj_cap) || !syncobj_cap)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Check if syncobj eventfd is supported. */
|
||||||
|
drmSyncobjEventfd(xwl_gbm->drm_fd, 0, 0, -1, 0);
|
||||||
|
if (errno != ENOENT)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
#if !defined(DMA_BUF_IOCTL_EXPORT_SYNC_FILE) || \
|
||||||
|
!defined(DMA_BUF_IOCTL_IMPORT_SYNC_FILE)
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static dri3_screen_info_rec xwl_dri3_info = {
|
||||||
.version = 2,
|
.version = 2,
|
||||||
.open = NULL,
|
.open = NULL,
|
||||||
.pixmap_from_fds = glamor_pixmap_from_fds,
|
.pixmap_from_fds = glamor_pixmap_from_fds,
|
||||||
|
@ -969,6 +1155,7 @@ static const dri3_screen_info_rec xwl_dri3_info = {
|
||||||
.get_formats = xwl_glamor_get_formats,
|
.get_formats = xwl_glamor_get_formats,
|
||||||
.get_modifiers = xwl_glamor_get_modifiers,
|
.get_modifiers = xwl_glamor_get_modifiers,
|
||||||
.get_drawable_modifiers = xwl_glamor_get_drawable_modifiers,
|
.get_drawable_modifiers = xwl_glamor_get_drawable_modifiers,
|
||||||
|
.import_syncobj = NULL, /* need to check for kernel support */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
@ -1129,6 +1316,13 @@ xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen)
|
||||||
xwl_gbm_get(xwl_screen)->implicit_sync;
|
xwl_gbm_get(xwl_screen)->implicit_sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
xwl_glamor_supports_syncobjs(struct xwl_screen *xwl_screen)
|
||||||
|
{
|
||||||
|
return xwl_screen->glamor &&
|
||||||
|
xwl_gbm_get(xwl_screen)->supports_syncobjs;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -1346,6 +1540,11 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
|
||||||
/* NVIDIA driver does not support implicit sync */
|
/* NVIDIA driver does not support implicit sync */
|
||||||
xwl_gbm->implicit_sync = !strstr(egl_vendor, "NVIDIA");
|
xwl_gbm->implicit_sync = !strstr(egl_vendor, "NVIDIA");
|
||||||
|
|
||||||
|
if (xwl_gbm_supports_syncobjs(xwl_screen) &&
|
||||||
|
epoxy_has_egl_extension(xwl_screen->egl_display,
|
||||||
|
"ANDROID_native_fence_sync"))
|
||||||
|
xwl_gbm->supports_syncobjs = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
error:
|
error:
|
||||||
if (xwl_screen->egl_display != EGL_NO_DISPLAY) {
|
if (xwl_screen->egl_display != EGL_NO_DISPLAY) {
|
||||||
|
@ -1363,6 +1562,11 @@ xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen)
|
||||||
{
|
{
|
||||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
|
||||||
|
if (xwl_gbm->supports_syncobjs) {
|
||||||
|
xwl_dri3_info.version = 4;
|
||||||
|
xwl_dri3_info.import_syncobj = xwl_dri3_import_syncobj;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
|
if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
|
||||||
ErrorF("Failed to initialize dri3\n");
|
ErrorF("Failed to initialize dri3\n");
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
@ -269,6 +269,30 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xwl_glamor_get_fence(struct xwl_screen *xwl_screen)
|
||||||
|
{
|
||||||
|
EGLint attribs[3];
|
||||||
|
EGLSyncKHR sync;
|
||||||
|
int fence_fd = -1;
|
||||||
|
|
||||||
|
if (!xwl_screen->glamor)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
xwl_glamor_egl_make_current(xwl_screen);
|
||||||
|
|
||||||
|
attribs[0] = EGL_SYNC_NATIVE_FENCE_FD_ANDROID;
|
||||||
|
attribs[1] = EGL_NO_NATIVE_FENCE_FD_ANDROID;
|
||||||
|
attribs[2] = EGL_NONE;
|
||||||
|
sync = eglCreateSyncKHR(xwl_screen->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
|
||||||
|
if (sync != EGL_NO_SYNC_KHR) {
|
||||||
|
fence_fd = eglDupNativeFenceFDANDROID(xwl_screen->egl_display, sync);
|
||||||
|
eglDestroySyncKHR(xwl_screen->egl_display, sync);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fence_fd;
|
||||||
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xwl_glamor_init(struct xwl_screen *xwl_screen)
|
xwl_glamor_init(struct xwl_screen *xwl_screen)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,6 +60,8 @@ PixmapPtr xwl_glamor_create_pixmap_for_window (struct xwl_window *xwl_window);
|
||||||
Bool xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen);
|
Bool xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen);
|
||||||
void xwl_glamor_dmabuf_import_sync_file(PixmapPtr pixmap, int sync_file);
|
void xwl_glamor_dmabuf_import_sync_file(PixmapPtr pixmap, int sync_file);
|
||||||
int xwl_glamor_dmabuf_export_sync_file(PixmapPtr pixmap);
|
int xwl_glamor_dmabuf_export_sync_file(PixmapPtr pixmap);
|
||||||
|
Bool xwl_glamor_supports_syncobjs(struct xwl_screen *xwl_screen);
|
||||||
|
int xwl_glamor_get_fence(struct xwl_screen *screen);
|
||||||
|
|
||||||
#ifdef XV
|
#ifdef XV
|
||||||
/* glamor Xv Adaptor */
|
/* glamor Xv Adaptor */
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <windowstr.h>
|
#include <windowstr.h>
|
||||||
#include <present.h>
|
#include <present.h>
|
||||||
|
#include <sys/eventfd.h>
|
||||||
|
|
||||||
#include "xwayland-present.h"
|
#include "xwayland-present.h"
|
||||||
#include "xwayland-screen.h"
|
#include "xwayland-screen.h"
|
||||||
|
@ -225,7 +226,8 @@ xwl_present_queue_vblank(ScreenPtr screen,
|
||||||
static uint32_t
|
static uint32_t
|
||||||
xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
|
xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
|
||||||
{
|
{
|
||||||
return XWL_PRESENT_CAPS;
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen_priv->pScreen);
|
||||||
|
return xwl_screen->present_capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -322,7 +324,17 @@ xwl_present_free_event(struct xwl_present_event *event)
|
||||||
static void
|
static void
|
||||||
xwl_present_free_idle_vblank(present_vblank_ptr vblank)
|
xwl_present_free_idle_vblank(present_vblank_ptr vblank)
|
||||||
{
|
{
|
||||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
#ifdef XWL_HAS_GLAMOR
|
||||||
|
if (vblank->release_syncobj) {
|
||||||
|
/* transfer implicit fence to release syncobj */
|
||||||
|
int fence_fd = xwl_glamor_dmabuf_export_sync_file(vblank->pixmap);
|
||||||
|
vblank->release_syncobj->import_fence(vblank->release_syncobj,
|
||||||
|
vblank->release_point,
|
||||||
|
fence_fd);
|
||||||
|
} else
|
||||||
|
#endif /* XWL_HAS_GLAMOR */
|
||||||
|
present_pixmap_idle(vblank->pixmap, vblank->window,
|
||||||
|
vblank->serial, vblank->idle_fence);
|
||||||
xwl_present_free_event(xwl_present_event_from_vblank(vblank));
|
xwl_present_free_event(xwl_present_event_from_vblank(vblank));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,6 +495,16 @@ xwl_present_buffer_release(void *data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vblank = &event->vblank;
|
vblank = &event->vblank;
|
||||||
|
|
||||||
|
#ifdef XWL_HAS_GLAMOR
|
||||||
|
if (vblank->release_syncobj) {
|
||||||
|
/* transfer implicit fence to release syncobj */
|
||||||
|
int fence_fd = xwl_glamor_dmabuf_export_sync_file(vblank->pixmap);
|
||||||
|
vblank->release_syncobj->import_fence(vblank->release_syncobj,
|
||||||
|
vblank->release_point,
|
||||||
|
fence_fd);
|
||||||
|
} else
|
||||||
|
#endif /* XWL_HAS_GLAMOR */
|
||||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||||
|
|
||||||
xwl_present_window = xwl_present_window_priv(vblank->window);
|
xwl_present_window = xwl_present_window_priv(vblank->window);
|
||||||
|
@ -679,6 +701,18 @@ xwl_present_maybe_set_reason(struct xwl_window *xwl_window, PresentFlipReason *r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xwl_present_flush_fenced(WindowPtr window)
|
||||||
|
{
|
||||||
|
int fence = -1;
|
||||||
|
#ifdef XWL_HAS_GLAMOR
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
|
||||||
|
fence = xwl_glamor_get_fence(xwl_screen);
|
||||||
|
#endif /* XWL_HAS_GLAMOR */
|
||||||
|
xwl_present_flush(window);
|
||||||
|
return fence;
|
||||||
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
xwl_present_check_flip(RRCrtcPtr crtc,
|
xwl_present_check_flip(RRCrtcPtr crtc,
|
||||||
WindowPtr present_window,
|
WindowPtr present_window,
|
||||||
|
@ -896,6 +930,7 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
||||||
|
|
||||||
xorg_list_del(&vblank->event_queue);
|
xorg_list_del(&vblank->event_queue);
|
||||||
|
|
||||||
|
retry:
|
||||||
if (present_execute_wait(vblank, crtc_msc))
|
if (present_execute_wait(vblank, crtc_msc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -972,6 +1007,8 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
||||||
}
|
}
|
||||||
|
|
||||||
vblank->flip = FALSE;
|
vblank->flip = FALSE;
|
||||||
|
/* re-execute, falling through to copy */
|
||||||
|
goto retry;
|
||||||
}
|
}
|
||||||
DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||||
vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
|
vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
|
||||||
|
@ -1029,13 +1066,16 @@ xwl_present_pixmap(WindowPtr window,
|
||||||
ScreenPtr screen = window->drawable.pScreen;
|
ScreenPtr screen = window->drawable.pScreen;
|
||||||
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
|
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
|
||||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen_priv->pScreen);
|
||||||
|
uint32_t caps = xwl_screen->present_capabilities;
|
||||||
struct xwl_present_event *event;
|
struct xwl_present_event *event;
|
||||||
|
|
||||||
if (!window_priv)
|
if (!window_priv)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
|
|
||||||
#ifdef DRI3
|
#ifdef DRI3
|
||||||
if (acquire_syncobj || release_syncobj)
|
if (!(caps & PresentCapabilitySyncobj) &&
|
||||||
|
(acquire_syncobj || release_syncobj))
|
||||||
return BadValue;
|
return BadValue;
|
||||||
#endif /* DRI3 */
|
#endif /* DRI3 */
|
||||||
|
|
||||||
|
@ -1076,6 +1116,10 @@ xwl_present_pixmap(WindowPtr window,
|
||||||
if (xwl_present_event_from_vblank(vblank)->copy_executed)
|
if (xwl_present_event_from_vblank(vblank)->copy_executed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (vblank->release_syncobj)
|
||||||
|
vblank->release_syncobj->signal(vblank->release_syncobj,
|
||||||
|
vblank->release_point);
|
||||||
|
|
||||||
present_vblank_scrap(vblank);
|
present_vblank_scrap(vblank);
|
||||||
if (vblank->flip_ready)
|
if (vblank->flip_ready)
|
||||||
xwl_present_re_execute(vblank);
|
xwl_present_re_execute(vblank);
|
||||||
|
@ -1092,7 +1136,7 @@ xwl_present_pixmap(WindowPtr window,
|
||||||
#ifdef DRI3
|
#ifdef DRI3
|
||||||
acquire_syncobj, release_syncobj, acquire_point, release_point,
|
acquire_syncobj, release_syncobj, acquire_point, release_point,
|
||||||
#endif /* DRI3 */
|
#endif /* DRI3 */
|
||||||
options, XWL_PRESENT_CAPS, notifies, num_notifies, target_msc, crtc_msc)) {
|
options, caps, notifies, num_notifies, target_msc, crtc_msc)) {
|
||||||
present_vblank_destroy(vblank);
|
present_vblank_destroy(vblank);
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
}
|
}
|
||||||
|
@ -1131,6 +1175,7 @@ xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
|
||||||
Bool
|
Bool
|
||||||
xwl_present_init(ScreenPtr screen)
|
xwl_present_init(ScreenPtr screen)
|
||||||
{
|
{
|
||||||
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||||
present_screen_priv_ptr screen_priv;
|
present_screen_priv_ptr screen_priv;
|
||||||
|
|
||||||
if (!present_screen_register_priv_keys())
|
if (!present_screen_register_priv_keys())
|
||||||
|
@ -1146,6 +1191,13 @@ xwl_present_init(ScreenPtr screen)
|
||||||
if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
|
if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
xwl_screen->present_capabilities = XWL_PRESENT_CAPS;
|
||||||
|
#ifdef XWL_HAS_GLAMOR
|
||||||
|
if (xwl_glamor_supports_syncobjs(xwl_screen))
|
||||||
|
xwl_screen->present_capabilities |=
|
||||||
|
PresentCapabilitySyncobj;
|
||||||
|
#endif /* XWL_HAS_GLAMOR */
|
||||||
|
|
||||||
screen_priv->query_capabilities = xwl_present_query_capabilities;
|
screen_priv->query_capabilities = xwl_present_query_capabilities;
|
||||||
screen_priv->get_crtc = xwl_present_get_crtc;
|
screen_priv->get_crtc = xwl_present_get_crtc;
|
||||||
|
|
||||||
|
@ -1156,6 +1208,7 @@ xwl_present_init(ScreenPtr screen)
|
||||||
screen_priv->present_pixmap = xwl_present_pixmap;
|
screen_priv->present_pixmap = xwl_present_pixmap;
|
||||||
screen_priv->queue_vblank = xwl_present_queue_vblank;
|
screen_priv->queue_vblank = xwl_present_queue_vblank;
|
||||||
screen_priv->flush = xwl_present_flush;
|
screen_priv->flush = xwl_present_flush;
|
||||||
|
screen_priv->flush_fenced = xwl_present_flush_fenced;
|
||||||
screen_priv->re_execute = xwl_present_re_execute;
|
screen_priv->re_execute = xwl_present_re_execute;
|
||||||
|
|
||||||
screen_priv->abort_vblank = xwl_present_abort_vblank;
|
screen_priv->abort_vblank = xwl_present_abort_vblank;
|
||||||
|
|
|
@ -142,6 +142,8 @@ struct xwl_screen {
|
||||||
struct libdecor *libdecor_context;
|
struct libdecor *libdecor_context;
|
||||||
#endif
|
#endif
|
||||||
const char *output_name;
|
const char *output_name;
|
||||||
|
|
||||||
|
uint32_t present_capabilities;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Apps which use randr/vidmode to change the mode when going fullscreen,
|
/* Apps which use randr/vidmode to change the mode when going fullscreen,
|
||||||
|
|
|
@ -60,7 +60,7 @@ endforeach
|
||||||
|
|
||||||
add_project_arguments(common_wflags, language : ['c', 'objc'])
|
add_project_arguments(common_wflags, language : ['c', 'objc'])
|
||||||
|
|
||||||
libdrm_req = '>= 2.4.109'
|
libdrm_req = '>= 2.4.116'
|
||||||
libselinux_req = '>= 2.0.86'
|
libselinux_req = '>= 2.0.86'
|
||||||
xext_req = '>= 1.0.99.4'
|
xext_req = '>= 1.0.99.4'
|
||||||
wayland_req = '>= 1.21.0'
|
wayland_req = '>= 1.21.0'
|
||||||
|
|
Loading…
Reference in New Issue