diff --git a/include/wlr/types/wlr_linux_dmabuf_v1.h b/include/wlr/types/wlr_linux_dmabuf_v1.h index 6bb0712e..3f703705 100644 --- a/include/wlr/types/wlr_linux_dmabuf_v1.h +++ b/include/wlr/types/wlr_linux_dmabuf_v1.h @@ -116,6 +116,8 @@ struct wlr_linux_dmabuf_feedback_v1_init_options { struct wlr_renderer *main_renderer; // Output on which direct scan-out is possible on the primary plane, or NULL struct wlr_output *scanout_primary_output; + // Output layer feedback event, or NULL + const struct wlr_output_layer_feedback_event *output_layer_feedback_event; }; /** diff --git a/types/wlr_linux_dmabuf_v1.c b/types/wlr_linux_dmabuf_v1.c index 0e663665..09f1d356 100644 --- a/types/wlr_linux_dmabuf_v1.c +++ b/types/wlr_linux_dmabuf_v1.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include "linux-dmabuf-unstable-v1-protocol.h" @@ -1062,6 +1063,8 @@ static bool devid_from_fd(int fd, dev_t *devid) { bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feedback_v1 *feedback, const struct wlr_linux_dmabuf_feedback_v1_init_options *options) { assert(options->main_renderer != NULL); + assert(options->scanout_primary_output == NULL || + options->output_layer_feedback_event == NULL); memset(feedback, 0, sizeof(*feedback)); @@ -1084,7 +1087,22 @@ bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feed goto error; } - if (options->scanout_primary_output != NULL) { + if (options->output_layer_feedback_event != NULL) { + const struct wlr_output_layer_feedback_event *event = options->output_layer_feedback_event; + + struct wlr_linux_dmabuf_feedback_v1_tranche *tranche = + wlr_linux_dmabuf_feedback_add_tranche(feedback); + if (tranche == NULL) { + goto error; + } + + tranche->target_device = event->target_device; + tranche->flags = ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT; + if (!wlr_drm_format_set_intersect(&tranche->formats, event->formats, renderer_formats)) { + wlr_log(WLR_ERROR, "Failed to intersect renderer and scanout formats"); + goto error; + } + } else if (options->scanout_primary_output != NULL) { int backend_drm_fd = wlr_backend_get_drm_fd(options->scanout_primary_output->backend); if (backend_drm_fd < 0) { wlr_log(WLR_ERROR, "Failed to get backend DRM FD");