compositor: ignore views on other outputs during compositor_accumulate_damage()
authorMichael Olbrich <m.olbrich@pengutronix.de>
Tue, 11 Aug 2020 10:42:35 +0000 (12:42 +0200)
committerDaniel Stone <daniels@collabora.com>
Wed, 12 Aug 2020 11:03:43 +0000 (11:03 +0000)
compositor_accumulate_damage() is called for each output during repaint.
The DRM backend will only set keep_buffer for the surfaces that are visible on
the current output. So a buffer_ref is released that may still be needed. When
the output that shows the surface is repainted, the buffer_ref is gone and the
surface cannot be put on a plane.

Ignore all surfaces that are not visible on the current output to avoid this.

Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
libweston/compositor.c

index a864d5a98443011765aa0ef82b29ddf7c3f5e329..57b220302b39ffc00235d354c56c67f9bbcba8f2 100644 (file)
@@ -2491,8 +2491,9 @@ view_accumulate_damage(struct weston_view *view,
 }
 
 static void
-compositor_accumulate_damage(struct weston_compositor *ec)
+output_accumulate_damage(struct weston_output *output)
 {
+       struct weston_compositor *ec = output->compositor;
        struct weston_plane *plane;
        struct weston_view *ev;
        pixman_region32_t opaque, clip;
@@ -2521,6 +2522,9 @@ compositor_accumulate_damage(struct weston_compositor *ec)
                ev->surface->touched = false;
 
        wl_list_for_each(ev, &ec->view_list, link) {
+               /* Ignore views not visible on the current output */
+               if (!(ev->output_mask & (1u << output->id)))
+                       continue;
                if (ev->surface->touched)
                        continue;
                ev->surface->touched = true;
@@ -2763,7 +2767,7 @@ weston_output_repaint(struct weston_output *output, void *repaint_data)
                }
        }
 
-       compositor_accumulate_damage(ec);
+       output_accumulate_damage(output);
 
        pixman_region32_init(&output_damage);
        pixman_region32_intersect(&output_damage,