aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2023-04-20 10:39:46 +0200
committerSimon Ser <contact@emersion.fr>2023-04-20 10:39:46 +0200
commit44069dfd5e9e3efa150ce468f48c64916f2de0ae (patch)
tree03261acc761e48a341cbb93988ef0f238f6581be
parentd79582434685827275d79dca05f61efed5e3d6e7 (diff)
output-layer: add cropping support
Add a src_box state field. Use the SRC_* KMS props in the DRM backend, reject the layers in the Wayland backend (for now, we can support it later via viewporter).
-rw-r--r--backend/drm/libliftoff.c16
-rw-r--r--backend/wayland/output.c7
-rw-r--r--include/wlr/types/wlr_output_layer.h3
-rw-r--r--types/output/output.c1
4 files changed, 23 insertions, 4 deletions
diff --git a/backend/drm/libliftoff.c b/backend/drm/libliftoff.c
index cd62dccb..550d4533 100644
--- a/backend/drm/libliftoff.c
+++ b/backend/drm/libliftoff.c
@@ -201,10 +201,18 @@ static bool set_layer_props(struct wlr_drm_backend *drm,
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);
- uint64_t src_w = to_fp16(width);
- uint64_t src_h = to_fp16(height);
+ struct wlr_fbox src_box = state->src_box;
+ if (wlr_fbox_empty(&src_box)) {
+ src_box = (struct wlr_fbox){
+ .width = width,
+ .height = height,
+ };
+ }
+
+ uint64_t src_x = to_fp16(src_box.x);
+ uint64_t src_y = to_fp16(src_box.y);
+ uint64_t src_w = to_fp16(src_box.width);
+ uint64_t src_h = to_fp16(src_box.height);
return
liftoff_layer_set_property(layer->liftoff, "zpos", zpos) == 0 &&
diff --git a/backend/wayland/output.c b/backend/wayland/output.c
index 5d736a20..f4892c9f 100644
--- a/backend/wayland/output.c
+++ b/backend/wayland/output.c
@@ -294,6 +294,13 @@ static bool output_test(struct wlr_output *wlr_output,
height != layer_state->dst_box.height) {
supported = false;
}
+ if (!wlr_fbox_empty(&layer_state->src_box)) {
+ supported = supported &&
+ layer_state->src_box.x == 0 &&
+ layer_state->src_box.y == 0 &&
+ layer_state->src_box.width == width &&
+ layer_state->src_box.height == height;
+ }
supported = supported &&
test_buffer(output->backend, layer_state->buffer);
}
diff --git a/include/wlr/types/wlr_output_layer.h b/include/wlr/types/wlr_output_layer.h
index 8bcd5a27..4e28d559 100644
--- a/include/wlr/types/wlr_output_layer.h
+++ b/include/wlr/types/wlr_output_layer.h
@@ -52,6 +52,7 @@ struct wlr_output_layer {
// private state
+ struct wlr_fbox src_box;
struct wlr_box dst_box;
};
@@ -63,6 +64,8 @@ struct wlr_output_layer_state {
// Buffer to display, or NULL to disable the layer
struct wlr_buffer *buffer;
+ // Source box, leave empty to use the whole buffer
+ struct wlr_fbox src_box;
// Destination box in output-buffer-local coordinates
struct wlr_box dst_box;
diff --git a/types/output/output.c b/types/output/output.c
index 674e6d8c..b958b3c3 100644
--- a/types/output/output.c
+++ b/types/output/output.c
@@ -832,6 +832,7 @@ bool wlr_output_commit_state(struct wlr_output *output,
wl_list_insert(output->layers.prev, &layer->link);
// Commit layer state
+ layer->src_box = layer_state->src_box;
layer->dst_box = layer_state->dst_box;
}
}