gl-renderer: use pixel_format_info instead of drm fourccs

Use struct pixel_format_info pointers instead of uint32_t drm fourcc
values at the API surface for output and image creation.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
Philipp Zabel 2023-01-26 17:33:05 +01:00 committed by Philipp Zabel
parent 782fd7f370
commit ad38c41a50
8 changed files with 91 additions and 83 deletions

View file

@ -64,43 +64,36 @@ create_gbm_device(int fd)
/* When initializing EGL, if the preferred buffer format isn't available
* we may be able to substitute an ARGB format for an XRGB one.
*
* This returns 0 if substitution isn't possible, but 0 might be a
* legitimate format for other EGL platforms, so the caller is
* responsible for checking for 0 before calling gl_renderer->create().
* This returns NULL if substitution isn't possible. The caller is responsible
* for checking for NULL before calling gl_renderer->create().
*
* 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 uint32_t
static const struct pixel_format_info *
fallback_format_for(uint32_t format)
{
const struct pixel_format_info *pf;
pf = pixel_format_get_info_by_opaque_substitute(format);
if (!pf)
return 0;
return pf->format;
return pixel_format_get_info_by_opaque_substitute(format);
}
static int
drm_backend_create_gl_renderer(struct drm_backend *b)
{
uint32_t format[3] = {
b->gbm_format,
const struct pixel_format_info *format[3] = {
pixel_format_get_info(b->gbm_format),
fallback_format_for(b->gbm_format),
0,
NULL,
};
struct gl_renderer_display_options options = {
.egl_platform = EGL_PLATFORM_GBM_KHR,
.egl_native_display = b->gbm,
.egl_surface_type = EGL_WINDOW_BIT,
.drm_formats = format,
.drm_formats_count = 2,
.formats = format,
.formats_count = 2,
};
if (format[1])
options.drm_formats_count = 3;
options.formats_count = 3;
return weston_compositor_init_renderer(b->compositor,
WESTON_RENDERER_GL,
@ -229,13 +222,13 @@ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
{
const struct weston_renderer *renderer = b->compositor->renderer;
const struct weston_mode *mode = output->base.current_mode;
uint32_t format[2] = {
output->gbm_format,
const struct pixel_format_info *format[2] = {
pixel_format_get_info(output->gbm_format),
fallback_format_for(output->gbm_format),
};
struct gl_renderer_output_options options = {
.drm_formats = format,
.drm_formats_count = 1,
.formats = format,
.formats_count = 1,
.area.x = 0,
.area.y = 0,
.area.width = mode->width,
@ -251,8 +244,8 @@ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
return -1;
}
if (options.drm_formats[1])
options.drm_formats_count = 2;
if (options.formats[1])
options.formats_count = 2;
options.window_for_legacy = (EGLNativeWindowType) output->gbm_surface;
options.window_for_platform = output->gbm_surface;
if (renderer->gl->output_window_create(&output->base, &options) < 0) {

View file

@ -46,6 +46,7 @@
#include "shared/weston-drm-fourcc.h"
#include "shared/weston-egl-ext.h"
#include "shared/cairo-util.h"
#include "shared/xalloc.h"
#include "linux-dmabuf.h"
#include "output-capture.h"
#include "presentation-time-server-protocol.h"
@ -59,6 +60,9 @@ struct headless_backend {
bool decorate;
struct theme *theme;
const struct pixel_format_info **formats;
unsigned int formats_count;
};
struct headless_head {
@ -249,8 +253,8 @@ headless_output_enable_gl(struct headless_output *output)
const struct weston_renderer *renderer = b->compositor->renderer;
const struct weston_mode *mode = output->base.current_mode;
struct gl_renderer_pbuffer_options options = {
.drm_formats = headless_formats,
.drm_formats_count = ARRAY_LENGTH(headless_formats),
.formats = b->formats,
.formats_count = b->formats_count,
};
if (b->decorate) {
@ -501,6 +505,7 @@ headless_destroy(struct weston_backend *backend)
if (b->theme)
theme_destroy(b->theme);
free(b->formats);
free(b);
}
@ -538,14 +543,17 @@ headless_backend_create(struct weston_compositor *compositor,
}
}
b->formats_count = ARRAY_LENGTH(headless_formats);
b->formats = pixel_format_get_array(headless_formats, b->formats_count);
switch (config->renderer) {
case WESTON_RENDERER_GL: {
const struct gl_renderer_display_options options = {
.egl_platform = EGL_PLATFORM_SURFACELESS_MESA,
.egl_native_display = NULL,
.egl_surface_type = EGL_PBUFFER_BIT,
.drm_formats = headless_formats,
.drm_formats_count = ARRAY_LENGTH(headless_formats),
.formats = b->formats,
.formats_count = b->formats_count,
};
ret = weston_compositor_init_renderer(compositor,
WESTON_RENDERER_GL,

View file

@ -57,6 +57,7 @@
#include "shared/os-compatibility.h"
#include "shared/cairo-util.h"
#include "shared/timespec-util.h"
#include "shared/xalloc.h"
#include "fullscreen-shell-unstable-v1-client-protocol.h"
#include "xdg-shell-client-protocol.h"
#include "presentation-time-server-protocol.h"
@ -100,6 +101,9 @@ struct wayland_backend {
/* These struct wayland_input objects are waiting for the outer
* compositor to provide a name and initial capabilities. */
struct wl_list pending_input_list;
const struct pixel_format_info **formats;
unsigned int formats_count;
};
struct wayland_output {
@ -727,10 +731,11 @@ static int
wayland_output_init_gl_renderer(struct wayland_output *output)
{
const struct weston_mode *mode = output->base.current_mode;
struct wayland_backend *b = output->backend;
const struct weston_renderer *renderer;
struct gl_renderer_output_options options = {
.drm_formats = wayland_formats,
.drm_formats_count = ARRAY_LENGTH(wayland_formats),
.formats = b->formats,
.formats_count = b->formats_count,
};
if (output->frame) {
@ -2811,14 +2816,17 @@ wayland_backend_create(struct weston_compositor *compositor,
create_cursor(b, new_config);
b->formats_count = ARRAY_LENGTH(wayland_formats);
b->formats = pixel_format_get_array(wayland_formats, b->formats_count);
if (renderer == WESTON_RENDERER_AUTO ||
renderer == WESTON_RENDERER_GL) {
const struct gl_renderer_display_options options = {
.egl_platform = EGL_PLATFORM_WAYLAND_KHR,
.egl_native_display = b->parent.wl_display,
.egl_surface_type = EGL_WINDOW_BIT,
.drm_formats = wayland_formats,
.drm_formats_count = ARRAY_LENGTH(wayland_formats),
.formats = b->formats,
.formats_count = b->formats_count,
};
if (weston_compositor_init_renderer(compositor,
@ -2868,6 +2876,7 @@ err_display:
wl_display_disconnect(b->parent.wl_display);
err_compositor:
weston_compositor_shutdown(compositor);
free(b->formats);
free(b);
return NULL;
}
@ -2884,6 +2893,7 @@ wayland_backend_destroy(struct wayland_backend *b)
wl_cursor_theme_destroy(b->cursor_theme);
weston_compositor_shutdown(b->compositor);
free(b->formats);
free(b);
}

View file

@ -59,6 +59,7 @@
#include "renderer-gl/gl-renderer.h"
#include "shared/weston-drm-fourcc.h"
#include "shared/weston-egl-ext.h"
#include "shared/xalloc.h"
#include "pixman-renderer.h"
#include "presentation-time-server-protocol.h"
#include "linux-dmabuf.h"
@ -120,6 +121,9 @@ struct x11_backend {
xcb_atom_t xkb_names;
} atom;
xcb_generic_event_t *prev_event;
const struct pixel_format_info **formats;
unsigned int formats_count;
};
struct x11_head {
@ -1056,8 +1060,8 @@ x11_output_enable(struct weston_output *base)
const struct gl_renderer_output_options options = {
.window_for_legacy = (EGLNativeWindowType) (uintptr_t) output->window,
.window_for_platform = &xid,
.drm_formats = x11_formats,
.drm_formats_count = ARRAY_LENGTH(x11_formats),
.formats = b->formats,
.formats_count = b->formats_count,
.area.x = 0,
.area.y = 0,
.area.width = mode->width,
@ -1836,6 +1840,7 @@ x11_destroy(struct weston_backend *base)
}
XCloseDisplay(backend->dpy);
free(backend->formats);
free(backend);
}
@ -1887,6 +1892,9 @@ x11_backend_create(struct weston_compositor *compositor,
config->fullscreen = 0;
}
b->formats_count = ARRAY_LENGTH(x11_formats);
b->formats = pixel_format_get_array(x11_formats, b->formats_count);
if (config->renderer == WESTON_RENDERER_PIXMAN) {
if (weston_compositor_init_renderer(compositor,
WESTON_RENDERER_PIXMAN,
@ -1900,8 +1908,8 @@ x11_backend_create(struct weston_compositor *compositor,
.egl_platform = EGL_PLATFORM_X11_KHR,
.egl_native_display = b->dpy,
.egl_surface_type = EGL_WINDOW_BIT,
.drm_formats = x11_formats,
.drm_formats_count = ARRAY_LENGTH(x11_formats),
.formats = b->formats,
.formats_count = b->formats_count,
};
if (weston_compositor_init_renderer(compositor,
WESTON_RENDERER_GL,
@ -1956,6 +1964,7 @@ err_renderer:
err_xdisplay:
XCloseDisplay(b->dpy);
err_free:
free(b->formats);
free(b);
return NULL;
}

View file

@ -392,12 +392,10 @@ explain_egl_config_criteria(EGLint egl_surface_type,
EGLConfig
gl_renderer_get_egl_config(struct gl_renderer *gr,
EGLint egl_surface_type,
const uint32_t *drm_formats,
unsigned drm_formats_count)
const struct pixel_format_info *const *formats,
unsigned formats_count)
{
EGLConfig egl_config;
const struct pixel_format_info *pinfo[16];
unsigned pinfo_count;
unsigned i;
char *what;
EGLint config_attribs[] = {
@ -409,27 +407,17 @@ gl_renderer_get_egl_config(struct gl_renderer *gr,
EGL_NONE
};
assert(drm_formats_count < ARRAY_LENGTH(pinfo));
drm_formats_count = MIN(drm_formats_count, ARRAY_LENGTH(pinfo));
for (pinfo_count = 0, i = 0; i < drm_formats_count; i++) {
pinfo[pinfo_count] = pixel_format_get_info(drm_formats[i]);
if (!pinfo[pinfo_count]) {
weston_log("Bad/unknown DRM format code 0x%08x.\n",
drm_formats[i]);
continue;
}
pinfo_count++;
}
for (i = 0; i < formats_count; i++)
assert(formats[i]);
if (egl_config_is_compatible(gr, gr->egl_config, egl_surface_type,
pinfo, pinfo_count))
formats, formats_count))
return gr->egl_config;
if (egl_choose_config(gr, config_attribs, pinfo, pinfo_count,
if (egl_choose_config(gr, config_attribs, formats, formats_count,
&egl_config) < 0) {
what = explain_egl_config_criteria(egl_surface_type,
pinfo, pinfo_count);
formats, formats_count);
weston_log("No EGLConfig matches %s.\n", what);
free(what);
log_all_egl_configs(gr->egl_display);
@ -444,7 +432,7 @@ gl_renderer_get_egl_config(struct gl_renderer *gr,
if (gr->egl_config != EGL_NO_CONFIG_KHR &&
egl_config != gr->egl_config) {
what = explain_egl_config_criteria(egl_surface_type,
pinfo, pinfo_count);
formats, formats_count);
weston_log("Found an EGLConfig matching %s but it is not usable"
" because neither EGL_KHR_no_config_context nor "
"EGL_MESA_configless_context are supported by EGL.\n",

View file

@ -229,8 +229,8 @@ log_egl_config_info(EGLDisplay egldpy, EGLConfig eglconfig);
EGLConfig
gl_renderer_get_egl_config(struct gl_renderer *gr,
EGLint egl_surface_type,
const uint32_t *drm_formats,
unsigned drm_formats_count);
const struct pixel_format_info *const *formats,
unsigned formats_count);
int
gl_renderer_setup_egl_display(struct gl_renderer *gr, void *native_display);

View file

@ -3449,14 +3449,14 @@ static EGLSurface
gl_renderer_create_window_surface(struct gl_renderer *gr,
EGLNativeWindowType window_for_legacy,
void *window_for_platform,
const uint32_t *drm_formats,
unsigned drm_formats_count)
const struct pixel_format_info *const *formats,
unsigned formats_count)
{
EGLSurface egl_surface = EGL_NO_SURFACE;
EGLConfig egl_config;
egl_config = gl_renderer_get_egl_config(gr, EGL_WINDOW_BIT,
drm_formats, drm_formats_count);
formats, formats_count);
if (egl_config == EGL_NO_CONFIG_KHR)
return EGL_NO_SURFACE;
@ -3541,8 +3541,8 @@ gl_renderer_output_window_create(struct weston_output *output,
egl_surface = gl_renderer_create_window_surface(gr,
options->window_for_legacy,
options->window_for_platform,
options->drm_formats,
options->drm_formats_count);
options->formats,
options->formats_count);
if (egl_surface == EGL_NO_SURFACE) {
weston_log("failed to create egl surface\n");
return -1;
@ -3573,8 +3573,8 @@ gl_renderer_output_pbuffer_create(struct weston_output *output,
};
pbuffer_config = gl_renderer_get_egl_config(gr, EGL_PBUFFER_BIT,
options->drm_formats,
options->drm_formats_count);
options->formats,
options->formats_count);
if (pbuffer_config == EGL_NO_CONFIG_KHR) {
weston_log("failed to choose EGL config for PbufferSurface\n");
return -1;
@ -3829,8 +3829,8 @@ gl_renderer_display_create(struct weston_compositor *ec,
gr->egl_config =
gl_renderer_get_egl_config(gr,
egl_surface_type,
options->drm_formats,
options->drm_formats_count);
options->formats,
options->formats_count);
if (gr->egl_config == EGL_NO_CONFIG_KHR) {
weston_log("failed to choose EGL config\n");
goto fail_terminate;

View file

@ -73,10 +73,10 @@ struct gl_renderer_display_options {
void *egl_native_display;
/** EGL_SURFACE_TYPE bits for the base EGLConfig */
EGLint egl_surface_type;
/** Array of DRM pixel formats acceptable for the base EGLConfig */
const uint32_t *drm_formats;
/** The \c drm_formats array length */
unsigned drm_formats_count;
/** Array of pixel formats acceptable for the base EGLConfig */
const struct pixel_format_info **formats;
/** The \c formats array length */
unsigned formats_count;
};
struct gl_renderer_output_options {
@ -88,10 +88,10 @@ struct gl_renderer_output_options {
struct weston_size fb_size;
/** Area inside the framebuffer in pixels for composited content */
struct weston_geometry area;
/** Array of DRM pixel formats acceptable for the window */
const uint32_t *drm_formats;
/** The \c drm_formats array length */
unsigned drm_formats_count;
/** Array of pixel formats acceptable for the window */
const struct pixel_format_info **formats;
/** The \c formats array length */
unsigned formats_count;
};
struct gl_renderer_pbuffer_options {
@ -99,10 +99,10 @@ struct gl_renderer_pbuffer_options {
struct weston_size fb_size;
/** Area inside the framebuffer in pixels for composited content */
struct weston_geometry area;
/** Array of DRM pixel formats acceptable for the pbuffer */
const uint32_t *drm_formats;
/** The \c drm_formats array length */
unsigned drm_formats_count;
/** Array of pixel formats acceptable for the pbuffer */
const struct pixel_format_info **formats;
/** The \c formats array length */
unsigned formats_count;
};
struct gl_renderer_interface {
@ -123,14 +123,14 @@ struct gl_renderer_interface {
* advertises it. Without the advertisement this function fails.
*
* If neither EGL_KHR_no_config_context or EGL_MESA_configless_context
* are supported, the arguments egl_surface_type, drm_formats, and
* drm_formats_count are used to find a so called base EGLConfig. The
* are supported, the arguments egl_surface_type, formats, and
* formats_count are used to find a so called base EGLConfig. The
* GL context is created with the base EGLConfig, and outputs will be
* required to use the same config as well. If one or both of the
* extensions are supported, these arguments are unused, and each
* output can use a different EGLConfig (pixel format).
*
* The first format in drm_formats that matches any EGLConfig
* The first format in formats that matches any EGLConfig
* determines which EGLConfig is chosen. On EGL GBM platform, the
* pixel format must match exactly. On other platforms, it is enough
* that each R, G, B, A channel has the same number of bits as in the
@ -154,7 +154,7 @@ struct gl_renderer_interface {
* used, otherwise \c window_for_legacy is used. This is because the
* handle on X11 platform is different between the two.
*
* The first format in drm_formats that matches any EGLConfig
* The first format in formats that matches any EGLConfig
* determines which EGLConfig is chosen. See \c display_create about
* how the matching works and the possible limitations.
*
@ -175,7 +175,7 @@ struct gl_renderer_interface {
* the output. The repaint results will be kept internal and can only
* be accessed through e.g. screen capture.
*
* The first format in drm_formats that matches any EGLConfig
* The first format in formats that matches any EGLConfig
* determines which EGLConfig is chosen. See \c display_create about
* how the matching works and the possible limitations.
*