From 4c5eadecce4fce6956c8e8f9fb5f2ae0e48a2e81 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 20 Apr 2023 10:31:22 +0200 Subject: [PATCH] backend/wayland: add scaling support for output layers Use the viewporter protocol to scale output layers. --- backend/wayland/backend.c | 7 +++++++ backend/wayland/meson.build | 1 + backend/wayland/output.c | 19 +++++++++++++++++-- include/backend/wayland.h | 2 ++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index b4bacf127..ba13aa304 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -29,6 +29,7 @@ #include "xdg-shell-client-protocol.h" #include "tablet-unstable-v2-client-protocol.h" #include "relative-pointer-unstable-v1-client-protocol.h" +#include "viewporter-client-protocol.h" struct wlr_wl_linux_dmabuf_feedback_v1 { struct wlr_wl_backend *backend; @@ -396,6 +397,9 @@ static void registry_global(void *data, struct wl_registry *registry, } else if (strcmp(iface, wl_subcompositor_interface.name) == 0) { wl->subcompositor = wl_registry_bind(registry, name, &wl_subcompositor_interface, 1); + } else if (strcmp(iface, wp_viewporter_interface.name) == 0) { + wl->viewporter = wl_registry_bind(registry, name, + &wp_viewporter_interface, 1); } } @@ -515,6 +519,9 @@ static void backend_destroy(struct wlr_backend *backend) { if (wl->subcompositor) { wl_subcompositor_destroy(wl->subcompositor); } + if (wl->viewporter) { + wp_viewporter_destroy(wl->viewporter); + } free(wl->drm_render_name); free(wl->activation_token); xdg_wm_base_destroy(wl->xdg_wm_base); diff --git a/backend/wayland/meson.build b/backend/wayland/meson.build index a8e310f3f..0fd528cf9 100644 --- a/backend/wayland/meson.build +++ b/backend/wayland/meson.build @@ -19,6 +19,7 @@ client_protos = [ 'presentation-time', 'relative-pointer-unstable-v1', 'tablet-unstable-v2', + 'viewporter', 'xdg-activation-v1', 'xdg-decoration-unstable-v1', 'xdg-shell', diff --git a/backend/wayland/output.c b/backend/wayland/output.c index f4892c9ff..986ee23da 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -22,6 +22,7 @@ #include "linux-dmabuf-unstable-v1-client-protocol.h" #include "presentation-time-client-protocol.h" +#include "viewporter-client-protocol.h" #include "xdg-activation-v1-client-protocol.h" #include "xdg-decoration-unstable-v1-client-protocol.h" #include "xdg-shell-client-protocol.h" @@ -287,11 +288,12 @@ static bool output_test(struct wlr_output *wlr_output, int y = layer_state->dst_box.y; int width = layer_state->dst_box.width; int height = layer_state->dst_box.height; + bool needs_viewport = width != layer_state->buffer->width || + height != layer_state->buffer->height; if (x < 0 || y < 0 || x + width > wlr_output->width || y + height > wlr_output->height || - width != layer_state->buffer->width || - height != layer_state->dst_box.height) { + (output->backend->viewporter == NULL && needs_viewport)) { supported = false; } if (!wlr_fbox_empty(&layer_state->src_box)) { @@ -315,6 +317,9 @@ static void output_layer_handle_addon_destroy(struct wlr_addon *addon) { struct wlr_wl_output_layer *layer = wl_container_of(addon, layer, addon); wlr_addon_finish(&layer->addon); + if (layer->viewport != NULL) { + wp_viewport_destroy(layer->viewport); + } wl_subsurface_destroy(layer->subsurface); wl_surface_destroy(layer->surface); free(layer); @@ -355,6 +360,10 @@ static struct wlr_wl_output_layer *get_or_create_output_layer( wl_surface_set_input_region(layer->surface, region); wl_region_destroy(region); + if (output->backend->viewporter != NULL) { + layer->viewport = wp_viewporter_get_viewport(output->backend->viewporter, layer->surface); + } + return layer; } @@ -405,6 +414,12 @@ static bool output_layer_commit(struct wlr_wl_output *output, return false; } + if (layer->viewport != NULL && + (state->layer->dst_box.width != state->dst_box.width || + state->layer->dst_box.height != state->dst_box.height)) { + wp_viewport_set_destination(layer->viewport, state->dst_box.width, state->dst_box.height); + } + wl_surface_attach(layer->surface, buffer->wl_buffer, 0, 0); wl_surface_damage_buffer(layer->surface, 0, 0, INT32_MAX, INT32_MAX); wl_surface_commit(layer->surface); diff --git a/include/backend/wayland.h b/include/backend/wayland.h index 13c652355..fd0564030 100644 --- a/include/backend/wayland.h +++ b/include/backend/wayland.h @@ -48,6 +48,7 @@ struct wlr_wl_backend { struct wl_drm *legacy_drm; struct xdg_activation_v1 *activation_v1; struct wl_subcompositor *subcompositor; + struct wp_viewporter *viewporter; char *drm_render_name; }; @@ -71,6 +72,7 @@ struct wlr_wl_output_layer { struct wl_surface *surface; struct wl_subsurface *subsurface; + struct wp_viewport *viewport; bool mapped; };