diff --git a/libweston/backend-drm/drm-gbm.c b/libweston/backend-drm/drm-gbm.c index d1781cb6..a46d59a1 100644 --- a/libweston/backend-drm/drm-gbm.c +++ b/libweston/backend-drm/drm-gbm.c @@ -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); diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h index 7d1d4985..5461eafc 100644 --- a/libweston/backend-drm/drm-internal.h +++ b/libweston/backend-drm/drm-internal.h @@ -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); diff --git a/libweston/backend-drm/drm-virtual.c b/libweston/backend-drm/drm-virtual.c index 42d5dfc3..94b7e401 100644 --- a/libweston/backend-drm/drm-virtual.c +++ b/libweston/backend-drm/drm-virtual.c @@ -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 diff --git a/libweston/backend-headless/headless.c b/libweston/backend-headless/headless.c index 44112721..8b9f7c14 100644 --- a/libweston/backend-headless/headless.c +++ b/libweston/backend-headless/headless.c @@ -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"); diff --git a/libweston/backend-wayland/wayland.c b/libweston/backend-wayland/wayland.c index 85e2726d..486dd5ad 100644 --- a/libweston/backend-wayland/wayland.c +++ b/libweston/backend-wayland/wayland.c @@ -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"); diff --git a/libweston/backend-x11/x11.c b/libweston/backend-x11/x11.c index 600e80ed..6ff08e5d 100644 --- a/libweston/backend-x11/x11.c +++ b/libweston/backend-x11/x11.c @@ -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"); diff --git a/libweston/compositor.c b/libweston/compositor.c index d239c290..7f7cb9b9 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -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 */ diff --git a/libweston/gl-borders.c b/libweston/gl-borders.c index 56d3812f..edf9df44 100644 --- a/libweston/gl-borders.c +++ b/libweston/gl-borders.c @@ -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]); diff --git a/libweston/gl-borders.h b/libweston/gl-borders.h index 6b36bebf..fd2dff3e 100644 --- a/libweston/gl-borders.h +++ b/libweston/gl-borders.h @@ -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); diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index ed933242..aed36dca 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -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, diff --git a/libweston/renderer-gl/gl-renderer.h b/libweston/renderer-gl/gl-renderer.h index 6605f174..638bd4ca 100644 --- a/libweston/renderer-gl/gl-renderer.h +++ b/libweston/renderer-gl/gl-renderer.h @@ -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 */