[mutter] renderer/native: Make EGL initialization failure not fatal



commit 3b46a8cd70fbae0f149f959aec8de832850801e3
Author: Pekka Paalanen <pekka paalanen collabora com>
Date:   Wed Apr 3 13:11:45 2019 +0300

    renderer/native: Make EGL initialization failure not fatal
    
    The failure to initialize EGL does not necessarily mean the KMS device cannot
    be used. The device could still be used as a "secondary GPU" with the CPU copy
    mode.
    
    If meta_renderer_native_create_renderer_gpu_data () fails,
    meta_renderer_native_get_gpu_data () will return NULL, which may cause crashes.
    This patch removes most of the failures, but does not fix the NULL dereferences
    that will still happen if creating gpu data fails.
    
    This patch reorders create_renderer_gpu_data_gbm () so that it fails hard only
    if GBM device cannot be created, and otherwise always returns an initialized
    gpu data structure. Users of the gpu data structure are responsible for
    checking egl_display validity.
    
    The GBM device creation failure is a hard failure because presumably GBM is
    necessary for cursors.
    
    Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/542
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/521

 src/backends/native/meta-renderer-native.c | 62 +++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 22 deletions(-)
---
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 086e8e43c..87cf3d010 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -3787,16 +3787,13 @@ gpu_kms_is_hardware_rendering (MetaRendererNative *renderer_native,
   return data->secondary.is_hardware_rendering;
 }
 
-static MetaRendererNativeGpuData *
-create_renderer_gpu_data_gbm (MetaRendererNative  *renderer_native,
-                              MetaGpuKms          *gpu_kms,
-                              GError             **error)
+static EGLDisplay
+init_gbm_egl_display (MetaRendererNative  *renderer_native,
+                      struct gbm_device   *gbm_device,
+                      GError             **error)
 {
   MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
-  struct gbm_device *gbm_device;
   EGLDisplay egl_display;
-  int kms_fd;
-  MetaRendererNativeGpuData *renderer_gpu_data;
 
   if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL,
                                 "EGL_MESA_platform_gbm",
@@ -3808,9 +3805,31 @@ create_renderer_gpu_data_gbm (MetaRendererNative  *renderer_native,
       g_set_error (error, G_IO_ERROR,
                    G_IO_ERROR_FAILED,
                    "Missing extension for GBM renderer: EGL_KHR_platform_gbm");
-      return NULL;
+      return EGL_NO_DISPLAY;
     }
 
+  egl_display = meta_egl_get_platform_display (egl,
+                                               EGL_PLATFORM_GBM_KHR,
+                                               gbm_device, NULL, error);
+  if (egl_display == EGL_NO_DISPLAY)
+    return EGL_NO_DISPLAY;
+
+  if (!meta_egl_initialize (egl, egl_display, error))
+    return EGL_NO_DISPLAY;
+
+  return egl_display;
+}
+
+static MetaRendererNativeGpuData *
+create_renderer_gpu_data_gbm (MetaRendererNative  *renderer_native,
+                              MetaGpuKms          *gpu_kms,
+                              GError             **error)
+{
+  struct gbm_device *gbm_device;
+  int kms_fd;
+  MetaRendererNativeGpuData *renderer_gpu_data;
+  g_autoptr (GError) local_error = NULL;
+
   kms_fd = meta_gpu_kms_get_fd (gpu_kms);
 
   gbm_device = gbm_create_device (kms_fd);
@@ -3822,26 +3841,25 @@ create_renderer_gpu_data_gbm (MetaRendererNative  *renderer_native,
       return NULL;
     }
 
-  egl_display = meta_egl_get_platform_display (egl,
-                                               EGL_PLATFORM_GBM_KHR,
-                                               gbm_device, NULL, error);
-  if (egl_display == EGL_NO_DISPLAY)
-    {
-      gbm_device_destroy (gbm_device);
-      return NULL;
-    }
-
-  if (!meta_egl_initialize (egl, egl_display, error))
-    return NULL;
-
   renderer_gpu_data = meta_create_renderer_native_gpu_data (gpu_kms);
   renderer_gpu_data->renderer_native = renderer_native;
   renderer_gpu_data->gbm.device = gbm_device;
   renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_GBM;
-  renderer_gpu_data->egl_display = egl_display;
 
-  init_secondary_gpu_data (renderer_gpu_data);
+  renderer_gpu_data->egl_display = init_gbm_egl_display (renderer_native,
+                                                         gbm_device,
+                                                         &local_error);
+  if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY)
+    {
+      g_debug ("GBM EGL init for %s failed: %s",
+               meta_gpu_kms_get_file_path (gpu_kms),
+               local_error->message);
 
+      init_secondary_gpu_data_cpu (renderer_gpu_data);
+      return renderer_gpu_data;
+    }
+
+  init_secondary_gpu_data (renderer_gpu_data);
   return renderer_gpu_data;
 }
 


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