mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-04 04:06:09 -05:00
scene/surface: don't cache frame pacing output
Storing the frame pacing output in a per-scene and per-surface struct doesn't play well with multiple scenes. outputs_update is only triggered for outputs the scene knows about, but operates on all outputs the surface has entered regardless of the scene. Thus leaving an output on one scene will not refresh the frame pacing output on other scenes, and these other scenes will operate with a stale frame pacing output. The surface will not receive any more wl_surface.frame done events. This also avoids keeping a dangling pointer around when the frame pacing output is destroyed but the output isn't added in the scene. References: https://github.com/swaywm/sway/issues/8885
This commit is contained in:
parent
2699b68b34
commit
b094f8aeb3
2 changed files with 4 additions and 8 deletions
|
|
@ -126,10 +126,6 @@ struct wlr_scene_surface {
|
|||
struct {
|
||||
struct wlr_box clip;
|
||||
|
||||
// Output used for frame pacing (surface frame callbacks, presentation
|
||||
// time feedback, etc), may be NULL
|
||||
struct wlr_output *frame_pacing_output;
|
||||
|
||||
struct wlr_addon addon;
|
||||
|
||||
struct wl_listener outputs_update;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ static double get_surface_preferred_buffer_scale(struct wlr_surface *surface) {
|
|||
return scale;
|
||||
}
|
||||
|
||||
// Output used for frame pacing (surface frame callbacks, presentation
|
||||
// time feedback, etc), may be NULL
|
||||
static struct wlr_output *get_surface_frame_pacing_output(struct wlr_surface *surface) {
|
||||
struct wlr_output *frame_pacing_output = NULL;
|
||||
struct wlr_surface_output *surface_output;
|
||||
|
|
@ -94,8 +96,6 @@ static void handle_scene_buffer_outputs_update(
|
|||
wl_container_of(listener, surface, outputs_update);
|
||||
struct wlr_scene *scene = scene_node_get_root(&surface->buffer->node);
|
||||
|
||||
surface->frame_pacing_output = get_surface_frame_pacing_output(surface->surface);
|
||||
|
||||
// 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)) {
|
||||
|
|
@ -138,7 +138,7 @@ static void handle_scene_buffer_output_sample(
|
|||
wl_container_of(listener, surface, output_sample);
|
||||
const struct wlr_scene_output_sample_event *event = data;
|
||||
struct wlr_output *output = event->output->output;
|
||||
if (surface->frame_pacing_output != output) {
|
||||
if (get_surface_frame_pacing_output(surface->surface) != output) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ static void handle_scene_buffer_frame_done(
|
|||
struct wlr_scene_surface *surface =
|
||||
wl_container_of(listener, surface, frame_done);
|
||||
struct wlr_scene_frame_done_event *event = data;
|
||||
if (surface->frame_pacing_output != event->output->output) {
|
||||
if (get_surface_frame_pacing_output(surface->surface) != event->output->output) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue