Merge branch 'commit_queue_v1' into 'master'

fifo-v1: new protocol implementation

See merge request wlroots/wlroots!4463
This commit is contained in:
Sergio Gómez 2026-01-24 22:57:19 +00:00
commit 85e803c73f
9 changed files with 559 additions and 4 deletions

View file

@ -5,6 +5,7 @@
#include <wlr/types/wlr_color_representation_v1.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_fifo_v1.h>
#include <wlr/types/wlr_fractional_scale_v1.h>
#include <wlr/types/wlr_linux_drm_syncobj_v1.h>
#include <wlr/types/wlr_output.h>
@ -99,6 +100,9 @@ static void handle_scene_buffer_outputs_update(
// If the surface is no longer visible on any output, keep the last sent
// preferred configuration to avoid unnecessary redraws
if (wl_list_empty(&surface->surface->current_outputs)) {
if (surface->fifo) {
wlr_fifo_v1_set_output(surface->fifo, NULL);
}
return;
}
@ -112,6 +116,9 @@ static void handle_scene_buffer_outputs_update(
wlr_color_manager_v1_set_surface_preferred_image_description(scene->color_manager_v1,
surface->surface, &img_desc);
}
if (surface->fifo) {
wlr_fifo_v1_set_output(surface->fifo, surface->buffer->primary_output->output);
}
}
static void handle_scene_buffer_output_enter(

View file

@ -8,6 +8,7 @@
#include <wlr/types/wlr_color_management_v1.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_damage_ring.h>
#include <wlr/types/wlr_fifo_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_linux_dmabuf_v1.h>
#include <wlr/types/wlr_presentation_time.h>
@ -1350,10 +1351,6 @@ bool wlr_scene_node_coords(struct wlr_scene_node *node,
static void scene_node_for_each_scene_buffer(struct wlr_scene_node *node,
int lx, int ly, wlr_scene_buffer_iterator_func_t user_iterator,
void *user_data) {
if (!node->enabled) {
return;
}
lx += node->x;
ly += node->y;
@ -1653,6 +1650,61 @@ void wlr_scene_set_color_manager_v1(struct wlr_scene *scene, struct wlr_color_ma
wl_signal_add(&manager->events.destroy, &scene->color_manager_v1_destroy);
}
static void scene_surface_handle_fifo_v1_destroy(struct wl_listener *listener,
void *data) {
struct wlr_scene_surface *surface =
wl_container_of(listener, surface, fifo_v1_destroy);
wl_list_remove(&surface->fifo_v1_destroy.link);
surface->fifo = NULL;
}
static void fifo_set_output(struct wlr_scene_buffer *scene_buffer, int x, int y, void *data) {
struct wlr_scene_surface *scene_surface =
wlr_scene_surface_try_from_buffer(scene_buffer);
if (!scene_surface) {
return;
}
struct wlr_fifo_v1 *fifo = data;
if (scene_surface->surface == fifo->surface) {
scene_surface->fifo = fifo;
scene_surface->fifo_v1_destroy.notify = scene_surface_handle_fifo_v1_destroy;
wl_signal_add(&fifo->events.destroy, &scene_surface->fifo_v1_destroy);
wlr_fifo_v1_set_output(fifo, scene_buffer->primary_output ?
scene_buffer->primary_output->output : NULL);
}
}
static void scene_handle_fifo_manager_v1_new_fifo(struct wl_listener *listener,
void *data) {
struct wlr_scene *scene =
wl_container_of(listener, scene, fifo_manager_v1_new_fifo);
struct wlr_fifo_manager_v1_new_fifo_event *event = data;
wlr_scene_node_for_each_buffer(&scene->tree.node, fifo_set_output, event->fifo);
}
static void scene_handle_fifo_manager_v1_destroy(struct wl_listener *listener,
void *data) {
struct wlr_scene *scene =
wl_container_of(listener, scene, fifo_manager_v1_destroy);
wl_list_remove(&scene->fifo_manager_v1_destroy.link);
wl_list_init(&scene->fifo_manager_v1_destroy.link);
wl_list_remove(&scene->fifo_manager_v1_new_fifo.link);
wl_list_init(&scene->fifo_manager_v1_new_fifo.link);
scene->fifo_manager_v1 = NULL;
}
void wlr_scene_set_fifo_manager_v1(struct wlr_scene *scene,
struct wlr_fifo_manager_v1 *fifo_manager) {
assert(scene->fifo_manager_v1 == NULL);
scene->fifo_manager_v1 = fifo_manager;
scene->fifo_manager_v1_new_fifo.notify = scene_handle_fifo_manager_v1_new_fifo;
wl_signal_add(&fifo_manager->events.new_fifo, &scene->fifo_manager_v1_new_fifo);
scene->fifo_manager_v1_destroy.notify = scene_handle_fifo_manager_v1_destroy;
wl_signal_add(&fifo_manager->events.destroy, &scene->fifo_manager_v1_destroy);
}
static void scene_output_handle_destroy(struct wlr_addon *addon) {
struct wlr_scene_output *scene_output =
wl_container_of(addon, scene_output, addon);