mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 13:24:09 +00:00
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
This commit is contained in:
parent
7a41483ea0
commit
712ec30cd9
@ -90,6 +90,11 @@ typedef struct _CoglWinsysEGLVtable
|
|||||||
(* add_config_attributes) (CoglDisplay *display,
|
(* add_config_attributes) (CoglDisplay *display,
|
||||||
CoglFramebufferConfig *config,
|
CoglFramebufferConfig *config,
|
||||||
EGLint *attributes);
|
EGLint *attributes);
|
||||||
|
CoglBool
|
||||||
|
(* choose_config) (CoglDisplay *display,
|
||||||
|
EGLint *attributes,
|
||||||
|
EGLConfig *out_config,
|
||||||
|
CoglError **error);
|
||||||
} CoglWinsysEGLVtable;
|
} CoglWinsysEGLVtable;
|
||||||
|
|
||||||
typedef enum _CoglEGLWinsysFeature
|
typedef enum _CoglEGLWinsysFeature
|
||||||
|
@ -336,6 +336,32 @@ _cogl_winsys_egl_add_config_attributes (CoglDisplay *display,
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CoglBool
|
||||||
|
_cogl_winsys_egl_choose_config (CoglDisplay *display,
|
||||||
|
EGLint *attributes,
|
||||||
|
EGLConfig *out_config,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
CoglRenderer *renderer = display->renderer;
|
||||||
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
|
EGLint config_count = 0;
|
||||||
|
EGLBoolean status;
|
||||||
|
|
||||||
|
status = eglChooseConfig (egl_renderer->edpy,
|
||||||
|
attributes,
|
||||||
|
out_config, 1,
|
||||||
|
&config_count);
|
||||||
|
if (status != EGL_TRUE || config_count == 0)
|
||||||
|
{
|
||||||
|
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||||
|
"No compatible EGL configs found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
_cogl_winsys_egl_display_setup (CoglDisplay *display,
|
_cogl_winsys_egl_display_setup (CoglDisplay *display,
|
||||||
CoglError **error)
|
CoglError **error)
|
||||||
@ -841,6 +867,7 @@ static const CoglWinsysEGLVtable
|
|||||||
_cogl_winsys_egl_vtable =
|
_cogl_winsys_egl_vtable =
|
||||||
{
|
{
|
||||||
.add_config_attributes = _cogl_winsys_egl_add_config_attributes,
|
.add_config_attributes = _cogl_winsys_egl_add_config_attributes,
|
||||||
|
.choose_config = _cogl_winsys_egl_choose_config,
|
||||||
.display_setup = _cogl_winsys_egl_display_setup,
|
.display_setup = _cogl_winsys_egl_display_setup,
|
||||||
.display_destroy = _cogl_winsys_egl_display_destroy,
|
.display_destroy = _cogl_winsys_egl_display_destroy,
|
||||||
.context_created = _cogl_winsys_egl_context_created,
|
.context_created = _cogl_winsys_egl_context_created,
|
||||||
|
@ -338,10 +338,9 @@ try_create_context (CoglDisplay *display,
|
|||||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
EGLDisplay edpy;
|
EGLDisplay edpy;
|
||||||
EGLConfig config;
|
EGLConfig config;
|
||||||
EGLint config_count = 0;
|
|
||||||
EGLBoolean status;
|
|
||||||
EGLint attribs[9];
|
EGLint attribs[9];
|
||||||
EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS];
|
EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS];
|
||||||
|
GError *config_error = NULL;
|
||||||
const char *error_message;
|
const char *error_message;
|
||||||
|
|
||||||
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE);
|
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE);
|
||||||
@ -356,14 +355,16 @@ try_create_context (CoglDisplay *display,
|
|||||||
|
|
||||||
edpy = egl_renderer->edpy;
|
edpy = egl_renderer->edpy;
|
||||||
|
|
||||||
status = eglChooseConfig (edpy,
|
if (!egl_renderer->platform_vtable->choose_config (display,
|
||||||
cfg_attribs,
|
cfg_attribs,
|
||||||
&config, 1,
|
&config,
|
||||||
&config_count);
|
&config_error))
|
||||||
if (status != EGL_TRUE || config_count == 0)
|
|
||||||
{
|
{
|
||||||
error_message = "Unable to find a usable EGL configuration";
|
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
||||||
goto fail;
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||||
|
"Couldn't choose config: %s", config_error->message);
|
||||||
|
g_error_free (config_error);
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_display->egl_config = config;
|
egl_display->egl_config = config;
|
||||||
@ -419,6 +420,7 @@ fail:
|
|||||||
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||||
"%s", error_message);
|
"%s", error_message);
|
||||||
|
|
||||||
|
err:
|
||||||
cleanup_context (display);
|
cleanup_context (display);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -265,6 +265,72 @@ meta_egl_get_proc_address (MetaEgl *egl,
|
|||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
gboolean
|
||||||
meta_egl_choose_first_config (MetaEgl *egl,
|
meta_egl_choose_first_config (MetaEgl *egl,
|
||||||
EGLDisplay display,
|
EGLDisplay display,
|
||||||
|
@ -62,6 +62,19 @@ gboolean meta_egl_choose_first_config (MetaEgl *egl,
|
|||||||
EGLConfig *chosen_config,
|
EGLConfig *chosen_config,
|
||||||
GError **error);
|
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,
|
EGLContext meta_egl_create_context (MetaEgl *egl,
|
||||||
EGLDisplay display,
|
EGLDisplay display,
|
||||||
EGLConfig config,
|
EGLConfig config,
|
||||||
|
@ -934,6 +934,73 @@ meta_renderer_native_add_egl_config_attributes (CoglDisplay *cogl_disp
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static gboolean
|
||||||
meta_renderer_native_setup_egl_display (CoglDisplay *cogl_display,
|
meta_renderer_native_setup_egl_display (CoglDisplay *cogl_display,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -2408,6 +2475,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
|
|||||||
static const CoglWinsysEGLVtable
|
static const CoglWinsysEGLVtable
|
||||||
_cogl_winsys_egl_vtable = {
|
_cogl_winsys_egl_vtable = {
|
||||||
.add_config_attributes = meta_renderer_native_add_egl_config_attributes,
|
.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_setup = meta_renderer_native_setup_egl_display,
|
||||||
.display_destroy = meta_renderer_native_destroy_egl_display,
|
.display_destroy = meta_renderer_native_destroy_egl_display,
|
||||||
.context_created = meta_renderer_native_egl_context_created,
|
.context_created = meta_renderer_native_egl_context_created,
|
||||||
@ -2846,9 +2914,10 @@ create_secondary_egl_config (MetaEgl *egl,
|
|||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
return meta_egl_choose_first_config (egl,
|
return choose_egl_config_from_gbm_format (egl,
|
||||||
egl_display,
|
egl_display,
|
||||||
attributes,
|
attributes,
|
||||||
|
GBM_FORMAT_XRGB8888,
|
||||||
egl_config,
|
egl_config,
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user