libweston, backends: move GL renderer interface into weston_renderer

Move the struct gl_renderer_interface pointer from the backends into
the weston_renderer structure. The interface struct only contains
function pointers that never change, so make it const.

Load and initialize the GL renderer in libweston instead of in the
backends, using the new weston_compositor_init_renderer() function.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
Philipp Zabel 2022-12-14 16:29:29 +01:00
parent e96494801b
commit fc8d260ce3
11 changed files with 120 additions and 104 deletions

View File

@ -44,19 +44,11 @@
#include "linux-dmabuf.h"
#include "linux-explicit-synchronization.h"
struct gl_renderer_interface *gl_renderer;
static struct gbm_device *
create_gbm_device(int fd)
{
struct gbm_device *gbm;
gl_renderer = weston_load_module("gl-renderer.so",
"gl_renderer_interface",
LIBWESTON_MODULEDIR);
if (!gl_renderer)
return NULL;
/* GBM will load a dri driver, but even though they need symbols from
* libglapi, in some version of Mesa they are not linked to it. Since
* only the gl-renderer module links to it, the call above won't make
@ -110,10 +102,9 @@ drm_backend_create_gl_renderer(struct drm_backend *b)
if (format[1])
options.drm_formats_count = 3;
if (gl_renderer->display_create(b->compositor, &options) < 0)
return -1;
return 0;
return weston_compositor_init_renderer(b->compositor,
WESTON_RENDERER_GL,
&options.base);
}
int
@ -236,6 +227,7 @@ create_gbm_surface(struct gbm_device *gbm, struct drm_output *output)
int
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,
@ -263,7 +255,7 @@ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
options.drm_formats_count = 2;
options.window_for_legacy = (EGLNativeWindowType) output->gbm_surface;
options.window_for_platform = output->gbm_surface;
if (gl_renderer->output_window_create(&output->base, &options) < 0) {
if (renderer->gl->output_window_create(&output->base, &options) < 0) {
weston_log("failed to create gl renderer output state\n");
gbm_surface_destroy(output->gbm_surface);
output->gbm_surface = NULL;
@ -279,6 +271,7 @@ void
drm_output_fini_egl(struct drm_output *output)
{
struct drm_backend *b = output->backend;
const struct weston_renderer *renderer = b->compositor->renderer;
/* Destroying the GBM surface will destroy all our GBM buffers,
* regardless of refcount. Ensure we destroy them here. */
@ -288,7 +281,7 @@ drm_output_fini_egl(struct drm_output *output)
drm_plane_reset_state(output->scanout_plane);
}
gl_renderer->output_destroy(&output->base);
renderer->gl->output_destroy(&output->base);
gbm_surface_destroy(output->gbm_surface);
output->gbm_surface = NULL;
drm_output_fini_cursor_egl(output);

View File

@ -863,8 +863,6 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage);
int
parse_gbm_format(const char *s, uint32_t default_value, uint32_t *gbm_format);
extern struct gl_renderer_interface *gl_renderer;
#ifdef BUILD_DRM_VIRTUAL
extern int
drm_backend_init_virtual_output_api(struct weston_compositor *compositor);

View File

@ -390,7 +390,10 @@ drm_virtual_output_set_submit_frame_cb(struct weston_output *output_base,
static int
drm_virtual_output_get_fence_fd(struct weston_output *output_base)
{
return gl_renderer->create_fence_fd(output_base);
struct weston_compositor *compositor = output_base->compositor;
const struct weston_renderer *renderer = compositor->renderer;
return renderer->gl->create_fence_fd(output_base);
}
static void

View File

@ -56,7 +56,6 @@ struct headless_backend {
struct weston_seat fake_seat;
struct gl_renderer_interface *glri;
bool decorate;
struct theme *theme;
};
@ -138,15 +137,13 @@ finish_frame_handler(void *data)
static void
headless_output_update_gl_border(struct headless_output *output)
{
struct headless_backend *backend = output->backend;
if (!output->frame)
return;
if (!(frame_status(output->frame) & FRAME_STATUS_REPAINT))
return;
weston_gl_borders_update(&output->gl.borders, output->frame,
&output->base, backend->glri);
&output->base);
}
static int
@ -175,11 +172,12 @@ headless_output_repaint(struct weston_output *output_base,
static void
headless_output_disable_gl(struct headless_output *output)
{
struct headless_backend *b = output->backend;
struct weston_compositor *compositor = output->base.compositor;
const struct weston_renderer *renderer = compositor->renderer;
weston_gl_borders_fini(&output->gl.borders, &output->base, b->glri);
weston_gl_borders_fini(&output->gl.borders, &output->base);
b->glri->output_destroy(&output->base);
renderer->gl->output_destroy(&output->base);
if (output->frame) {
frame_destroy(output->frame);
@ -243,6 +241,7 @@ static int
headless_output_enable_gl(struct headless_output *output)
{
struct headless_backend *b = output->backend;
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,
@ -275,7 +274,7 @@ headless_output_enable_gl(struct headless_output *output)
options.fb_size.height = mode->height;
}
if (b->glri->output_pbuffer_create(&output->base, &options) < 0) {
if (renderer->gl->output_pbuffer_create(&output->base, &options) < 0) {
weston_log("failed to create gl renderer output state\n");
if (output->frame) {
frame_destroy(output->frame);
@ -502,26 +501,6 @@ headless_destroy(struct weston_backend *backend)
free(b);
}
static int
headless_gl_renderer_init(struct headless_backend *b)
{
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),
};
b->glri = weston_load_module("gl-renderer.so",
"gl_renderer_interface",
LIBWESTON_MODULEDIR);
if (!b->glri)
return -1;
return b->glri->display_create(b->compositor, &options);
}
static const struct weston_windowed_output_api api = {
headless_output_set_size,
headless_head_create,
@ -557,9 +536,19 @@ headless_backend_create(struct weston_compositor *compositor,
}
switch (config->renderer) {
case WESTON_RENDERER_GL:
ret = headless_gl_renderer_init(b);
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),
};
ret = weston_compositor_init_renderer(compositor,
WESTON_RENDERER_GL,
&options.base);
break;
}
case WESTON_RENDERER_PIXMAN:
if (config->decorate) {
weston_log("Error: Pixman renderer does not support decorations.\n");

View File

@ -225,8 +225,6 @@ struct wayland_input {
enum wl_seat_capability caps;
};
struct gl_renderer_interface *gl_renderer;
static void
wayland_destroy(struct weston_backend *backend);
@ -445,7 +443,7 @@ wayland_output_update_gl_border(struct wayland_output *output)
return;
weston_gl_borders_update(&output->gl.borders, output->frame,
&output->base, gl_renderer);
&output->base);
}
#endif
@ -664,6 +662,7 @@ wayland_output_destroy_shm_buffers(struct wayland_output *output)
static int
wayland_output_disable(struct weston_output *base)
{
const struct weston_renderer *renderer = base->compositor->renderer;
struct wayland_output *output = to_wayland_output(base);
assert(output);
@ -671,14 +670,13 @@ wayland_output_disable(struct weston_output *base)
if (!output->base.enabled)
return 0;
if (base->compositor->renderer->type == WESTON_RENDERER_PIXMAN) {
if (renderer->type == WESTON_RENDERER_PIXMAN) {
pixman_renderer_output_destroy(&output->base);
#ifdef ENABLE_EGL
} else {
weston_gl_borders_fini(&output->gl.borders,
&output->base, gl_renderer);
weston_gl_borders_fini(&output->gl.borders, &output->base);
gl_renderer->output_destroy(&output->base);
renderer->gl->output_destroy(&output->base);
wl_egl_window_destroy(output->gl.egl_window);
#endif
}
@ -716,6 +714,7 @@ static int
wayland_output_init_gl_renderer(struct wayland_output *output)
{
const struct weston_mode *mode = output->base.current_mode;
const struct weston_renderer *renderer;
struct gl_renderer_output_options options = {
.drm_formats = wayland_formats,
.drm_formats_count = ARRAY_LENGTH(wayland_formats),
@ -746,7 +745,9 @@ wayland_output_init_gl_renderer(struct wayland_output *output)
options.window_for_legacy = output->gl.egl_window;
options.window_for_platform = output->gl.egl_window;
if (gl_renderer->output_window_create(&output->base, &options) < 0)
renderer = output->base.compositor->renderer;
if (renderer->gl->output_window_create(&output->base, &options) < 0)
goto cleanup_window;
return 0;
@ -824,8 +825,7 @@ wayland_output_resize_surface(struct wayland_output *output)
weston_renderer_resize_output(&output->base, &fb_size, &area);
/* These will need to be re-created due to the resize */
weston_gl_borders_fini(&output->gl.borders,
&output->base, gl_renderer);
weston_gl_borders_fini(&output->gl.borders, &output->base);
} else
#endif
{
@ -1060,7 +1060,10 @@ wayland_output_switch_mode(struct weston_output *output_base,
goto err_output;
#ifdef ENABLE_EGL
} else {
gl_renderer->output_destroy(output_base);
struct weston_compositor *compositor = output_base->compositor;
const struct weston_renderer *renderer = compositor->renderer;
renderer->gl->output_destroy(output_base);
wl_egl_window_destroy(output->gl.egl_window);
if (wayland_output_init_gl_renderer(output) < 0)
goto err_output;
@ -2793,7 +2796,8 @@ wayland_backend_create(struct weston_compositor *compositor,
create_cursor(b, new_config);
if (renderer == WESTON_RENDERER_AUTO || renderer == WESTON_RENDERER_GL) {
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,
@ -2802,14 +2806,9 @@ wayland_backend_create(struct weston_compositor *compositor,
.drm_formats_count = ARRAY_LENGTH(wayland_formats),
};
#ifdef ENABLE_EGL
gl_renderer = weston_load_module("gl-renderer.so",
"gl_renderer_interface",
LIBWESTON_MODULEDIR);
#endif
if (!gl_renderer ||
gl_renderer->display_create(compositor, &options) < 0) {
if (weston_compositor_init_renderer(compositor,
WESTON_RENDERER_GL,
&options.base) < 0) {
weston_log("Failed to initialize the GL renderer");
if (renderer == WESTON_RENDERER_AUTO) {
weston_log_continue("; falling back to Pixman.\n");

View File

@ -150,8 +150,6 @@ struct window_delete_data {
xcb_window_t window;
};
struct gl_renderer_interface *gl_renderer;
static void
x11_destroy(struct weston_backend *backend);
@ -874,6 +872,7 @@ x11_output_switch_mode(struct weston_output *base, struct weston_mode *mode)
static int
x11_output_disable(struct weston_output *base)
{
const struct weston_renderer *renderer = base->compositor->renderer;
struct x11_output *output = to_x11_output(base);
struct x11_backend *backend;
@ -886,11 +885,11 @@ x11_output_disable(struct weston_output *base)
wl_event_source_remove(output->finish_frame_timer);
if (base->compositor->renderer->type == WESTON_RENDERER_PIXMAN) {
if (renderer->type == WESTON_RENDERER_PIXMAN) {
pixman_renderer_output_destroy(&output->base);
x11_output_deinit_shm(backend, output);
} else {
gl_renderer->output_destroy(&output->base);
renderer->gl->output_destroy(&output->base);
}
xcb_destroy_window(backend->conn, output->window);
@ -915,6 +914,7 @@ x11_output_destroy(struct weston_output *base)
static int
x11_output_enable(struct weston_output *base)
{
const struct weston_renderer *renderer = base->compositor->renderer;
struct x11_output *output = to_x11_output(base);
const struct weston_mode *mode = output->base.current_mode;
struct x11_backend *b;
@ -1020,7 +1020,7 @@ x11_output_enable(struct weston_output *base)
if (b->fullscreen)
x11_output_wait_for_map(b, output);
if (base->compositor->renderer->type == WESTON_RENDERER_PIXMAN) {
if (renderer->type == WESTON_RENDERER_PIXMAN) {
const struct pixman_renderer_output_options options = {
.use_shadow = true,
.fb_size = {
@ -1057,8 +1057,7 @@ x11_output_enable(struct weston_output *base)
.fb_size.height = mode->height,
};
ret = gl_renderer->output_window_create(&output->base,
&options);
ret = renderer->gl->output_window_create(base, &options);
if (ret < 0)
goto err;
@ -1831,26 +1830,6 @@ x11_destroy(struct weston_backend *base)
free(backend);
}
static int
init_gl_renderer(struct x11_backend *b)
{
const struct gl_renderer_display_options options = {
.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),
};
gl_renderer = weston_load_module("gl-renderer.so",
"gl_renderer_interface",
LIBWESTON_MODULEDIR);
if (!gl_renderer)
return -1;
return gl_renderer->display_create(b->compositor, &options);
}
static const struct weston_windowed_output_api api = {
x11_output_set_size,
x11_head_create,
@ -1905,8 +1884,18 @@ x11_backend_create(struct weston_compositor *compositor,
goto err_xdisplay;
}
}
else if (init_gl_renderer(b) < 0) {
goto err_xdisplay;
else {
const struct gl_renderer_display_options options = {
.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),
};
if (weston_compositor_init_renderer(compositor,
WESTON_RENDERER_GL,
&options.base) < 0)
goto err_xdisplay;
}
weston_log("Using %s renderer\n",
(config->renderer == WESTON_RENDERER_PIXMAN) ? "pixman" : "gl");

View File

@ -80,6 +80,7 @@
#include "libweston-internal.h"
#include "color.h"
#include "output-capture.h"
#include "renderer-gl/gl-renderer.h"
#include "weston-log-internal.h"
@ -8743,6 +8744,39 @@ weston_compositor_load_backend(struct weston_compositor *compositor,
return 0;
}
WL_EXPORT int
weston_compositor_init_renderer(struct weston_compositor *compositor,
enum weston_renderer_type renderer_type,
const struct weston_renderer_options *options)
{
const struct gl_renderer_interface *gl_renderer;
const struct gl_renderer_display_options *gl_options;
int ret;
switch (renderer_type) {
case WESTON_RENDERER_GL:
gl_renderer = weston_load_module("gl-renderer.so",
"gl_renderer_interface",
LIBWESTON_MODULEDIR);
if (!gl_renderer)
return -1;
gl_options = container_of(options,
struct gl_renderer_display_options,
base);
ret = gl_renderer->display_create(compositor, gl_options);
if (ret < 0)
return ret;
compositor->renderer->gl = gl_renderer;
break;
default:
ret = -1;
}
return ret;
}
/** weston_compositor_load_xwayland
* \ingroup compositor
*/

View File

@ -34,9 +34,10 @@
void
weston_gl_borders_update(struct weston_gl_borders *borders,
struct frame *frame,
struct weston_output *output,
struct gl_renderer_interface *glri)
struct weston_output *output)
{
const struct gl_renderer_interface *glri =
output->compositor->renderer->gl;
int32_t ix, iy, iwidth, iheight, fwidth, fheight;
fwidth = frame_width(frame);
@ -86,9 +87,11 @@ weston_gl_borders_update(struct weston_gl_borders *borders,
void
weston_gl_borders_fini(struct weston_gl_borders *borders,
struct weston_output *output,
struct gl_renderer_interface *glri)
struct weston_output *output)
{
const struct gl_renderer_interface *glri =
output->compositor->renderer->gl;
for (unsigned i = 0; i < ARRAY_LENGTH(borders->tile); i++) {
glri->output_set_border(output, i, 0, 0, 0, NULL);
cairo_surface_destroy(borders->tile[i]);

View File

@ -35,10 +35,8 @@ struct weston_gl_borders {
void
weston_gl_borders_update(struct weston_gl_borders *borders,
struct frame *frame,
struct weston_output *output,
struct gl_renderer_interface *glri);
struct weston_output *output);
void
weston_gl_borders_fini(struct weston_gl_borders *borders,
struct weston_output *output,
struct gl_renderer_interface *glri);
struct weston_output *output);

View File

@ -46,6 +46,9 @@
/* compositor <-> renderer interface */
struct weston_renderer_options {
};
struct weston_renderer {
int (*read_pixels)(struct weston_output *output,
const struct pixel_format_info *format, void *pixels,
@ -84,6 +87,7 @@ struct weston_renderer {
struct weston_buffer *buffer);
enum weston_renderer_type type;
const struct gl_renderer_interface *gl;
};
void
@ -161,6 +165,11 @@ weston_compositor_read_presentation_clock(
struct weston_compositor *compositor,
struct timespec *ts);
int
weston_compositor_init_renderer(struct weston_compositor *compositor,
enum weston_renderer_type renderer_type,
const struct weston_renderer_options *options);
int
weston_compositor_run_axis_binding(struct weston_compositor *compositor,
struct weston_pointer *pointer,

View File

@ -66,6 +66,7 @@ enum gl_renderer_border_side {
* \see struct gl_renderer_interface
*/
struct gl_renderer_display_options {
struct weston_renderer_options base;
/** The EGL platform identifier */
EGLenum egl_platform;
/** The native display corresponding to the given EGL platform */