aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2023-04-20 10:31:22 +0200
committerAlexander Orzechowski <alex@ozal.ski>2023-06-05 18:29:55 +0000
commit4c5eadecce4fce6956c8e8f9fb5f2ae0e48a2e81 (patch)
tree0db6200c3f11f9dae22e77c0fa9e9e8141d9c51c
parent46a014bf478c612a415410ea02906f1b82d48ba8 (diff)
backend/wayland: add scaling support for output layers
Use the viewporter protocol to scale output layers.
-rw-r--r--backend/wayland/backend.c7
-rw-r--r--backend/wayland/meson.build1
-rw-r--r--backend/wayland/output.c19
-rw-r--r--include/backend/wayland.h2
4 files changed, 27 insertions, 2 deletions
diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c
index b4bacf12..ba13aa30 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 a8e310f3..0fd528cf 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 f4892c9f..986ee23d 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 13c65235..fd056403 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;
};