summaryrefslogtreecommitdiff
path: root/src/egl
diff options
context:
space:
mode:
authorHal Gentz <zegentzy@protonmail.com>2019-10-10 18:35:50 -0600
committerAdam Jackson <ajax@nwnk.net>2019-10-11 21:57:21 +0000
commit075a96aa926e6e89795f95a6a59693f44d9ac970 (patch)
tree81b0142a0494f8325711ab37542bb2f7051e57af /src/egl
parenta800d16e4f1589e41e53edf8e8a771a33bb46a6a (diff)
downloadmesa-075a96aa926e6e89795f95a6a59693f44d9ac970.tar.gz
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>
Diffstat (limited to 'src/egl')
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c57
-rw-r--r--src/egl/drivers/dri2/egl_dri2.h3
-rw-r--r--src/egl/drivers/dri2/platform_android.c2
-rw-r--r--src/egl/drivers/dri2/platform_device.c2
-rw-r--r--src/egl/drivers/dri2/platform_drm.c2
-rw-r--r--src/egl/drivers/dri2/platform_surfaceless.c2
-rw-r--r--src/egl/drivers/dri2/platform_wayland.c2
-rw-r--r--src/egl/drivers/dri2/platform_x11.c2
-rw-r--r--src/egl/main/eglconfig.c10
-rw-r--r--src/egl/main/eglconfig.h3
10 files changed, 78 insertions, 7 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 63864346594..3d17c8f11cd 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -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)
{
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 146f954eacf..9bd859869f8 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -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,
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index 35d40e567dc..e395bb27cb2 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -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",
diff --git a/src/egl/drivers/dri2/platform_device.c b/src/egl/drivers/dri2/platform_device.c
index 9bd7a93270d..b36033ba504 100644
--- a/src/egl/drivers/dri2/platform_device.c
+++ b/src/egl/drivers/dri2/platform_device.c
@@ -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",
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index d0ab172d659..551b9392125 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -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;
diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c
index 1a2d3be0aad..8361b9ade47 100644
--- a/src/egl/drivers/dri2/platform_surfaceless.c
+++ b/src/egl/drivers/dri2/platform_surfaceless.c
@@ -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",
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 71bcb04a77b..3de9695f45e 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -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",
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index b3ed7b943da..45c06ae04b3 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -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;
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index b3362363664..b15ba758278 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -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.
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index 064187ff1dd..e9b87d98a9d 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -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);