scene: filter frame_done primary output in surface handler

This lets the surface handler decide which output to send frame
callbacks from. The output_sample event already works this way.

Introduce wlr_scene_surface_send_frame_done() as a replacement for
wlr_scene_buffer_send_frame_done() when a compositor doesn't have
an output at hand.
This commit is contained in:
Simon Ser 2025-06-05 12:11:01 +02:00 committed by Kenny Levinsen
parent 8713ac72fb
commit 51d051497d
3 changed files with 32 additions and 10 deletions

View file

@ -76,9 +76,19 @@ static void handle_scene_buffer_frame_done(
struct wl_listener *listener, void *data) {
struct wlr_scene_surface *surface =
wl_container_of(listener, surface, frame_done);
struct timespec *now = data;
struct wlr_scene_frame_done_event *event = data;
if (surface->buffer->primary_output != event->output) {
return;
}
wlr_surface_send_frame_done(surface->surface, now);
wlr_surface_send_frame_done(surface->surface, &event->when);
}
void wlr_scene_surface_send_frame_done(struct wlr_scene_surface *scene_surface,
const struct timespec *when) {
if (!pixman_region32_empty(&scene_surface->buffer->node.visible)) {
wlr_surface_send_frame_done(scene_surface->surface, when);
}
}
static void scene_surface_handle_surface_destroy(

View file

@ -1072,9 +1072,9 @@ void wlr_scene_buffer_set_transform(struct wlr_scene_buffer *scene_buffer,
}
void wlr_scene_buffer_send_frame_done(struct wlr_scene_buffer *scene_buffer,
struct timespec *now) {
struct wlr_scene_frame_done_event *event) {
if (!pixman_region32_empty(&scene_buffer->node.visible)) {
wl_signal_emit_mutable(&scene_buffer->events.frame_done, now);
wl_signal_emit_mutable(&scene_buffer->events.frame_done, event);
}
}
@ -2376,10 +2376,11 @@ static void scene_node_send_frame_done(struct wlr_scene_node *node,
if (node->type == WLR_SCENE_NODE_BUFFER) {
struct wlr_scene_buffer *scene_buffer =
wlr_scene_buffer_from_node(node);
if (scene_buffer->primary_output == scene_output) {
wlr_scene_buffer_send_frame_done(scene_buffer, now);
}
struct wlr_scene_frame_done_event event = {
.output = scene_output,
.when = *now,
};
wlr_scene_buffer_send_frame_done(scene_buffer, &event);
} else if (node->type == WLR_SCENE_NODE_TREE) {
struct wlr_scene_tree *scene_tree = wlr_scene_tree_from_node(node);
struct wlr_scene_node *child;