From 1074040be3b89ffa7d6fb15a3c1ef35e141e15d1 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Wed, 3 Apr 2019 13:11:45 +0300 Subject: [PATCH 2/3] 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 771ca0872..c7483f3cd 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -3698,16 +3698,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", @@ -3719,9 +3716,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); @@ -3733,26 +3752,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; } -- 2.21.0