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:
parent
782fd7f370
commit
ad38c41a50
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user