diff --git a/libweston/renderer-gl/egl-glue.c b/libweston/renderer-gl/egl-glue.c index ebea9370e..f26852923 100644 --- a/libweston/renderer-gl/egl-glue.c +++ b/libweston/renderer-gl/egl-glue.c @@ -280,6 +280,67 @@ out: free(configs); } +const struct pixel_format_info ** +egl_set_supported_rendering_formats(EGLDisplay egldpy, + unsigned int *formats_count) +{ + struct wl_array formats; + const struct pixel_format_info **f, *p; + EGLConfig *configs; + EGLint count = 0; + EGLint value; + EGLint i; + bool found; + + wl_array_init(&formats); + + if (!eglGetConfigs(egldpy, NULL, 0, &count) || count < 1) + return NULL; + + configs = zalloc(count * sizeof(*configs)); + if (!configs) + return NULL; + + if (!eglGetConfigs(egldpy, configs, count, &count)) { + free(configs); + return NULL; + } + + for (i = 0; i < count; i++) { + if (!eglGetConfigAttrib(egldpy, configs[i], EGL_SURFACE_TYPE, &value)) + continue; + if (!(value & EGL_WINDOW_BIT)) + continue; + + if (!eglGetConfigAttrib(egldpy, configs[i], EGL_NATIVE_VISUAL_ID, &value)) + continue; + if (value == 0) + continue; + + p = pixel_format_get_info(value); + if (!p) + continue; + + found = false; + wl_array_for_each(f, &formats) { + if (p == (*f)) { + found = true; + break; + } + } + if (found) + continue; + + f = wl_array_add(&formats, sizeof(*f)); + *f = p; + } + + free(configs); + + *formats_count = formats.size / sizeof(p); + return formats.data; +} + void log_egl_config_info(struct gl_renderer *gr, EGLConfig eglconfig) { diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index e92c3760b..55ce937e7 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -405,6 +405,9 @@ struct gl_renderer { struct weston_drm_format_array supported_dmabuf_formats; + unsigned int supported_rendering_formats_count; + const struct pixel_format_info **supported_rendering_formats; + uint64_t egl_client_extensions; uint64_t egl_device_extensions; uint64_t egl_display_extensions; @@ -682,6 +685,10 @@ gl_renderer_log_extensions(struct gl_renderer *gr, void log_egl_config_info(struct gl_renderer *gr, EGLConfig eglconfig); +const struct pixel_format_info ** +egl_set_supported_rendering_formats(EGLDisplay egldpy, + unsigned int *formats_count); + EGLConfig gl_renderer_get_egl_config(struct gl_renderer *gr, EGLint egl_surface_type, diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index d6645e9a0..320aa3d22 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -4321,6 +4321,16 @@ gl_renderer_output_window_create(struct weston_output *output, return ret; } +static const struct pixel_format_info ** +gl_renderer_get_supported_rendering_formats(struct weston_compositor *ec, + unsigned int *formats_count) +{ + struct gl_renderer *gr = get_renderer(ec); + + *formats_count = gr->supported_rendering_formats_count; + return gr->supported_rendering_formats; +} + static int gl_renderer_output_fbo_create(struct weston_output *output, const struct gl_renderer_fbo_options *options) @@ -4546,6 +4556,7 @@ gl_renderer_destroy(struct weston_compositor *ec) dmabuf_format_destroy(format); weston_drm_format_array_fini(&gr->supported_dmabuf_formats); + free(gr->supported_rendering_formats); gl_renderer_allocator_destroy(gr->allocator); @@ -4688,6 +4699,14 @@ gl_renderer_display_create(struct weston_compositor *ec, if (gr->allocator) gr->base.dmabuf_alloc = gl_renderer_dmabuf_alloc; + if (gr->platform == EGL_PLATFORM_GBM_KHR) { + gr->supported_rendering_formats = + egl_set_supported_rendering_formats(gr->egl_display, + &gr->supported_rendering_formats_count); + if (!gr->supported_rendering_formats) + goto fail_terminate; + } + /* No need to check for GL_OES_EGL_image_external because this is gated * by EGL_EXT_image_dma_buf_import_modifiers which depends on it. */ if (egl_display_has(gr, EXTENSION_EXT_IMAGE_DMA_BUF_IMPORT) && @@ -4764,6 +4783,7 @@ fail_feedback: ec->dmabuf_feedback_format_table = NULL; } fail_terminate: + free(gr->supported_rendering_formats); weston_drm_format_array_fini(&gr->supported_dmabuf_formats); eglTerminate(gr->egl_display); fail: @@ -5078,6 +5098,7 @@ gl_renderer_setup(struct weston_compositor *ec) WL_EXPORT struct gl_renderer_interface gl_renderer_interface = { .display_create = gl_renderer_display_create, .output_window_create = gl_renderer_output_window_create, + .get_supported_rendering_formats = gl_renderer_get_supported_rendering_formats, .output_fbo_create = gl_renderer_output_fbo_create, .output_destroy = gl_renderer_output_destroy, .create_fence_fd = gl_renderer_create_fence_fd, diff --git a/libweston/renderer-gl/gl-renderer.h b/libweston/renderer-gl/gl-renderer.h index 232e5900d..2afb9a953 100644 --- a/libweston/renderer-gl/gl-renderer.h +++ b/libweston/renderer-gl/gl-renderer.h @@ -153,6 +153,21 @@ struct gl_renderer_interface { int (*output_window_create)(struct weston_output *output, const struct gl_renderer_output_options *options); + /** + * Query rendering formats supported by EGL on GBM platform + * + * \param ec The weston_compositor. + * \param formats_count The number of formats in the returned array. + * \return The array of formats supported, or NULL on failure. + * + * This function returns the formats that are present in the EGLConfig's + * that we query from the EGLDisplay. Such formats can be used for + * rendering. + */ + const struct pixel_format_info ** + (*get_supported_rendering_formats)(struct weston_compositor *ec, + unsigned int *formats_count); + /** * Attach GL-renderer to the output with a frame buffer object *