compositor: Move clearing of primary plane damage to the backends
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Thu, 22 Nov 2012 13:57:00 +0000 (15:57 +0200)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 27 Nov 2012 22:36:38 +0000 (17:36 -0500)
Backends may move surfaces to different planes, in which case damage is
generated in the primary plane. This damage is usually passed to the
renderer, but in some cases the backend may decide to not render
anything (that's the case when drm compositor scans out a client
buffer). In that case the damage on the primary plane would be
discarded, leading to artifacts later.

This patch makes the backend's responsibility to clear the damage on
the primary plane, so that unrendered damage is kept for as long as
necessary.

src/compositor-android.c
src/compositor-drm.c
src/compositor-wayland.c
src/compositor-x11.c
src/compositor.c

index 3c0273a..a55c9b0 100644 (file)
@@ -128,10 +128,14 @@ android_output_repaint(struct weston_output *base, pixman_region32_t *damage)
 {
        struct android_output *output = to_android_output(base);
         struct android_compositor *compositor = output->compositor;
+       struct weston_plane *primary_plane = &compositor->base.primary_plane;
        struct wl_event_loop *loop;
 
        compositor->base.renderer->repaint_output(&output->base, damage);
 
+       pixman_region32_subtract(&primary_plane->damage,
+                                &primary_plane->damage, damage);
+
        /* FIXME: does Android have a way to signal page flip done? */
        loop = wl_display_get_event_loop(compositor->base.wl_display);
        wl_event_loop_add_idle(loop, android_finish_frame, output);
index 2dca85c..8956c8c 100644 (file)
@@ -330,6 +330,9 @@ drm_output_render(struct drm_output *output, pixman_region32_t *damage)
 
        ec->renderer->repaint_output(&output->base, damage);
 
+       pixman_region32_subtract(&ec->primary_plane.damage,
+                                &ec->primary_plane.damage, damage);
+
        bo = gbm_surface_lock_front_buffer(output->surface);
        if (!bo) {
                weston_log("failed to lock front buffer: %m\n");
index 56759fc..d42d56f 100644 (file)
@@ -311,6 +311,10 @@ wayland_output_repaint(struct weston_output *output_base,
        wl_callback_add_listener(callback, &frame_listener, output);
 
        ec->renderer->repaint_output(&output->base, damage);
+
+       pixman_region32_subtract(&ec->primary_plane.damage,
+                                &ec->primary_plane.damage, damage);
+
 }
 
 static void
index c575f25..20aede8 100644 (file)
@@ -363,6 +363,9 @@ x11_output_repaint(struct weston_output *output_base,
 
        ec->renderer->repaint_output(output_base, damage);
 
+       pixman_region32_subtract(&ec->primary_plane.damage,
+                                &ec->primary_plane.damage, damage);
+
        wl_event_source_timer_update(output->finish_frame_timer, 10);
 }
 
index 55d2060..5da3925 100644 (file)
@@ -985,8 +985,6 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
        pixman_region32_init(&output_damage);
        pixman_region32_intersect(&output_damage,
                                  &ec->primary_plane.damage, &output->region);
-       pixman_region32_subtract(&ec->primary_plane.damage,
-                                &ec->primary_plane.damage, &output->region);
 
        if (output->dirty)
                weston_output_update_matrix(output);