From 8e42af02a67899288c9ce85ae75ca791b55d7cb8 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Fri, 13 Sep 2019 15:35:10 +0300 Subject: [PATCH] gl_renderer: introduce gl_renderer_get_egl_config() In an attempt to pull more of EGLConfig choosing into one place, refactor code into the new gl_renderer_get_egl_config(). The purpose of this function is to find an EGL config that not only satisfies the requested attributes and the pixel formats if given but also makes sure the config is generally compatible with the single GL context we have. All this was already checked in gl_renderer_create_window_surface(), but gl_renderer_create_pbuffer_surface() is still missing it. This patch is preparation for fixing the pbuffer path. We explicitly replace visual_id with drm_formats, because that is what they really are. Only the DRM backend passes in other than NULL/0, and if other backends start caring about the actual pixel format, drm_format is the lingua franca. Signed-off-by: Pekka Paalanen --- libweston/backend-drm/drm.c | 6 +-- libweston/renderer-gl/egl-glue.c | 44 +++++++++++++++++++- libweston/renderer-gl/gl-renderer-internal.h | 6 +++ libweston/renderer-gl/gl-renderer.c | 28 +++++-------- libweston/renderer-gl/gl-renderer.h | 4 +- 5 files changed, 64 insertions(+), 24 deletions(-) diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index e6db80c9..e96b7b75 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -720,7 +720,7 @@ create_gbm_device(int fd) * This works around https://bugs.freedesktop.org/show_bug.cgi?id=89689 * but it's entirely possible we'll see this again on other implementations. */ -static int +static uint32_t fallback_format_for(uint32_t format) { const struct pixel_format_info *pf; @@ -1338,11 +1338,11 @@ err: static int drm_output_init_egl(struct drm_output *output, struct drm_backend *b) { - EGLint format[2] = { + uint32_t format[2] = { output->gbm_format, fallback_format_for(output->gbm_format), }; - int n_formats = 1; + unsigned n_formats = 1; struct weston_mode *mode = output->base.current_mode; struct drm_plane *plane = output->scanout_plane; unsigned int i; diff --git a/libweston/renderer-gl/egl-glue.c b/libweston/renderer-gl/egl-glue.c index 845c9b76..7f3dadad 100644 --- a/libweston/renderer-gl/egl-glue.c +++ b/libweston/renderer-gl/egl-glue.c @@ -1,6 +1,6 @@ /* * Copyright © 2012 Intel Corporation - * Copyright © 2015 Collabora, Ltd. + * Copyright © 2015, 2019 Collabora, Ltd. * Copyright © 2016 NVIDIA Corporation * * Permission is hereby granted, free of charge, to any person obtaining @@ -27,6 +27,8 @@ #include "config.h" +#include + #include "shared/helpers.h" #include "shared/platform.h" @@ -167,6 +169,46 @@ out: return 0; } +EGLConfig +gl_renderer_get_egl_config(struct gl_renderer *gr, + const EGLint *config_attribs, + const uint32_t *drm_formats, + unsigned drm_formats_count) +{ + EGLConfig egl_config; + EGLint visual_id[16]; + int id_count; + int i; + + assert(drm_formats_count < ARRAY_LENGTH(visual_id)); + id_count = MIN(drm_formats_count, ARRAY_LENGTH(visual_id)); + + for (i = 0; i < id_count; i++) + visual_id[i] = drm_formats[i]; + + if (egl_choose_config(gr, config_attribs, visual_id, + id_count, &egl_config) < 0) { + weston_log("No EGLConfig matches.\n"); + return EGL_NO_CONFIG_KHR; + } + + /* + * If we do not have configless context support, all EGLConfigs must + * be the one and the same, because we use just one GL context for + * everything. + */ + if (gr->egl_config != EGL_NO_CONFIG_KHR && + egl_config != gr->egl_config && + !gr->has_configless_context) { + weston_log("Found an EGLConfig but it is not usable because " + "neither EGL_KHR_no_config_context nor " + "EGL_MESA_configless_context are supported by EGL.\n"); + return EGL_NO_CONFIG_KHR; + } + + return egl_config; +} + static void renderer_setup_egl_client_extensions(struct gl_renderer *gr) { diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index 248c5f01..0248424f 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -131,6 +131,12 @@ egl_choose_config(struct gl_renderer *gr, const EGLint *attribs, const EGLint *visual_id, const int n_ids, EGLConfig *config_out); +EGLConfig +gl_renderer_get_egl_config(struct gl_renderer *gr, + const EGLint *config_attribs, + const uint32_t *drm_formats, + unsigned drm_formats_count); + int gl_renderer_setup_egl_extensions(struct weston_compositor *ec); diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index b805075b..14b5ae94 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -1,6 +1,6 @@ /* * Copyright © 2012 Intel Corporation - * Copyright © 2015 Collabora, Ltd. + * Copyright © 2015,2019 Collabora, Ltd. * Copyright © 2016 NVIDIA Corporation * * Permission is hereby granted, free of charge, to any person obtaining @@ -3062,25 +3062,16 @@ gl_renderer_create_window_surface(struct gl_renderer *gr, EGLNativeWindowType window_for_legacy, void *window_for_platform, const EGLint *config_attribs, - const EGLint *visual_id, - int n_ids) + const uint32_t *drm_formats, + unsigned drm_formats_count) { EGLSurface egl_surface = EGL_NO_SURFACE; EGLConfig egl_config; - if (egl_choose_config(gr, config_attribs, visual_id, - n_ids, &egl_config) == -1) { - weston_log("failed to choose EGL config for output\n"); + egl_config = gl_renderer_get_egl_config(gr, config_attribs, + drm_formats, drm_formats_count); + if (egl_config == EGL_NO_CONFIG_KHR) return EGL_NO_SURFACE; - } - - if (egl_config != gr->egl_config && - !gr->has_configless_context) { - weston_log("attempted to use a different EGL config for an " - "output but EGL_KHR_no_config_context or " - "EGL_MESA_configless_context is not supported\n"); - return EGL_NO_SURFACE; - } log_egl_config_info(gr->egl_display, egl_config); @@ -3128,8 +3119,8 @@ gl_renderer_output_window_create(struct weston_output *output, EGLNativeWindowType window_for_legacy, void *window_for_platform, const EGLint *config_attribs, - const EGLint *visual_id, - int n_ids) + const uint32_t *drm_formats, + unsigned drm_formats_count) { struct weston_compositor *ec = output->compositor; struct gl_renderer *gr = get_renderer(ec); @@ -3140,7 +3131,8 @@ gl_renderer_output_window_create(struct weston_output *output, window_for_legacy, window_for_platform, config_attribs, - visual_id, n_ids); + drm_formats, + drm_formats_count); if (egl_surface == EGL_NO_SURFACE) { weston_log("failed to create egl surface\n"); return -1; diff --git a/libweston/renderer-gl/gl-renderer.h b/libweston/renderer-gl/gl-renderer.h index 9a062236..91a45763 100644 --- a/libweston/renderer-gl/gl-renderer.h +++ b/libweston/renderer-gl/gl-renderer.h @@ -71,8 +71,8 @@ struct gl_renderer_interface { EGLNativeWindowType window_for_legacy, void *window_for_platform, const EGLint *config_attribs, - const EGLint *visual_id, - const int n_ids); + const uint32_t *drm_formats, + unsigned drm_formats_count); void (*output_destroy)(struct weston_output *output);