egl: Configs w/o double buffering support have no `EGL_WINDOW_BIT`.

When users pass a config to `eglCreateWindowSurface` it requests double
buffering, but if the config doesn't have the appropriate `__DRIconfig`,
`eglCreateWindowSurface` fails with a `EGL_BAD_MATCH`.

Given that such behaviour is completely unacceptable, we drop the
`EGL_WINDOW_BIT` if we don't have at least one `__DRIconfig` supporting double
buffering, otherwise dropping the `EGL_PIXMAP_BIT`.

Fixes: 049f343e8ac "egl: Allow 24-bit visuals for 32-bit RGBA8888 configs"
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67676
Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hal Gentz <zegentzy@protonmail.com>
This commit is contained in:
Hal Gentz 2019-10-10 18:35:50 -06:00 committed by Adam Jackson
parent a800d16e4f
commit 075a96aa92
10 changed files with 78 additions and 7 deletions

View File

@ -425,10 +425,6 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
base.BindToTextureRGBA = bind_to_texture_rgba;
}
if (double_buffer) {
surface_type &= ~EGL_PIXMAP_BIT;
}
/* No support for pbuffer + MSAA for now.
*
* XXX TODO: pbuffer + MSAA does not work and causes crashes.
@ -438,9 +434,6 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
surface_type &= ~EGL_PBUFFER_BIT;
}
if (!surface_type)
return NULL;
base.RenderableType = disp->ClientAPIs;
base.Conformant = disp->ClientAPIs;
@ -490,6 +483,56 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
return conf;
}
/*
* We finalize the set of `SurfaceType`s supported by a config, and only
* reinsert it if it actually supports something.
*/
void
dri2_finalize_config_surface_types(_EGLDisplay *disp)
{
_EGLArray *configs = _eglWipeConfigs(disp);
for (int i = 0; i < configs->Size; ++i)
{
// Since `base` is the first member of `dri2_egl_config`, `base`'s ptr
// should equal `dri2_egl_config`'s. This is why this cast is safe.
struct dri2_egl_config *conf
= (struct dri2_egl_config *) configs->Elements[i];
const bool double_buffer = conf->dri_config[true][false]
|| conf->dri_config[true][true];
const bool single_buffer = conf->dri_config[false][false]
|| conf->dri_config[false][true];
/* No support for pixmaps without single buffered dri configs.
*
* When users pass a config to `eglCreateWindowSurface` it requests
* double buffering, but if the config doesn't have the appropriate
* `__DRIconfig`, `eglCreateWindowSurface` fails with a `EGL_BAD_MATCH`.
*
* Given that such behaviour is completely unacceptable, we drop the
* `EGL_WINDOW_BIT` if we don't have at least one `__DRIconfig`
* supporting double buffering.
*/
if (!single_buffer) {
conf->base.SurfaceType &= ~EGL_PIXMAP_BIT;
}
if (!double_buffer) {
conf->base.SurfaceType &= ~EGL_WINDOW_BIT;
}
// Dont reinsert configs without some supported surface type.
if (!conf->base.SurfaceType) {
free(conf);
continue;
}
_eglLinkConfig(&conf->base);
}
}
__DRIimage *
dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data)
{

View File

@ -419,6 +419,9 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
EGLint surface_type, const EGLint *attr_list,
const int *rgba_shifts, const unsigned int *rgba_sizes);
void
dri2_finalize_config_surface_types(_EGLDisplay *disp);
_EGLImage *
dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
_EGLContext *ctx, EGLenum target,

View File

@ -1225,6 +1225,8 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
has_rgba = true;
}
dri2_finalize_config_surface_types(disp);
for (int i = 0; i < ARRAY_SIZE(format_count); i++) {
if (!format_count[i]) {
_eglLog(_EGL_DEBUG, "No DRI config supports native format 0x%x",

View File

@ -216,6 +216,8 @@ device_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
}
}
dri2_finalize_config_surface_types(disp);
for (unsigned i = 0; i < ARRAY_SIZE(format_count); i++) {
if (!format_count[i]) {
_eglLog(_EGL_DEBUG, "No DRI config supports native format %s",

View File

@ -658,6 +658,8 @@ drm_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
}
}
dri2_finalize_config_surface_types(disp);
for (unsigned i = 0; i < ARRAY_SIZE(format_count); i++) {
if (!format_count[i]) {
struct gbm_format_name_desc desc;

View File

@ -212,6 +212,8 @@ surfaceless_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
}
}
dri2_finalize_config_surface_types(disp);
for (unsigned i = 0; i < ARRAY_SIZE(format_count); i++) {
if (!format_count[i]) {
_eglLog(_EGL_DEBUG, "No DRI config supports native format %s",

View File

@ -1445,6 +1445,8 @@ dri2_wl_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
}
}
dri2_finalize_config_surface_types(disp);
for (unsigned i = 0; i < ARRAY_SIZE(format_count); i++) {
if (!format_count[i]) {
_eglLog(_EGL_DEBUG, "No DRI config supports native format %s",

View File

@ -848,6 +848,8 @@ dri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
xcb_depth_next(&d);
}
dri2_finalize_config_surface_types(disp);
if (!config_count) {
_eglLog(_EGL_WARNING, "DRI2: failed to create any config");
return EGL_FALSE;

View File

@ -71,6 +71,16 @@ _eglInitConfig(_EGLConfig *conf, _EGLDisplay *disp, EGLint id)
conf->ComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
}
/*
* Wipe the configs list and return the old list
*/
_EGLArray *
_eglWipeConfigs(_EGLDisplay *disp)
{
_EGLArray *configs = disp->Configs;
disp->Configs = NULL;
return configs;
}
/**
* Link a config to its display and return the handle of the link.

View File

@ -179,6 +179,9 @@ _eglGetConfigKey(const _EGLConfig *conf, EGLint key)
extern void
_eglInitConfig(_EGLConfig *config, _EGLDisplay *disp, EGLint id);
extern _EGLArray *
_eglWipeConfigs(_EGLDisplay *disp);
extern EGLConfig
_eglLinkConfig(_EGLConfig *conf);