diff options
author | Jonas Ådahl <jadahl@gmail.com> | 2018-02-23 22:14:07 +0800 |
---|---|---|
committer | Jonas Ådahl <jadahl@gmail.com> | 2018-03-05 15:42:27 +0000 |
commit | 712ec30cd9be1f180c3789e7e6a042c5f7b5781d (patch) | |
tree | 8e71ba19b7a1e57b305a11c7593134021765c49b /src | |
parent | 7a41483ea066d9654c2eb3104cda27439ad4ca05 (diff) | |
download | mutter-712ec30cd9be1f180c3789e7e6a042c5f7b5781d.tar.gz |
renderer/native: Force EGL config pixel format
We just arbitrarily chose the first EGL config matching the passed
attributes, but we then assumed we always got GBM_FORMAT_XRGB8888. That
was not a correct assumption. Instead, make sure we always pick the
format we expect.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/2
Diffstat (limited to 'src')
-rw-r--r-- | src/backends/meta-egl.c | 66 | ||||
-rw-r--r-- | src/backends/meta-egl.h | 13 | ||||
-rw-r--r-- | src/backends/native/meta-renderer-native.c | 79 |
3 files changed, 153 insertions, 5 deletions
diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c index 775863f88..755ec4908 100644 --- a/src/backends/meta-egl.c +++ b/src/backends/meta-egl.c @@ -266,6 +266,72 @@ meta_egl_get_proc_address (MetaEgl *egl, } gboolean +meta_egl_get_config_attrib (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLint attribute, + EGLint *value, + GError **error) +{ + if (!eglGetConfigAttrib (display, + config, + attribute, + value)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +EGLConfig * +meta_egl_choose_all_configs (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + EGLint *out_num_configs, + 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; + } + + if (num_matches == 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No matching EGL configs"); + g_free (configs); + return NULL; + } + + *out_num_configs = num_configs; + return configs; +} + +gboolean meta_egl_choose_first_config (MetaEgl *egl, EGLDisplay display, const EGLint *attrib_list, diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h index be4e631d2..060c7cd2d 100644 --- a/src/backends/meta-egl.h +++ b/src/backends/meta-egl.h @@ -62,6 +62,19 @@ gboolean meta_egl_choose_first_config (MetaEgl *egl, EGLConfig *chosen_config, GError **error); +gboolean meta_egl_get_config_attrib (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLint attribute, + EGLint *value, + GError **error); + +EGLConfig * meta_egl_choose_all_configs (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + EGLint *out_num_configs, + GError **error); + EGLContext meta_egl_create_context (MetaEgl *egl, EGLDisplay display, EGLConfig config, diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 5c29597cc..8175a6b21 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -935,6 +935,73 @@ meta_renderer_native_add_egl_config_attributes (CoglDisplay *cogl_disp } static gboolean +choose_egl_config_from_gbm_format (MetaEgl *egl, + EGLDisplay egl_display, + const EGLint *attributes, + uint32_t gbm_format, + EGLConfig *out_config, + GError **error) +{ + EGLConfig *egl_configs; + EGLint n_configs; + EGLint i; + + egl_configs = meta_egl_choose_all_configs (egl, egl_display, + attributes, + &n_configs, + error); + if (!egl_configs) + return FALSE; + + for (i = 0; i < n_configs; i++) + { + EGLint visual_id; + + if (!meta_egl_get_config_attrib (egl, egl_display, + egl_configs[i], + EGL_NATIVE_VISUAL_ID, + &visual_id, + error)) + { + g_free (egl_configs); + return FALSE; + } + + if ((uint32_t) visual_id == gbm_format) + { + *out_config = egl_configs[i]; + g_free (egl_configs); + return TRUE; + } + } + + g_free (egl_configs); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No EGL config matching supported GBM format found"); + return FALSE; +} + +static gboolean +meta_renderer_native_choose_egl_config (CoglDisplay *cogl_display, + EGLint *attributes, + EGLConfig *out_config, + GError **error) +{ + CoglRenderer *cogl_renderer = cogl_display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + EGLDisplay egl_display = cogl_renderer_egl->edpy; + + return choose_egl_config_from_gbm_format (egl, + egl_display, + attributes, + GBM_FORMAT_XRGB8888, + out_config, + error); +} + +static gboolean meta_renderer_native_setup_egl_display (CoglDisplay *cogl_display, GError **error) { @@ -2408,6 +2475,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen) static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable = { .add_config_attributes = meta_renderer_native_add_egl_config_attributes, + .choose_config = meta_renderer_native_choose_egl_config, .display_setup = meta_renderer_native_setup_egl_display, .display_destroy = meta_renderer_native_destroy_egl_display, .context_created = meta_renderer_native_egl_context_created, @@ -2846,11 +2914,12 @@ create_secondary_egl_config (MetaEgl *egl, EGL_NONE }; - return meta_egl_choose_first_config (egl, - egl_display, - attributes, - egl_config, - error); + return choose_egl_config_from_gbm_format (egl, + egl_display, + attributes, + GBM_FORMAT_XRGB8888, + egl_config, + error); } static EGLContext |