From de6dfd292a1c55f8e275d301607eadc228aecb90 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Mon, 18 Nov 2024 14:18:22 +0200 Subject: compositor: Add support for loading PipeWire backend Bug-AGL: SPEC-5289 Signed-off-by: Marius Vlad Change-Id: I4a19aa6d242154db398578e2bdff452f713d7116 --- meson.build | 7 ++++ src/compositor.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/meson.build b/meson.build index b17afa4..5cb16d6 100644 --- a/meson.build +++ b/meson.build @@ -169,16 +169,19 @@ if libweston_dep.found() dir_path_x11_backend = join_paths(prefix_path, 'include', libweston_version, 'libweston', 'backend-x11.h') dir_path_wayland_backend = join_paths(prefix_path, 'include', libweston_version, 'libweston', 'backend-wayland.h') dir_path_rdp_backend = join_paths(prefix_path, 'include', libweston_version, 'libweston', 'backend-rdp.h') + dir_path_pipewire_backend = join_paths(prefix_path, 'include', libweston_version, 'libweston', 'backend-pipewire.h') else dir_path_x11_backend = join_paths(libweston_version, 'libweston', 'backend-x11.h') dir_path_wayland_backend = join_paths(libweston_version, 'libweston', 'backend-wayland.h') dir_path_rdp_backend = join_paths(libweston_version, 'libweston', 'backend-rdp.h') + dir_path_pipewire_backend = join_paths(libweston_version, 'libweston', 'backend-pipewire.h') endif else message('Building with cross environment') dir_path_x11_backend = join_paths(libweston_version, 'libweston', 'backend-x11.h') dir_path_wayland_backend = join_paths(libweston_version, 'libweston', 'backend-wayland.h') dir_path_rdp_backend = join_paths(libweston_version, 'libweston', 'backend-rdp.h') + dir_path_pipewire_backend = join_paths(libweston_version, 'libweston', 'backend-pipewire.h') endif # do the test @@ -196,6 +199,10 @@ if libweston_dep.found() config_h.set('HAVE_BACKEND_RDP', 1) message('Building with RDP backend') endif + if cc.has_header(dir_path_pipewire_backend) + config_h.set('HAVE_BACKEND_PIPEWIRE', 1) + message('Building with PipeWire backend') + endif endif if dep_libsystemd.found() diff --git a/src/compositor.c b/src/compositor.c index df6419c..2568246 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -39,6 +39,9 @@ #include #include +#ifdef HAVE_BACKEND_PIPEWIRE +#include +#endif #ifdef HAVE_BACKEND_X11 #include #endif @@ -127,6 +130,7 @@ struct { } backend_name_map[] = { { "drm", "drm-backend.so", WESTON_BACKEND_DRM }, { "rdp", "rdp-backend.so", WESTON_BACKEND_RDP }, + { "pipewire", "pipewire-backend.so", WESTON_BACKEND_PIPEWIRE }, { "wayland", "wayland-backend.so", WESTON_BACKEND_WAYLAND }, { "x11", "x11-backend.so", WESTON_BACKEND_X11 }, }; @@ -1314,6 +1318,119 @@ load_rdp_backend(struct ivi_compositor *ivi, int *argc, char **argv, } #endif +#ifdef HAVE_BACKEND_PIPEWIRE +static void +pipewire_backend_config_init(struct weston_pipewire_backend_config *config) +{ + config->base.struct_version = WESTON_PIPEWIRE_BACKEND_CONFIG_VERSION; + config->base.struct_size = sizeof(struct weston_pipewire_backend_config); +} + +static int +pipewire_backend_output_configure(struct weston_output *output) +{ + int width = 640; + int height = 480; + struct ivi_compositor *ivi = to_ivi_compositor(output->compositor); + struct ivi_output_config *parsed_options = ivi->parsed_options; + + const struct weston_pipewire_output_api *api = + weston_pipewire_output_get_api(output->compositor); + struct weston_config_section *section; + char *gbm_format = NULL; + uint32_t transform = WL_OUTPUT_TRANSFORM_NORMAL; + int scale = 1; + + assert(parsed_options); + + if (!api) { + weston_log("Cannot use weston_pipewire_output_api.\n"); + return -1; + } + + section = weston_config_get_section(ivi->config, + "output", "name", output->name); + + weston_config_section_get_int(section, "width", &width, width); + weston_config_section_get_int(section, "height", &height, height); + + if (parsed_options->width) + width = parsed_options->width; + + if (parsed_options->height) + height = parsed_options->height; + + weston_config_section_get_string(section, "gbm-format", &gbm_format, NULL); + + weston_output_set_scale(output, scale); + weston_output_set_transform(output, transform); + + api->set_gbm_format(output, gbm_format); + free(gbm_format); + + if (api->output_set_size(output, width, height) < 0) { + weston_log("Cannot configure output \"%s\" using weston_pipewire_output_api.\n", + output->name); + return -1; + } + weston_log("pipewire_backend_output_configure.. Done\n"); + + return 0; +} + + +static int +load_pipewire_backend(struct ivi_compositor *ivi, int *argc, char **argv, + enum weston_renderer_type renderer) +{ + struct weston_pipewire_backend_config config = {}; + struct weston_config_section *section; + struct ivi_output_config *parsed_options = + ivi_init_parsed_options(ivi->compositor); + + if (!parsed_options) + return -1; + + pipewire_backend_config_init(&config); + + const struct weston_option pipewire_options[] = { + { WESTON_OPTION_INTEGER, "width", 0, &parsed_options->width }, + { WESTON_OPTION_INTEGER, "height", 0, &parsed_options->height }, + }; + + parse_options(pipewire_options, ARRAY_LENGTH(pipewire_options), argc, argv); + + config.renderer = renderer; + + section = weston_config_get_section(ivi->config, "core", NULL, NULL); + weston_config_section_get_string(section, "gbm-format", + &config.gbm_format, NULL); + + section = weston_config_get_section(ivi->config, "pipewire", NULL, NULL); + weston_config_section_get_int(section, "num-outputs", + &config.num_outputs, 1); + + ivi->simple_output_configure = pipewire_backend_output_configure; + ivi->heads_changed.notify = simple_heads_changed; + weston_compositor_add_heads_changed_listener(ivi->compositor, + &ivi->heads_changed); + + if (!weston_compositor_load_backend(ivi->compositor, + WESTON_BACKEND_PIPEWIRE, &config.base)) { + weston_log("Failed to create PipeWire backend\n"); + return -1; + } + + return 0; +} +#else +static int +load_pipewire_backend(struct ivi_compositor *ivi, int *argc, char **argv, + enum weston_renderer_type renderer) +{ + return -1; +} +#endif static int load_backend(struct ivi_compositor *ivi, int *argc, char **argv, @@ -1337,6 +1454,8 @@ load_backend(struct ivi_compositor *ivi, int *argc, char **argv, return load_drm_backend(ivi, argc, argv, renderer); case WESTON_BACKEND_RDP: return load_rdp_backend(ivi, argc, argv, renderer); + case WESTON_BACKEND_PIPEWIRE: + return load_pipewire_backend(ivi, argc, argv, renderer); case WESTON_BACKEND_WAYLAND: return load_wayland_backend(ivi, argc, argv, renderer); case WESTON_BACKEND_X11: -- cgit