compositor: Generalize output previous damage into per buffer damage
This is a more generic fix for the issue solved in 4f521731 where
damage obscured by overlays could be lost in one of the output buffers
due to rapid move of a surface in an overlay plane.
This changes the renderer so it keeps track of the damage in each
buffer. Every time a new frame is drawn, the damage of the frame is
added to all the buffers and the rendered regions are cleared from
the current buffer's damage.
diff --git a/src/compositor.c b/src/compositor.c
index 8cb8a3f..bda1381 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -863,7 +863,7 @@
struct weston_animation *animation, *next;
struct weston_frame_callback *cb, *cnext;
struct wl_list frame_callback_list;
- pixman_region32_t opaque, output_damage, new_damage;
+ pixman_region32_t opaque, output_damage;
weston_compositor_update_drag_surfaces(ec);
@@ -896,21 +896,10 @@
pixman_region32_fini(&opaque);
pixman_region32_init(&output_damage);
-
- pixman_region32_init(&new_damage);
- pixman_region32_copy(&new_damage, &ec->primary_plane.damage);
-
- pixman_region32_union(&ec->primary_plane.damage,
- &ec->primary_plane.damage,
- &output->previous_damage);
-
- pixman_region32_intersect(&output->previous_damage,
- &new_damage, &output->region);
-
pixman_region32_intersect(&output_damage,
&ec->primary_plane.damage, &output->region);
-
- pixman_region32_fini(&new_damage);
+ pixman_region32_subtract(&ec->primary_plane.damage,
+ &ec->primary_plane.damage, &output->region);
if (output->dirty)
weston_output_update_matrix(output);
@@ -2521,9 +2510,13 @@
weston_output_destroy(struct weston_output *output)
{
struct weston_compositor *c = output->compositor;
+ int i;
pixman_region32_fini(&output->region);
- pixman_region32_fini(&output->previous_damage);
+
+ for (i = 0; i < 2; i++)
+ pixman_region32_fini(&output->buffer_damage[i]);
+
output->compositor->output_id_pool &= ~(1 << output->id);
wl_display_remove_global(c->wl_display, output->global);
@@ -2647,10 +2640,15 @@
WL_EXPORT void
weston_output_move(struct weston_output *output, int x, int y)
{
+ int i;
+
output->x = x;
output->y = y;
- pixman_region32_init(&output->previous_damage);
+ output->current_buffer = 0;
+ for (i = 0; i < 2; i++)
+ pixman_region32_init(&output->buffer_damage[i]);
+
pixman_region32_init_rect(&output->region, x, y,
output->width,
output->height);