diff --git a/include/sway/output.h b/include/sway/output.h index cabb4b557..c718e3b5e 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -57,6 +57,8 @@ struct sway_output { uint32_t refresh_nsec; int max_render_time; // In milliseconds struct wl_event_source *repaint_timer; + + list_t *textured_buffers; }; struct sway_output *output_create(struct wlr_output *wlr_output); diff --git a/sway/desktop/render.c b/sway/desktop/render.c index d3d927c83..d3857c40e 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -140,12 +140,18 @@ static void render_surface_iterator(struct sway_output *output, struct sway_view struct wlr_output *wlr_output = output->wlr_output; pixman_region32_t *output_damage = data->damage; float alpha = data->alpha; + struct wlr_renderer *renderer = + wlr_backend_get_renderer(wlr_output->backend); struct wlr_texture *texture = wlr_surface_get_texture(surface); if (!texture) { return; } + if (surface->buffer->base.in_fence_fd >= 0) { + wlr_renderer_wait_in_fence(renderer, surface->buffer->base.in_fence_fd); + } + struct wlr_fbox src_box; wlr_surface_get_buffer_source_box(surface, &src_box); @@ -163,6 +169,8 @@ static void render_surface_iterator(struct sway_output *output, struct sway_view wlr_presentation_surface_sampled_on_output(server.presentation, surface, wlr_output); + + list_add(output->textured_buffers, &surface->buffer->base); } static void render_layer_toplevel(struct sway_output *output, @@ -1008,6 +1016,7 @@ void output_render(struct sway_output *output, struct timespec *when, } wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); + output->textured_buffers->length = 0; if (!pixman_region32_not_empty(damage)) { // Output isn't damaged but needs buffer swap @@ -1109,6 +1118,17 @@ renderer_end: wlr_output_render_software_cursors(wlr_output, damage); wlr_renderer_end(renderer); + // TODO: software cursors + int fence_fd = wlr_renderer_dup_out_fence(renderer); + if (fence_fd >= 0) { + for (int i = 0; i < output->textured_buffers->length; i++) { + struct wlr_buffer *buffer = output->textured_buffers->items[i]; + wlr_buffer_add_out_fence(buffer, fence_fd); + } + close(fence_fd); + } + output->textured_buffers->length = 0; + int width, height; wlr_output_transformed_resolution(wlr_output, &width, &height); diff --git a/sway/server.c b/sway/server.c index 724a0e25f..c55e8b650 100644 --- a/sway/server.c +++ b/sway/server.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -148,6 +149,7 @@ bool server_init(struct sway_server *server) { wlr_data_control_manager_v1_create(server->wl_display); wlr_primary_selection_v1_device_manager_create(server->wl_display); wlr_viewporter_create(server->wl_display); + wlr_linux_explicit_synchronization_v1_create(server->wl_display); server->socket = wl_display_add_socket_auto(server->wl_display); if (!server->socket) { diff --git a/sway/tree/output.c b/sway/tree/output.c index 9a10c6a89..2efc96f0b 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -107,6 +107,8 @@ struct sway_output *output_create(struct wlr_output *wlr_output) { wl_list_init(&output->layers[i]); } + output->textured_buffers = create_list(); + return output; } @@ -235,6 +237,7 @@ void output_destroy(struct sway_output *output) { } list_free(output->workspaces); list_free(output->current.workspaces); + list_free(output->textured_buffers); wl_event_source_remove(output->repaint_timer); free(output); }