diff options
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r-- | sway/desktop/output.c | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 0f715c19..6498198b 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -23,6 +23,7 @@ #include "sway/layers.h" #include "sway/output.h" #include "sway/server.h" +#include "sway/surface.h" #include "sway/tree/arrange.h" #include "sway/tree/container.h" #include "sway/tree/root.h" @@ -80,6 +81,7 @@ struct surface_iterator_data { void *user_data; struct sway_output *output; + struct sway_view *view; double ox, oy; int width, height; float rotation; @@ -134,7 +136,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface, return; } - data->user_iterator(data->output, surface, &box, data->rotation, + data->user_iterator(data->output, data->view, surface, &box, data->rotation, data->user_data); } @@ -145,6 +147,7 @@ void output_surface_for_each_surface(struct sway_output *output, .user_iterator = iterator, .user_data = user_data, .output = output, + .view = NULL, .ox = ox, .oy = oy, .width = surface->current.width, @@ -163,6 +166,7 @@ void output_view_for_each_surface(struct sway_output *output, .user_iterator = iterator, .user_data = user_data, .output = output, + .view = view, .ox = view->container->surface_x - output->lx - view->geometry.x, .oy = view->container->surface_y - output->ly @@ -182,6 +186,7 @@ void output_view_for_each_popup(struct sway_output *output, .user_iterator = iterator, .user_data = user_data, .output = output, + .view = view, .ox = view->container->surface_x - output->lx - view->geometry.x, .oy = view->container->surface_y - output->ly @@ -224,6 +229,7 @@ void output_layer_for_each_surface(struct sway_output *output, .user_iterator = iterator, .user_data = user_data, .output = output, + .view = NULL, .ox = popup_sx, .oy = popup_sy, .width = surface->current.width, @@ -291,6 +297,7 @@ static void output_for_each_surface(struct sway_output *output, .user_iterator = iterator, .user_data = user_data, .output = output, + .view = NULL, }; struct sway_workspace *workspace = output_get_active_workspace(output); @@ -401,18 +408,37 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output) { return false; } -static void send_frame_done_iterator(struct sway_output *output, +struct send_frame_done_data { + struct timespec when; + int msec_until_refresh; +}; + +static void send_frame_done_iterator(struct sway_output *output, struct sway_view *view, struct wlr_surface *surface, struct wlr_box *box, float rotation, - void *data) { - struct timespec *when = data; - wlr_surface_send_frame_done(surface, when); + void *user_data) { + int view_max_render_time = 0; + if (view != NULL) { + view_max_render_time = view->max_render_time; + } + + struct send_frame_done_data *data = user_data; + + int delay = data->msec_until_refresh - output->max_render_time + - view_max_render_time; + + if (output->max_render_time == 0 || view_max_render_time == 0 || delay < 1) { + wlr_surface_send_frame_done(surface, &data->when); + } else { + struct sway_surface *sway_surface = surface->data; + wl_event_source_timer_update(sway_surface->frame_done_timer, delay); + } } -static void send_frame_done(struct sway_output *output, struct timespec *when) { - output_for_each_surface(output, send_frame_done_iterator, when); +static void send_frame_done(struct sway_output *output, struct send_frame_done_data *data) { + output_for_each_surface(output, send_frame_done_iterator, data); } -static void count_surface_iterator(struct sway_output *output, +static void count_surface_iterator(struct sway_output *output, struct sway_view *view, struct wlr_surface *surface, struct wlr_box *_box, float rotation, void *data) { size_t *n = data; @@ -533,7 +559,7 @@ int output_repaint_timer_handler(void *data) { return 0; } -static void damage_handle_frame(struct wl_listener *listener, void *data) { +static void damage_handle_frame(struct wl_listener *listener, void *user_data) { struct sway_output *output = wl_container_of(listener, output, damage_frame); if (!output->enabled || !output->wlr_output->enabled) { @@ -592,9 +618,10 @@ static void damage_handle_frame(struct wl_listener *listener, void *data) { } // Send frame done to all visible surfaces - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - send_frame_done(output, &now); + struct send_frame_done_data data = {0}; + clock_gettime(CLOCK_MONOTONIC, &data.when); + data.msec_until_refresh = msec_until_refresh; + send_frame_done(output, &data); } void output_damage_whole(struct sway_output *output) { @@ -605,7 +632,7 @@ void output_damage_whole(struct sway_output *output) { } } -static void damage_surface_iterator(struct sway_output *output, +static void damage_surface_iterator(struct sway_output *output, struct sway_view *view, struct wlr_surface *surface, struct wlr_box *_box, float rotation, void *_data) { bool *data = _data; @@ -811,7 +838,7 @@ static void handle_scale(struct wl_listener *listener, void *data) { update_output_manager_config(output->server); } -static void send_presented_iterator(struct sway_output *output, +static void send_presented_iterator(struct sway_output *output, struct sway_view *view, struct wlr_surface *surface, struct wlr_box *box, float rotation, void *data) { struct wlr_presentation_event *event = data; |