[gnome-remote-desktop] egl-thread: Add API to query format modifiers
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-remote-desktop] egl-thread: Add API to query format modifiers
- Date: Wed, 8 Dec 2021 09:09:51 +0000 (UTC)
commit e7aa56d2c896160900ca3cefe3912a8217e851db
Author: Jonas Ådahl <jadahl gmail com>
Date: Fri Nov 26 11:57:45 2021 +0100
egl-thread: Add API to query format modifiers
Will be used for explicit DMA buffer PipeWire support.
src/grd-egl-thread.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/grd-egl-thread.h | 5 ++
2 files changed, 131 insertions(+)
---
diff --git a/src/grd-egl-thread.c b/src/grd-egl-thread.c
index 69875f5..681a94b 100644
--- a/src/grd-egl-thread.c
+++ b/src/grd-egl-thread.c
@@ -34,6 +34,8 @@ struct _GrdEglThread
GAsyncQueue *task_queue;
+ GHashTable *modifiers;
+
struct
{
gboolean initialized;
@@ -108,6 +110,80 @@ is_hardware_accelerated (void)
return !is_software;
}
+static gboolean
+query_format_modifiers (GrdEglThread *egl_thread,
+ EGLDisplay egl_display,
+ GError **error)
+{
+ EGLint n_formats;
+ g_autofree EGLint *formats = NULL;
+ EGLint i;
+
+ if (!eglQueryDmaBufFormatsEXT (egl_display, 0, NULL, &n_formats))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to query number of DMA buffer formats");
+ return FALSE;
+ }
+
+ if (n_formats == 0)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "No available DMA buffer formats");
+ return FALSE;
+ }
+
+ formats = g_new0 (EGLint, n_formats);
+ if (!eglQueryDmaBufFormatsEXT (egl_display, n_formats, formats, &n_formats))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to query DMA buffer formats");
+ return FALSE;
+ }
+
+ for (i = 0; i < n_formats; i++)
+ {
+ EGLint n_modifiers;
+ GArray *modifiers;
+
+ if (!eglQueryDmaBufModifiersEXT (egl_display,
+ formats[i], 0, NULL, NULL,
+ &n_modifiers))
+ {
+ g_warning ("Failed to query number of modifiers for format %d",
+ formats[0]);
+ continue;
+ }
+
+ if (n_modifiers == 0)
+ {
+ g_debug ("No modifiers available for format %d", formats[0]);
+ continue;
+ }
+
+ modifiers = g_array_sized_new (FALSE, FALSE,
+ sizeof (EGLuint64KHR),
+ n_modifiers);
+ g_array_set_size (modifiers, n_modifiers);
+ if (!eglQueryDmaBufModifiersEXT (egl_display,
+ formats[i], n_modifiers,
+ (EGLuint64KHR *) modifiers->data,
+ NULL,
+ &n_modifiers))
+ {
+ g_warning ("Failed to query modifiers for format %d",
+ formats[0]);
+ continue;
+ }
+
+ g_hash_table_insert (egl_thread->modifiers,
+ GINT_TO_POINTER (formats[i]),
+ modifiers);
+ }
+
+ return TRUE;
+}
+
static gboolean
grd_egl_init_in_impl (GrdEglThread *egl_thread,
GError **error)
@@ -165,6 +241,15 @@ grd_egl_init_in_impl (GrdEglThread *egl_thread,
return FALSE;
}
+ if (!epoxy_has_egl_extension (egl_display,
+ "EGL_EXT_image_dma_buf_import_modifiers"))
+ {
+ eglTerminate (egl_display);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Missing extension 'EGL_EXT_image_dma_buf_import_modifiers'");
+ return FALSE;
+ }
+
attrs = (EGLint[]) {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
@@ -186,6 +271,22 @@ grd_egl_init_in_impl (GrdEglThread *egl_thread,
EGL_NO_SURFACE,
egl_context);
+ if (!query_format_modifiers (egl_thread, egl_display, error))
+ {
+ eglDestroyContext (egl_display, egl_context);
+ eglTerminate (egl_display);
+ return FALSE;
+ }
+
+ if (g_hash_table_size (egl_thread->modifiers) == 0)
+ {
+ eglDestroyContext (egl_display, egl_context);
+ eglTerminate (egl_display);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "No DMA buffer modifiers / format pair found");
+ return FALSE;
+ }
+
if (!is_hardware_accelerated ())
{
eglDestroyContext (egl_display, egl_context);
@@ -354,6 +455,11 @@ grd_egl_thread_new (GError **error)
GrdEglThread *egl_thread;
egl_thread = g_new0 (GrdEglThread, 1);
+
+ egl_thread->modifiers =
+ g_hash_table_new_full (NULL, NULL,
+ NULL, (GDestroyNotify) g_array_unref);
+
g_mutex_init (&egl_thread->mutex);
g_cond_init (&egl_thread->cond);
@@ -402,6 +508,7 @@ grd_egl_thread_free (GrdEglThread *egl_thread)
g_mutex_clear (&egl_thread->mutex);
g_cond_clear (&egl_thread->cond);
+ g_clear_pointer (&egl_thread->modifiers, g_hash_table_unref);
g_clear_pointer (&egl_thread->impl.main_context, g_main_context_unref);
g_free (egl_thread);
@@ -656,3 +763,22 @@ grd_egl_thread_sync (GrdEglThread *egl_thread,
g_async_queue_push (egl_thread->task_queue, task);
g_main_context_wakeup (egl_thread->impl.main_context);
}
+
+gboolean
+grd_egl_thread_get_modifiers_for_format (GrdEglThread *egl_thread,
+ uint32_t format,
+ int *out_n_modifiers,
+ uint64_t **out_modifiers)
+{
+ GArray *modifiers;
+
+ modifiers = g_hash_table_lookup (egl_thread->modifiers,
+ GINT_TO_POINTER (format));
+ if (!modifiers)
+ return FALSE;
+
+ *out_n_modifiers = modifiers->len;
+ *out_modifiers = g_memdup2 (modifiers->data,
+ sizeof (uint64_t) * modifiers->len);
+ return TRUE;
+}
diff --git a/src/grd-egl-thread.h b/src/grd-egl-thread.h
index 4b946c4..9af35ee 100644
--- a/src/grd-egl-thread.h
+++ b/src/grd-egl-thread.h
@@ -53,4 +53,9 @@ void grd_egl_thread_sync (GrdEglThread *egl_thread,
gpointer user_data,
GDestroyNotify destroy);
+gboolean grd_egl_thread_get_modifiers_for_format (GrdEglThread *egl_thread,
+ uint32_t format,
+ int *out_n_modifiers,
+ uint64_t **out_modifiers);
+
#endif /* GRD_EGL_THREAD_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]