render/egl: add support for explicit sync extensions

This commit is contained in:
Simon Ser 2020-03-16 17:24:25 +01:00
parent dab20d8311
commit 1bcec23099
3 changed files with 86 additions and 0 deletions

View file

@ -60,4 +60,12 @@ void wlr_egl_save_context(struct wlr_egl_context *context);
*/ */
bool wlr_egl_restore_context(struct wlr_egl_context *context); bool wlr_egl_restore_context(struct wlr_egl_context *context);
EGLSyncKHR wlr_egl_create_sync(struct wlr_egl *egl, int fence_fd);
void wlr_egl_destroy_sync(struct wlr_egl *egl, EGLSyncKHR sync);
int wlr_egl_dup_fence_fd(struct wlr_egl *egl, EGLSyncKHR sync);
bool wlr_egl_wait_sync(struct wlr_egl *egl, EGLSyncKHR sync);
#endif #endif

View file

@ -62,6 +62,10 @@ struct wlr_egl {
PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT; PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT;
PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT; PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT;
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT; PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT;
PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR;
PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR;
PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID;
PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR;
} procs; } procs;
struct wlr_drm_format_set dmabuf_texture_formats; struct wlr_drm_format_set dmabuf_texture_formats;

View file

@ -313,6 +313,18 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
return false; return false;
} }
if (check_egl_ext(display_exts_str, "EGL_KHR_fence_sync") &&
check_egl_ext(display_exts_str, "EGL_ANDROID_native_fence_sync")) {
load_egl_proc(&egl->procs.eglCreateSyncKHR, "eglCreateSyncKHR");
load_egl_proc(&egl->procs.eglDestroySyncKHR, "eglDestroySyncKHR");
load_egl_proc(&egl->procs.eglDupNativeFenceFDANDROID,
"eglDupNativeFenceFDANDROID");
}
if (check_egl_ext(display_exts_str, "EGL_KHR_wait_sync")) {
load_egl_proc(&egl->procs.eglWaitSyncKHR, "eglWaitSyncKHR");
}
wlr_log(WLR_INFO, "Supported EGL display extensions: %s", display_exts_str); wlr_log(WLR_INFO, "Supported EGL display extensions: %s", display_exts_str);
if (device_exts_str != NULL) { if (device_exts_str != NULL) {
wlr_log(WLR_INFO, "Supported EGL device extensions: %s", device_exts_str); wlr_log(WLR_INFO, "Supported EGL device extensions: %s", device_exts_str);
@ -897,3 +909,65 @@ int wlr_egl_dup_drm_fd(struct wlr_egl *egl) {
return render_fd; return render_fd;
} }
EGLSyncKHR wlr_egl_create_sync(struct wlr_egl *egl, int fence_fd) {
if (!egl->procs.eglCreateSyncKHR) {
return EGL_NO_SYNC_KHR;
}
EGLint attribs[3] = { EGL_NONE };
int dup_fd = -1;
if (fence_fd >= 0) {
dup_fd = fcntl(fence_fd, F_DUPFD_CLOEXEC, 0);
if (dup_fd < 0) {
wlr_log_errno(WLR_ERROR, "dup failed");
return EGL_NO_SYNC_KHR;
}
attribs[0] = EGL_SYNC_NATIVE_FENCE_FD_ANDROID;
attribs[1] = dup_fd;
attribs[2] = EGL_NONE;
}
EGLSyncKHR sync = egl->procs.eglCreateSyncKHR(egl->display,
EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync == EGL_NO_SYNC_KHR) {
wlr_log(WLR_ERROR, "eglCreateSyncKHR failed");
if (dup_fd >= 0) {
close(dup_fd);
}
}
return sync;
}
void wlr_egl_destroy_sync(struct wlr_egl *egl, EGLSyncKHR sync) {
if (sync == EGL_NO_SYNC_KHR) {
return;
}
assert(egl->procs.eglDestroySyncKHR);
if (egl->procs.eglDestroySyncKHR(egl->display, sync) != EGL_TRUE) {
wlr_log(WLR_ERROR, "eglDestroySyncKHR failed");
}
}
int wlr_egl_dup_fence_fd(struct wlr_egl *egl, EGLSyncKHR sync) {
if (!egl->procs.eglDupNativeFenceFDANDROID) {
return -1;
}
int fd = egl->procs.eglDupNativeFenceFDANDROID(egl->display, sync);
if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
wlr_log(WLR_ERROR, "eglDupNativeFenceFDANDROID failed");
return -1;
}
return fd;
}
bool wlr_egl_wait_sync(struct wlr_egl *egl, EGLSyncKHR sync) {
if (egl->procs.eglWaitSyncKHR(egl->display, sync, 0) != EGL_TRUE) {
wlr_log(WLR_ERROR, "eglWaitSyncKHR failed");
return false;
}
return true;
}