output-layer: add support for scaling buffers

This allows callers to set a destination size different from the
buffer size to scale them.

The DRM backend supports this. The Wayland backend doesn't yet
(we'd need to wire up viewporter).
This commit is contained in:
Simon Ser 2023-04-04 19:38:48 +02:00
parent 89dcecba39
commit 835208db98
5 changed files with 27 additions and 16 deletions

View File

@ -196,10 +196,10 @@ static bool set_layer_props(struct wlr_drm_backend *drm,
return false;
}
uint64_t crtc_x = (uint64_t)state->x;
uint64_t crtc_y = (uint64_t)state->y;
uint64_t crtc_w = (uint64_t)width;
uint64_t crtc_h = (uint64_t)height;
uint64_t crtc_x = (uint64_t)state->dst_box.x;
uint64_t crtc_y = (uint64_t)state->dst_box.y;
uint64_t crtc_w = (uint64_t)state->dst_box.width;
uint64_t crtc_h = (uint64_t)state->dst_box.height;
uint64_t src_x = to_fp16(0);
uint64_t src_y = to_fp16(0);

View File

@ -283,9 +283,15 @@ static bool output_test(struct wlr_output *wlr_output,
for (ssize_t i = state->layers_len - 1; i >= 0; i--) {
struct wlr_output_layer_state *layer_state = &state->layers[i];
if (layer_state->buffer != NULL) {
if (layer_state->x < 0 || layer_state->y < 0 ||
layer_state->x + layer_state->buffer->width > wlr_output->width ||
layer_state->y + layer_state->buffer->height > wlr_output->height) {
int x = layer_state->dst_box.x;
int y = layer_state->dst_box.y;
int width = layer_state->dst_box.width;
int height = layer_state->dst_box.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) {
supported = false;
}
supported = supported &&
@ -376,8 +382,9 @@ static void output_layer_unmap(struct wlr_wl_output_layer *layer) {
static bool output_layer_commit(struct wlr_wl_output *output,
struct wlr_wl_output_layer *layer,
const struct wlr_output_layer_state *state) {
if (state->layer->x != state->x || state->layer->y != state->y) {
wl_subsurface_set_position(layer->subsurface, state->x, state->y);
if (state->layer->dst_box.x != state->dst_box.x ||
state->layer->dst_box.y != state->dst_box.y) {
wl_subsurface_set_position(layer->subsurface, state->dst_box.x, state->dst_box.y);
}
if (state->buffer == NULL) {

View File

@ -74,8 +74,12 @@ static void output_handle_frame(struct wl_listener *listener, void *data) {
*layer_state = (struct wlr_output_layer_state){
.layer = output_surface->layer,
.buffer = output_surface->buffer,
.x = output_surface->x,
.y = output_surface->y,
.dst_box = {
.x = output_surface->x,
.y = output_surface->y,
.width = output_surface->wlr_surface->current.width,
.height = output_surface->wlr_surface->current.height,
},
};
}

View File

@ -11,6 +11,7 @@
#include <wlr/render/drm_format_set.h>
#include <wlr/types/wlr_output.h>
#include <wlr/util/box.h>
#include <wlr/util/addon.h>
/**
@ -51,7 +52,7 @@ struct wlr_output_layer {
// private state
int x, y;
struct wlr_box dst_box;
};
/**
@ -62,8 +63,8 @@ struct wlr_output_layer_state {
// Buffer to display, or NULL to disable the layer
struct wlr_buffer *buffer;
// Position in output-buffer-local coordinates
int x, y;
// Destination box in output-buffer-local coordinates
struct wlr_box dst_box;
// Populated by the backend after wlr_output_test() and wlr_output_commit(),
// indicates whether the backend has acknowledged and will take care of

View File

@ -851,8 +851,7 @@ bool wlr_output_commit_state(struct wlr_output *output,
wl_list_insert(output->layers.prev, &layer->link);
// Commit layer state
layer->x = layer_state->x;
layer->y = layer_state->y;
layer->dst_box = layer_state->dst_box;
}
}