[gnome-remote-desktop] egl-thread: Add fallback with EGL_PLATFORM_DEVICE_EXT



commit f1cba140949b6b451889d2fb064914723b46ba28
Author: Pascal Nowack <Pascal Nowack gmx de>
Date:   Thu Dec 30 12:23:32 2021 +0100

    egl-thread: Add fallback with EGL_PLATFORM_DEVICE_EXT
    
    When initializing the EGL thread with the platform
    EGL_PLATFORM_SURFACELESS_MESA, it won't be hardware accelerated, when
    using the NVIDIA drivers.
    The result is that EGL Thread will be torn down, although it could
    actually be used with the NVIDIA drivers, even when dma-buf are not
    used:
    
    With CUDA, it is possible to map pixel buffer objects for the use in
    CUDA.
    These mapped CUDA buffers can then be used for e.g. the damage region
    creation on the GPU, which is much faster than the creation on the CPU,
    or be used in NVENC later.
    The EGL thread can then, when dma-bufs are used, directly map the frame
    data.
    When dma-bufs are not available, the frame data can be uploaded, which
    is done in future commits.
    With this operation in the EGL thread, it won't block the graphics
    thread in the RDP backend, which allows the RDP backend to maximize the
    maximum possible framerate, due to shorter encoding times, as there
    won't be a blocking upload operation be any more.
    
    It would also make the implementation with the support of dma-bufs
    easier in the future.
    With dma-bufs, the frame data can then directly mapped, while being
    implementation-wise close to the non-dma-buf path.
    
    So, add a fallback path using the platform EGL_PLATFORM_DEVICE_EXT to
    enable the ability to directly map pixel buffer objects, when using the
    NVIDIA driver.

 src/grd-egl-thread.c | 84 +++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 60 insertions(+), 24 deletions(-)
---
diff --git a/src/grd-egl-thread.c b/src/grd-egl-thread.c
index 681a94b0..0675894d 100644
--- a/src/grd-egl-thread.c
+++ b/src/grd-egl-thread.c
@@ -115,7 +115,7 @@ query_format_modifiers (GrdEglThread  *egl_thread,
                         EGLDisplay     egl_display,
                         GError       **error)
 {
-  EGLint n_formats;
+  EGLint n_formats = 0;
   g_autofree EGLint *formats = NULL;
   EGLint i;
 
@@ -185,26 +185,23 @@ query_format_modifiers (GrdEglThread  *egl_thread,
 }
 
 static gboolean
-grd_egl_init_in_impl (GrdEglThread  *egl_thread,
-                      GError       **error)
+initialize_egl_context (GrdEglThread  *egl_thread,
+                        EGLenum        egl_platform,
+                        GError       **error)
 {
   EGLDisplay egl_display;
   EGLint major, minor;
   EGLint *attrs;
   EGLContext egl_context;
 
-  if (!epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Missing extension 'EGL_EXT_platform_base'");
-      return FALSE;
-    }
+  g_clear_error (error);
 
-  egl_display = eglGetPlatformDisplayEXT (EGL_PLATFORM_SURFACELESS_MESA,
-                                          NULL, NULL);
+  egl_display = eglGetPlatformDisplayEXT (egl_platform, NULL, NULL);
   if (egl_display == EGL_NO_DISPLAY)
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+      int code = egl_platform == EGL_PLATFORM_DEVICE_EXT ? G_IO_ERROR_NOT_SUPPORTED
+                                                         : G_IO_ERROR_FAILED;
+      g_set_error (error, G_IO_ERROR, code,
                    "Failed to get EGL display");
       return FALSE;
     }
@@ -225,20 +222,23 @@ grd_egl_init_in_impl (GrdEglThread  *egl_thread,
       return FALSE;
     }
 
-  if (!epoxy_has_egl_extension (egl_display, "EGL_MESA_platform_surfaceless"))
+  if (egl_platform == EGL_PLATFORM_SURFACELESS_MESA)
     {
-      eglTerminate (egl_display);
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-                   "Missing extension 'EGL_MESA_platform_surfaceless'");
-      return FALSE;
-    }
+      if (!epoxy_has_egl_extension (egl_display, "EGL_MESA_platform_surfaceless"))
+        {
+          eglTerminate (egl_display);
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                       "Missing extension 'EGL_MESA_platform_surfaceless'");
+          return FALSE;
+        }
 
-  if (!epoxy_has_egl_extension (egl_display, "EGL_MESA_configless_context"))
-    {
-      eglTerminate (egl_display);
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-                   "Missing extension 'EGL_MESA_platform_surfaceless'");
-      return FALSE;
+      if (!epoxy_has_egl_extension (egl_display, "EGL_MESA_configless_context"))
+        {
+          eglTerminate (egl_display);
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                       "Missing extension 'EGL_MESA_configless_context'");
+          return FALSE;
+        }
     }
 
   if (!epoxy_has_egl_extension (egl_display,
@@ -302,6 +302,42 @@ grd_egl_init_in_impl (GrdEglThread  *egl_thread,
   return TRUE;
 }
 
+static gboolean
+grd_egl_init_in_impl (GrdEglThread  *egl_thread,
+                      GError       **error)
+{
+  gboolean initialized;
+
+  if (!epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Missing extension 'EGL_EXT_platform_base'");
+      return FALSE;
+    }
+
+  initialized = initialize_egl_context (egl_thread,
+                                        EGL_PLATFORM_SURFACELESS_MESA,
+                                        error);
+  if (initialized)
+    {
+      g_debug ("EGL context initialized with platform "
+               "EGL_PLATFORM_SURFACELESS_MESA");
+    }
+  else
+    {
+      initialized = initialize_egl_context (egl_thread,
+                                            EGL_PLATFORM_DEVICE_EXT,
+                                            error);
+      if (initialized)
+        {
+          g_debug ("EGL context initialized with platform "
+                   "EGL_PLATFORM_DEVICE_EXT");
+        }
+    }
+
+  return initialized;
+}
+
 static void
 grd_egl_task_free (GrdEglTask *task)
 {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]