mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-29 05:40:12 -04:00
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:
parent
8713ac72fb
commit
51d051497d
3 changed files with 32 additions and 10 deletions
|
|
@ -152,6 +152,11 @@ struct wlr_scene_output_sample_event {
|
|||
bool direct_scanout;
|
||||
};
|
||||
|
||||
struct wlr_scene_frame_done_event {
|
||||
struct wlr_scene_output *output;
|
||||
struct timespec when;
|
||||
};
|
||||
|
||||
/** A scene-graph node displaying a buffer */
|
||||
struct wlr_scene_buffer {
|
||||
struct wlr_scene_node node;
|
||||
|
|
@ -164,7 +169,7 @@ struct wlr_scene_buffer {
|
|||
struct wl_signal output_enter; // struct wlr_scene_output
|
||||
struct wl_signal output_leave; // struct wlr_scene_output
|
||||
struct wl_signal output_sample; // struct wlr_scene_output_sample_event
|
||||
struct wl_signal frame_done; // struct timespec
|
||||
struct wl_signal frame_done; // struct wlr_scene_frame_done_event
|
||||
} events;
|
||||
|
||||
// May be NULL
|
||||
|
|
@ -416,6 +421,12 @@ struct wlr_scene_rect *wlr_scene_rect_from_node(struct wlr_scene_node *node);
|
|||
struct wlr_scene_surface *wlr_scene_surface_try_from_buffer(
|
||||
struct wlr_scene_buffer *scene_buffer);
|
||||
|
||||
/**
|
||||
* Call wlr_surface_send_frame_done() if the surface is visible.
|
||||
*/
|
||||
void wlr_scene_surface_send_frame_done(struct wlr_scene_surface *scene_surface,
|
||||
const struct timespec *when);
|
||||
|
||||
/**
|
||||
* Add a node displaying a solid-colored rectangle to the scene-graph.
|
||||
*
|
||||
|
|
@ -531,7 +542,7 @@ void wlr_scene_buffer_set_filter_mode(struct wlr_scene_buffer *scene_buffer,
|
|||
* Calls the buffer's frame_done signal.
|
||||
*/
|
||||
void wlr_scene_buffer_send_frame_done(struct wlr_scene_buffer *scene_buffer,
|
||||
struct timespec *now);
|
||||
struct wlr_scene_frame_done_event *event);
|
||||
|
||||
/**
|
||||
* Add a viewport for the specified output to the scene-graph.
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue