From da1c1d9c22fbd1cf0ea4fc8fd6b433522cbe938e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 31 Aug 2016 11:25:45 +0800 Subject: [PATCH] MetaRendererNative: Use pbuffer surface as dummy surface Lets use a pbuffer surface as a dummy surface instead of a gbm based one, so that we don't need to rely on the availability of gbm to create a dummy surface when there is no need for it. https://bugzilla.gnome.org/show_bug.cgi?id=773629 --- src/backends/meta-egl.c | 63 ++++++++++++++++++++++ src/backends/meta-egl.h | 12 +++++ src/backends/native/meta-renderer-native.c | 61 +++++++++++---------- 3 files changed, 108 insertions(+), 28 deletions(-) diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c index 65e627e7a..d605a7956 100644 --- a/src/backends/meta-egl.c +++ b/src/backends/meta-egl.c @@ -200,6 +200,69 @@ meta_egl_get_display (MetaEgl *egl, return display; } +gboolean +meta_egl_choose_config (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + EGLConfig *chosen_config, + GError **error) +{ + EGLint num_configs; + EGLConfig *configs; + EGLint num_matches; + + if (!eglGetConfigs (display, NULL, 0, &num_configs)) + { + set_egl_error (error); + return FALSE; + } + + if (num_configs < 1) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "No EGL configurations available"); + return FALSE; + } + + configs = g_new0 (EGLConfig, num_configs); + + if (!eglChooseConfig (display, attrib_list, configs, num_configs, &num_matches)) + { + g_free (configs); + set_egl_error (error); + return FALSE; + } + + /* + * We don't have any preference specified yet, so lets choose the first one. + */ + *chosen_config = configs[0]; + + g_free (configs); + + return TRUE; +} + +EGLSurface +meta_egl_create_pbuffer_surface (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + const EGLint *attrib_list, + GError **error) +{ + EGLSurface surface; + + surface = eglCreatePbufferSurface (display, config, attrib_list); + if (surface == EGL_NO_SURFACE) + { + set_egl_error (error); + return EGL_NO_SURFACE; + } + + return surface; +} + static gboolean is_egl_proc_valid_real (void *proc, const char *proc_name, diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h index f8a7a94d2..ac176d573 100644 --- a/src/backends/meta-egl.h +++ b/src/backends/meta-egl.h @@ -42,6 +42,18 @@ EGLDisplay meta_egl_get_display (MetaEgl *egl, EGLNativeDisplayType display_id, GError **error); +gboolean meta_egl_choose_config (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + EGLConfig *chosen_config, + GError **error); + +EGLSurface meta_egl_create_pbuffer_surface (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + const EGLint *attrib_list, + GError **error); + EGLDisplay meta_egl_get_platform_display (MetaEgl *egl, EGLenum platform, void *native_display, diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 273a34efd..9ec423ff6 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -95,8 +95,6 @@ struct _MetaRendererNative CoglClosure *swap_notify_idle; int64_t frame_counter; - - struct gbm_surface *dummy_gbm_surface; }; static void @@ -281,6 +279,37 @@ meta_renderer_native_destroy_egl_display (CoglDisplay *cogl_display) { } +static EGLSurface +create_dummy_pbuffer_surface (EGLDisplay egl_display, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + EGLConfig pbuffer_config; + static const EGLint pbuffer_config_attribs[] = { + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_ALPHA_SIZE, 0, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE + }; + static const EGLint pbuffer_attribs[] = { + EGL_WIDTH, 16, + EGL_HEIGHT, 16, + EGL_NONE + }; + + if (!meta_egl_choose_config (egl, egl_display, pbuffer_config_attribs, + &pbuffer_config, error)) + return EGL_NO_SURFACE; + + return meta_egl_create_pbuffer_surface (egl, egl_display, + pbuffer_config, pbuffer_attribs, + error); +} + static gboolean meta_renderer_native_egl_context_created (CoglDisplay *cogl_display, GError **error) @@ -288,37 +317,14 @@ meta_renderer_native_egl_context_created (CoglDisplay *cogl_display, CoglDisplayEGL *egl_display = cogl_display->winsys; CoglRenderer *cogl_renderer = cogl_display->renderer; CoglRendererEGL *egl_renderer = cogl_renderer->winsys; - MetaRendererNative *renderer_native = egl_renderer->platform; if ((egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0) { - renderer_native->dummy_gbm_surface = - gbm_surface_create (renderer_native->gbm.device, - 16, 16, - GBM_FORMAT_XRGB8888, - GBM_BO_USE_RENDERING); - if (!renderer_native->dummy_gbm_surface) - { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Failed to create dummy GBM surface"); - return FALSE; - } - egl_display->dummy_surface = - eglCreateWindowSurface (egl_renderer->edpy, - egl_display->egl_config, - (EGLNativeWindowType) - renderer_native->dummy_gbm_surface, - NULL); + create_dummy_pbuffer_surface (egl_renderer->edpy, error); if (egl_display->dummy_surface == EGL_NO_SURFACE) - { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Failed to create dummy EGL surface"); - return FALSE; - } + return FALSE; } if (!_cogl_winsys_egl_make_current (cogl_display, @@ -1228,7 +1234,6 @@ meta_renderer_native_finalize (GObject *object) { MetaRendererNative *renderer_native = META_RENDERER_NATIVE (object); - g_clear_pointer (&renderer_native->dummy_gbm_surface, gbm_surface_destroy); g_clear_pointer (&renderer_native->gbm.device, gbm_device_destroy); G_OBJECT_CLASS (meta_renderer_native_parent_class)->finalize (object);