From 57d32d03a87ab4a74230294cefc5fa8b1e28c96d Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 25 Apr 2019 19:39:44 +0300 Subject: [PATCH] rootston: don't submit too much damage We only need to damage the parts of the screen that changed since last frame, we don't need to accumulate damage from previous buffers. We still need to re-render the accumulated damage. Fixes https://github.com/swaywm/wlroots/issues/1665 --- rootston/render.c | 54 +++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/rootston/render.c b/rootston/render.c index 66996d96..f8e3894f 100644 --- a/rootston/render.c +++ b/rootston/render.c @@ -58,7 +58,7 @@ static void render_texture(struct wlr_output *wlr_output, pixman_region32_intersect(&damage, &damage, output_damage); bool damaged = pixman_region32_not_empty(&damage); if (!damaged) { - goto damage_finish; + goto buffer_damage_finish; } int nrects; @@ -68,7 +68,7 @@ static void render_texture(struct wlr_output *wlr_output, wlr_render_texture_with_matrix(renderer, texture, matrix, alpha); } -damage_finish: +buffer_damage_finish: pixman_region32_fini(&damage); } @@ -121,7 +121,7 @@ static void render_decorations(struct roots_output *output, pixman_region32_intersect(&damage, &damage, data->damage); bool damaged = pixman_region32_not_empty(&damage); if (!damaged) { - goto damage_finish; + goto buffer_damage_finish; } float matrix[9]; @@ -137,7 +137,7 @@ static void render_decorations(struct roots_output *output, wlr_render_quad_with_matrix(renderer, color, matrix); } -damage_finish: +buffer_damage_finish: pixman_region32_fini(&damage); } @@ -221,25 +221,26 @@ void output_render(struct roots_output *output) { } bool needs_frame; - pixman_region32_t damage; - pixman_region32_init(&damage); - if (!wlr_output_damage_attach_render(output->damage, &needs_frame, &damage)) { + pixman_region32_t buffer_damage; + pixman_region32_init(&buffer_damage); + if (!wlr_output_damage_attach_render(output->damage, &needs_frame, + &buffer_damage)) { return; } struct render_data data = { - .damage = &damage, + .damage = &buffer_damage, .alpha = 1.0, }; if (!needs_frame) { // Output doesn't need swap and isn't damaged, skip rendering completely - goto damage_finish; + goto buffer_damage_finish; } wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); - if (!pixman_region32_not_empty(&damage)) { + if (!pixman_region32_not_empty(&buffer_damage)) { // Output isn't damaged but needs buffer swap goto renderer_end; } @@ -249,15 +250,15 @@ void output_render(struct roots_output *output) { } int nrects; - pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); + pixman_box32_t *rects = pixman_region32_rectangles(&buffer_damage, &nrects); for (int i = 0; i < nrects; ++i) { scissor_output(output->wlr_output, &rects[i]); wlr_renderer_clear(renderer, clear_color); } - render_layer(output, &damage, + render_layer(output, &buffer_damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); - render_layer(output, &damage, + render_layer(output, &buffer_damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); // If a view is fullscreen on this output, render it @@ -285,39 +286,46 @@ void output_render(struct roots_output *output) { render_view(output, view, &data); } // Render top layer above shell views - render_layer(output, &damage, + render_layer(output, &buffer_damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } - render_drag_icons(output, &damage, server->input); + render_drag_icons(output, &buffer_damage, server->input); - render_layer(output, &damage, + render_layer(output, &buffer_damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); renderer_end: - wlr_output_render_software_cursors(wlr_output, &damage); + wlr_output_render_software_cursors(wlr_output, &buffer_damage); wlr_renderer_scissor(renderer, NULL); wlr_renderer_end(renderer); int width, height; wlr_output_transformed_resolution(wlr_output, &width, &height); + pixman_region32_t output_damage; + pixman_region32_init(&output_damage); + if (server->config->debug_damage_tracking) { - pixman_region32_union_rect(&damage, &damage, 0, 0, width, height); + pixman_region32_union_rect(&output_damage, &output_damage, + 0, 0, width, height); } enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform); - wlr_region_transform(&damage, &damage, transform, width, height); + wlr_region_transform(&output_damage, &output->damage->current, + transform, width, height); + + wlr_output_set_damage(wlr_output, &output_damage); + pixman_region32_fini(&output_damage); - wlr_output_set_damage(wlr_output, &damage); if (!wlr_output_commit(wlr_output)) { - goto damage_finish; + goto buffer_damage_finish; } output->last_frame = desktop->last_frame = now; -damage_finish: - pixman_region32_fini(&damage); +buffer_damage_finish: + pixman_region32_fini(&buffer_damage); // Send frame done events to all surfaces output_for_each_surface(output, surface_send_frame_done_iterator, &now);