From 892c90e2ef25609b11934fb6489e0f3ce25497e1 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 20 Feb 2023 12:28:01 +0100 Subject: [PATCH] Use wlr_output_swapchain References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3984 --- include/sway/output.h | 3 ++- sway/desktop/output.c | 52 ++++++++++++++++++++++++++++++++++++++++--- sway/desktop/render.c | 30 ++----------------------- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index 28be6a1e9..98b3cc855 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -28,6 +28,7 @@ struct sway_output { struct timespec last_frame; struct wlr_damage_ring damage_ring; + struct wlr_output_swapchain *swapchain; int lx, ly; // layout coords int width, height; // transformed buffer size @@ -112,7 +113,7 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output); struct sway_workspace *output_get_active_workspace(struct sway_output *output); -void output_render(struct sway_output *output, struct timespec *when, +void output_render(struct sway_output *output, struct wlr_buffer *buffer, pixman_region32_t *damage); void output_surface_for_each_surface(struct sway_output *output, diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 141edb491..08a5e1404 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -517,6 +518,26 @@ static bool scan_out_fullscreen_view(struct sway_output *output, return wlr_output_commit(wlr_output); } +static void get_frame_damage(struct sway_output *output, + pixman_region32_t *frame_damage) { + struct wlr_output *wlr_output = output->wlr_output; + + int width, height; + wlr_output_transformed_resolution(wlr_output, &width, &height); + + pixman_region32_init(frame_damage); + + enum wl_output_transform transform = + wlr_output_transform_invert(wlr_output->transform); + wlr_region_transform(frame_damage, &output->damage_ring.current, + transform, width, height); + + if (debug.damage != DAMAGE_DEFAULT) { + pixman_region32_union_rect(frame_damage, frame_damage, + 0, 0, wlr_output->width, wlr_output->height); + } +} + static int output_repaint_timer_handler(void *data) { struct sway_output *output = data; if (output->wlr_output == NULL) { @@ -558,7 +579,10 @@ static int output_repaint_timer_handler(void *data) { } int buffer_age; - if (!wlr_output_attach_render(output->wlr_output, &buffer_age)) { + struct wlr_output_state state = {0}; + struct wlr_buffer *buffer = wlr_output_swapchain_acquire(output->swapchain, + &state, &buffer_age); + if (buffer == NULL) { return 0; } @@ -568,17 +592,37 @@ static int output_repaint_timer_handler(void *data) { if (!output->wlr_output->needs_frame && !pixman_region32_not_empty(&output->damage_ring.current)) { pixman_region32_fini(&damage); - wlr_output_rollback(output->wlr_output); + wlr_buffer_unlock(buffer); return 0; } struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - output_render(output, &now, &damage); + output_render(output, buffer, &damage); pixman_region32_fini(&damage); + struct wlr_output *wlr_output = output->wlr_output; + + wlr_output_attach_buffer(wlr_output, buffer); + wlr_buffer_unlock(buffer); + + int width, height; + wlr_output_transformed_resolution(wlr_output, &width, &height); + + pixman_region32_t frame_damage; + get_frame_damage(output, &frame_damage); + wlr_output_set_damage(wlr_output, &frame_damage); + pixman_region32_fini(&frame_damage); + + if (!wlr_output_commit(wlr_output)) { + return 0; + } + + wlr_damage_ring_rotate(&output->damage_ring); + output->last_frame = now; + return 0; } @@ -814,6 +858,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&output->needs_frame.link); wl_list_remove(&output->request_state.link); + // output->swapchain destroys itself with the wlr_output wlr_damage_ring_finish(&output->damage_ring); output->wlr_output->data = NULL; @@ -953,6 +998,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { return; } output->server = server; + output->swapchain = wlr_output_swapchain_create(wlr_output); wlr_damage_ring_init(&output->damage_ring); wl_signal_add(&wlr_output->events.destroy, &output->destroy); diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 2b7214c35..68c812e87 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -1029,7 +1029,7 @@ static void render_seatops(struct sway_output *output, } } -void output_render(struct sway_output *output, struct timespec *when, +void output_render(struct sway_output *output, struct wlr_buffer *buffer, pixman_region32_t *damage) { struct wlr_output *wlr_output = output->wlr_output; struct wlr_renderer *renderer = output->server->renderer; @@ -1044,7 +1044,7 @@ void output_render(struct sway_output *output, struct timespec *when, fullscreen_con = workspace->current.fullscreen; } - if (!wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height)) { + if (!wlr_renderer_begin_with_buffer(renderer, buffer)) { return; } @@ -1184,30 +1184,4 @@ renderer_end: wlr_renderer_scissor(renderer, NULL); wlr_output_render_software_cursors(wlr_output, damage); wlr_renderer_end(renderer); - - int width, height; - wlr_output_transformed_resolution(wlr_output, &width, &height); - - pixman_region32_t frame_damage; - pixman_region32_init(&frame_damage); - - enum wl_output_transform transform = - wlr_output_transform_invert(wlr_output->transform); - wlr_region_transform(&frame_damage, &output->damage_ring.current, - transform, width, height); - - if (debug.damage != DAMAGE_DEFAULT) { - pixman_region32_union_rect(&frame_damage, &frame_damage, - 0, 0, wlr_output->width, wlr_output->height); - } - - wlr_output_set_damage(wlr_output, &frame_damage); - pixman_region32_fini(&frame_damage); - - if (!wlr_output_commit(wlr_output)) { - return; - } - - wlr_damage_ring_rotate(&output->damage_ring); - output->last_frame = *when; }