Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Explicit Sync #104

Merged
merged 1 commit into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ libnvidia_egl_wayland_la_dmabuf_built_client_headers = \
libnvidia_egl_wayland_la_dmabuf_built_private_protocols = \
linux-dmabuf-unstable-v1-protocol.c

libnvidia_egl_wayland_la_drm_syncobj_built_client_headers = \
linux-drm-syncobj-v1-client-protocol.h

libnvidia_egl_wayland_la_drm_syncobj_built_private_protocols = \
linux-drm-syncobj-v1-protocol.c

libnvidia_egl_wayland_la_presentation_time_built_client_headers = \
presentation-time-client-protocol.h

Expand All @@ -93,6 +99,8 @@ libnvidia_egl_wayland_la_built_sources = \
$(libnvidia_egl_wayland_la_built_server_headers) \
$(libnvidia_egl_wayland_la_dmabuf_built_client_headers) \
$(libnvidia_egl_wayland_la_dmabuf_built_private_protocols) \
$(libnvidia_egl_wayland_la_drm_syncobj_built_client_headers) \
$(libnvidia_egl_wayland_la_drm_syncobj_built_private_protocols) \
$(libnvidia_egl_wayland_la_presentation_time_built_client_headers) \
$(libnvidia_egl_wayland_la_presentation_time_private_protocols)

Expand Down Expand Up @@ -129,6 +137,12 @@ $(libnvidia_egl_wayland_la_dmabuf_built_private_protocols):%-protocol.c : $(WAYL
$(libnvidia_egl_wayland_la_dmabuf_built_client_headers):%-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/linux-dmabuf/%.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@

$(libnvidia_egl_wayland_la_drm_syncobj_built_private_protocols):%-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/staging/linux-drm-syncobj/%.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) $(WAYLAND_PRIVATE_CODEGEN) < $< > $@

$(libnvidia_egl_wayland_la_drm_syncobj_built_client_headers):%-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/staging/linux-drm-syncobj/%.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@

$(libnvidia_egl_wayland_la_presentation_time_private_protocols):%-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/stable/presentation-time/%.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) $(WAYLAND_PRIVATE_CODEGEN) < $< > $@

Expand Down
7 changes: 7 additions & 0 deletions include/wayland-egldisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,17 @@ typedef struct WlEglDmaBufFeedbackRec {
typedef struct WlEglDisplayRec {
WlEglDeviceDpy *devDpy;

/* Supports EGL_ANDROID_native_fence_sync */
int supports_native_fence_sync;

EGLBoolean ownNativeDpy;
struct wl_display *nativeDpy;

struct wl_registry *wlRegistry;
struct wl_eglstream_display *wlStreamDpy;
struct wl_eglstream_controller *wlStreamCtl;
struct zwp_linux_dmabuf_v1 *wlDmaBuf;
struct wp_linux_drm_syncobj_manager_v1 *wlDrmSyncobj;
unsigned int wlStreamCtlVer;
struct wp_presentation *wpPresentation;
struct wl_event_queue *wlEventQueue;
Expand All @@ -139,6 +143,9 @@ typedef struct WlEglDisplayRec {

WlEglPlatformData *data;

/* DRM device in use */
int drmFd;

EGLBoolean useInitRefCount;
EGLDeviceEXT requestedDevice;

Expand Down
2 changes: 2 additions & 0 deletions include/wayland-eglhandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ typedef struct WlEglPlatformDataRec {
PFNEGLCLIENTWAITSYNCKHRPROC clientWaitSync;
PFNEGLSIGNALSYNCKHRPROC signalSync;
PFNEGLDESTROYSYNCKHRPROC destroySync;
PFNEGLCREATESYNCKHRPROC createSync;
PFNEGLSTREAMFLUSHNVPROC streamFlush;
PFNEGLDUPNATIVEFENCEFDANDROIDPROC dupNativeFenceFD;

/* Used for dma-buf surfaces */
PFNEGLSTREAMIMAGECONSUMERCONNECTNVPROC streamImageConsumerConnect;
Expand Down
18 changes: 18 additions & 0 deletions include/wayland-eglsurface-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ typedef struct WlEglStreamImageRec {
struct wl_buffer *buffer;
EGLBoolean attached;
struct wl_list acquiredLink;

struct wp_linux_drm_syncobj_timeline_v1 *wlReleaseTimeline;
uint32_t drmSyncobjHandle;
int releasePending;
/* Latest release point the compositor will signal with explicit sync */
uint64_t releasePoint;
/* Cached acquire EGLSync from acquireImage */
EGLSyncKHR acquireSync;
} WlEglStreamImage;

typedef struct WlEglSurfaceCtxRec {
Expand Down Expand Up @@ -151,6 +159,13 @@ struct WlEglSurfaceRec {
EGLBoolean isResized;

WlEglDmaBufFeedback feedback;

/* per-surface Explicit Sync objects */
struct wp_linux_drm_syncobj_surface_v1 *wlSyncobjSurf;
struct wp_linux_drm_syncobj_timeline_v1 *wlAcquireTimeline;
uint32_t drmSyncobjHandle;
/* Last acquire point used. This starts at 1, zero means invalid. */
uint64_t syncPoint;
};

void wlEglReallocSurface(WlEglDisplay *display,
Expand Down Expand Up @@ -185,6 +200,9 @@ EGLBoolean wlEglQueryNativeResourceHook(EGLDisplay dpy,
EGLint attribute,
int *value);

EGLBoolean
wlEglSurfaceCheckReleasePoints(WlEglDisplay *display, WlEglSurface *surface);

EGLBoolean wlEglSendDamageEvent(WlEglSurface *surface,
struct wl_event_queue *queue);

Expand Down
4 changes: 4 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ libdrm = dependency('libdrm')
wl_protos_dir = wl_protos.get_pkgconfig_variable('pkgdatadir')
wl_dmabuf_xml = join_paths(wl_protos_dir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml')
wp_presentation_time_xml = join_paths(wl_protos_dir, 'stable', 'presentation-time', 'presentation-time.xml')
wl_drm_syncobj_xml = join_paths(wl_protos_dir, 'staging', 'linux-drm-syncobj', 'linux-drm-syncobj-v1.xml')

client_header = generator(prog_scanner,
output : '@[email protected]',
Expand Down Expand Up @@ -65,6 +66,9 @@ src += code.process(wl_dmabuf_xml)
src += client_header.process(wp_presentation_time_xml)
src += code.process(wp_presentation_time_xml)

src += client_header.process(wl_drm_syncobj_xml)
src += code.process(wl_drm_syncobj_xml)
amshafer marked this conversation as resolved.
Show resolved Hide resolved

egl_wayland = library('nvidia-egl-wayland',
src,
dependencies : [
Expand Down
31 changes: 30 additions & 1 deletion src/wayland-egldisplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "wayland-drm-client-protocol.h"
#include "wayland-drm.h"
#include "presentation-time-client-protocol.h"
#include "linux-drm-syncobj-v1-client-protocol.h"
#include <string.h>
#include <stdlib.h>
#include <assert.h>
Expand Down Expand Up @@ -454,6 +455,12 @@ registry_handle_global(void *data,
name,
&wp_presentation_interface,
version);
} else if (strcmp(interface, "wp_linux_drm_syncobj_manager_v1") == 0 &&
display->supports_native_fence_sync) {
display->wlDrmSyncobj = wl_registry_bind(registry,
amshafer marked this conversation as resolved.
Show resolved Hide resolved
name,
&wp_linux_drm_syncobj_manager_v1_interface,
version);
}
}

Expand Down Expand Up @@ -738,6 +745,10 @@ static EGLBoolean terminateDisplay(WlEglDisplay *display, EGLBoolean globalTeard
wp_presentation_destroy(display->wpPresentation);
display->wpPresentation = NULL;
}
if (display->wlDrmSyncobj) {
wp_linux_drm_syncobj_manager_v1_destroy(display->wlDrmSyncobj);
display->wlDrmSyncobj = NULL;
}
if (display->wlDmaBuf) {
zwp_linux_dmabuf_v1_destroy(display->wlDmaBuf);
display->wlDmaBuf = NULL;
Expand Down Expand Up @@ -926,6 +937,7 @@ EGLDisplay wlEglGetPlatformDisplayExport(void *data,
EGLDeviceEXT requestedDevice = EGL_NO_DEVICE_EXT;
EGLBoolean usePrimeRenderOffload = EGL_FALSE;
EGLBoolean isServerNV;
const char *drmName = NULL;

if (platform != EGL_PLATFORM_WAYLAND_EXT) {
wlEglSetError(data, EGL_BAD_PARAMETER);
Expand Down Expand Up @@ -1156,7 +1168,6 @@ EGLDisplay wlEglGetPlatformDisplayExport(void *data,
display->primeRenderOffload = EGL_TRUE;
}


display->devDpy = wlGetInternalDisplay(pData, eglDevice);
if (display->devDpy == NULL) {
goto fail;
Expand All @@ -1168,6 +1179,17 @@ EGLDisplay wlEglGetPlatformDisplayExport(void *data,
display->refCount = 1;
WL_LIST_INIT(&display->wlEglSurfaceList);

/* Get the DRM device in use */
drmName = display->data->egl.queryDeviceString(display->devDpy->eglDevice,
EGL_DRM_DEVICE_FILE_EXT);
if (!drmName) {
goto fail;
}

display->drmFd = open(drmName, O_RDWR | O_CLOEXEC);
if (display->drmFd < 0) {
goto fail;
}

// The newly created WlEglDisplay has been set up properly, insert it
// in wlEglDisplayList.
Expand Down Expand Up @@ -1205,6 +1227,7 @@ EGLBoolean wlEglInitializeHook(EGLDisplay dpy, EGLint *major, EGLint *minor)
struct wl_display *wrapper = NULL;
EGLint err = EGL_SUCCESS;
int ret = 0;
const char *dev_exts = NULL;

if (!display) {
return EGL_FALSE;
Expand Down Expand Up @@ -1235,6 +1258,11 @@ EGLBoolean wlEglInitializeHook(EGLDisplay dpy, EGLint *major, EGLint *minor)
return EGL_FALSE;
}

dev_exts = display->data->egl.queryString(display->devDpy->eglDisplay, EGL_EXTENSIONS);
if (dev_exts && wlEglFindExtension("EGL_ANDROID_native_fence_sync", dev_exts)) {
display->supports_native_fence_sync = true;
}

// Set the initCount to 1. If something goes wrong, then terminateDisplay
// will clean up and set it back to zero.
display->initCount = 1;
Expand Down Expand Up @@ -1353,6 +1381,7 @@ WlEglDisplay *wlEglAcquireDisplay(EGLDisplay dpy) {
static void wlEglUnrefDisplay(WlEglDisplay *display) {
if (--display->refCount == 0) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love non-atomic refcount decrements

wlEglMutexDestroy(&display->mutex);
close(display->drmFd);
free(display);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/wayland-eglhandle.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ wlEglCreatePlatformData(int apiMajor, int apiMinor, const EGLExtDriver *driver)
GET_PROC(clientWaitSync, eglClientWaitSyncKHR);
GET_PROC(signalSync, eglSignalSyncKHR);
GET_PROC(destroySync, eglDestroySyncKHR);
GET_PROC(createSync, eglCreateSyncKHR);
GET_PROC(dupNativeFenceFD, eglDupNativeFenceFDANDROID);

/* Stream flush */
GET_PROC(streamFlush, eglStreamFlushNV);
Expand Down
Loading