Support direct scanout with src crop and dst boxes

Enable scene-tree direct scanout of a single buffer with various options
for scaling and source crop. This is intended to support direct scanout
for fullscreen video with/without scaling, letterboxing/pillarboxing
(e.g. 4:3 content on a 16:9 display), and source crop (e.g. when
1920x1088 planes are used for 1920x1080 video).

This works by explicitly specifying the source crop and destination box
for the primary buffer in the output state.  DRM atomic and libliftoff
backends will turn this into a crop and scale of the plane (assuming the
hardware supports that).  For the Wayland/X11/DRM-legacy backends I just
reject this so scanout will be disabled.

The previous behaviour is preserved if buffer_src_box and buffer_dst_box
are unset: the buffer is displayed at native size at the top-left of the
output with no crop.

The change to `struct wlr_output_state` makes this a binary breaking
change (but this works transparently for scene-tree compositors like
labwc after a recompile).
This commit is contained in:
David Turner 2024-10-17 14:24:05 +01:00
parent 47fb00f66d
commit c87ab6465d
10 changed files with 230 additions and 59 deletions

View file

@ -26,4 +26,9 @@ void output_defer_present(struct wlr_output *output, struct wlr_output_event_pre
bool output_prepare_commit(struct wlr_output *output, const struct wlr_output_state *state);
void output_apply_commit(struct wlr_output *output, const struct wlr_output_state *state);
void output_state_get_buffer_src_box(const struct wlr_output_state *state,
struct wlr_fbox *out);
void output_state_get_buffer_dst_box(const struct wlr_output_state *state,
struct wlr_box *out);
#endif

View file

@ -17,6 +17,7 @@
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_buffer.h>
#include <wlr/util/addon.h>
#include <wlr/util/box.h>
enum wlr_output_mode_aspect_ratio {
WLR_OUTPUT_MODE_ASPECT_RATIO_NONE,
@ -94,6 +95,14 @@ struct wlr_output_state {
enum wl_output_subpixel subpixel;
struct wlr_buffer *buffer;
// Source crop for the buffer. If all zeros then no crop is applied.
// Double-buffered by WLR_OUTPUT_STATE_BUFFER along with `buffer`.
struct wlr_fbox buffer_src_box;
// Destination rect to scale the buffer to (after source crop). If width
// and height are zero then the buffer is displayed at native size.
// Double-buffered by WLR_OUTPUT_STATE_BUFFER along with `buffer`.
struct wlr_box buffer_dst_box;
/* Request a tearing page-flip. When enabled, this may cause the output to
* display a part of the previous buffer and a part of the current buffer at
* the same time. The backend may reject the commit if a tearing page-flip