These egl helpers would be used for creating and waiting on
a sync object.
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
include/ui/console.h | 2 ++
include/ui/egl-helpers.h | 3 +++
ui/egl-helpers.c | 44 ++++++++++++++++++++++++++++++++++++++++
ui/gtk.c | 15 ++++++++++++++
4 files changed, 64 insertions(+)
diff --git a/include/ui/console.h b/include/ui/console.h
index c3dca61c31..a89f739f10 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -168,6 +168,8 @@ typedef struct QemuDmaBuf {
uint64_t modifier;
uint32_t texture;
bool y0_top;
+ void *sync;
+ int fence_fd;
} QemuDmaBuf;
typedef struct DisplayState DisplayState;
diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index f1bf8f97fc..5a7575dc13 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -45,6 +45,9 @@ int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc,
void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf);
void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf);
+void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf);
+void egl_dmabuf_create_fence(QemuDmaBuf *dmabuf);
+void egl_dmabuf_wait_sync(QemuDmaBuf *dmabuf);
#endif
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 6d0cb2b5cb..47220b66e0 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -76,6 +76,50 @@ void egl_fb_setup_for_tex(egl_fb *fb, int width, int height,
GL_TEXTURE_2D, fb->texture, 0);
}
+void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf)
+{
+ EGLSyncKHR sync;
+
+ if (epoxy_has_egl_extension(qemu_egl_display,
+ "EGL_KHR_fence_sync") &&
+ epoxy_has_egl_extension(qemu_egl_display,
+ "EGL_ANDROID_native_fence_sync")) {
+ sync = eglCreateSyncKHR(qemu_egl_display,
+ EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
+ if (sync != EGL_NO_SYNC_KHR) {
+ dmabuf->sync = sync;
+ }
+ }
+}
+
+void egl_dmabuf_create_fence(QemuDmaBuf *dmabuf)
+{
+ if (dmabuf->sync) {
+ dmabuf->fence_fd = eglDupNativeFenceFDANDROID(qemu_egl_display,
+ dmabuf->sync);
+ eglDestroySyncKHR(qemu_egl_display, dmabuf->sync);
+ dmabuf->sync = NULL;
+ }
+}
+
+void egl_dmabuf_wait_sync(QemuDmaBuf *dmabuf)
+{
+ EGLSyncKHR sync;
+ EGLint attrib_list[] = {
+ EGL_SYNC_NATIVE_FENCE_FD_ANDROID, dmabuf->fence_fd,
+ EGL_NONE,
+ };
+
+ sync = eglCreateSyncKHR(qemu_egl_display,
+ EGL_SYNC_NATIVE_FENCE_ANDROID, attrib_list);
+ if (sync != EGL_NO_SYNC_KHR) {
+ eglClientWaitSyncKHR(qemu_egl_display, sync,
+ 0, EGL_FOREVER_KHR);
+ eglDestroySyncKHR(qemu_egl_display, sync);
+ dmabuf->fence_fd = -1;
+ }
+}
+
void egl_fb_setup_new_tex(egl_fb *fb, int width, int height)
{
GLuint texture;
diff --git a/ui/gtk.c b/ui/gtk.c
index 6132bab52f..cd884ca26c 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -583,6 +583,19 @@ static void gd_gl_release_dmabuf(DisplayChangeListener *dcl,
#endif
}
+static void gd_gl_wait_dmabuf(DisplayChangeListener *dcl,
+ QemuDmaBuf *dmabuf)
+{
+#ifdef CONFIG_GBM
+ egl_dmabuf_create_fence(dmabuf);
+ if (dmabuf->fence_fd <= 0) {
+ return;
+ }
+
+ egl_dmabuf_wait_sync(dmabuf);
+#endif
+}
+
/** DisplayState Callbacks (opengl version) **/
static const DisplayChangeListenerOps dcl_gl_area_ops = {
@@ -602,6 +615,7 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = {
.dpy_gl_update = gd_gl_area_scanout_flush,
.dpy_gl_scanout_dmabuf = gd_gl_area_scanout_dmabuf,
.dpy_gl_release_dmabuf = gd_gl_release_dmabuf,
+ .dpy_gl_wait_dmabuf = gd_gl_wait_dmabuf,
.dpy_has_dmabuf = gd_has_dmabuf,
};
@@ -626,6 +640,7 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
.dpy_gl_cursor_position = gd_egl_cursor_position,
.dpy_gl_update = gd_egl_scanout_flush,
.dpy_gl_release_dmabuf = gd_gl_release_dmabuf,
+ .dpy_gl_wait_dmabuf = gd_gl_wait_dmabuf,
.dpy_has_dmabuf = gd_has_dmabuf,
};
--
2.30.2
Hi,
> + epoxy_has_egl_extension(qemu_egl_display,
> + "EGL_ANDROID_native_fence_sync")) {
What about non-android? Is the name there just for historical reasons?
Or do we actually need something else for desktop systems?
> +void egl_dmabuf_wait_sync(QemuDmaBuf *dmabuf)
See other mail on blocking wait. Otherwise looks sane.
> +static void gd_gl_wait_dmabuf(DisplayChangeListener *dcl,
> + QemuDmaBuf *dmabuf)
separate patch for the gtk bits please.
thanks,
Gerd
Hi Gerd,
> > + epoxy_has_egl_extension(qemu_egl_display,
> > + "EGL_ANDROID_native_fence_sync")) {
>
> What about non-android? Is the name there just for historical reasons?
> Or do we actually need something else for desktop systems?
[Kasireddy, Vivek] It is not specific to Android:
https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_native_fence_sync.txt
I have been using Linux (Fedora 33 for both Guest and Host) as my
test platform.
>
> > +void egl_dmabuf_wait_sync(QemuDmaBuf *dmabuf)
>
> See other mail on blocking wait. Otherwise looks sane.
>
> > +static void gd_gl_wait_dmabuf(DisplayChangeListener *dcl,
> > + QemuDmaBuf *dmabuf)
>
> separate patch for the gtk bits please.
[Kasireddy, Vivek] Ok, will do.
Thanks,
Vivek
>
> thanks,
> Gerd
© 2016 - 2026 Red Hat, Inc.