[PATCH weston 2/2] compositor: Move clearing of primary plane damage to the backends
Ander Conselvan de Oliveira
ander.conselvan.de.oliveira at intel.com
Thu Nov 22 05:57:00 PST 2012
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.
---
I tested this change with drm, x11 and wayland backends. Android and
rpi are untested.
The wayland backend has some artifacts, but that happends because it
is tripple buffering, while the renderer assumes that only two buffers
are used.
src/compositor-android.c | 4 ++++
src/compositor-drm.c | 3 +++
src/compositor-headless.c | 3 +++
src/compositor-rpi.c | 4 ++++
src/compositor-wayland.c | 4 ++++
src/compositor-x11.c | 3 +++
src/compositor.c | 2 --
7 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/compositor-android.c b/src/compositor-android.c
index 2c75e8f..5e27071 100644
--- a/src/compositor-android.c
+++ b/src/compositor-android.c
@@ -92,10 +92,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);
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 1ecd93c..417b67f 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -357,6 +357,9 @@ drm_output_render(struct drm_output *output, pixman_region32_t *damage)
c->base.renderer->repaint_output(&output->base, damage);
+ pixman_region32_subtract(&c->base.primary_plane.damage,
+ &c->base.primary_plane.damage, damage);
+
bo = gbm_surface_lock_front_buffer(output->surface);
if (!bo) {
weston_log("failed to lock front buffer: %m\n");
diff --git a/src/compositor-headless.c b/src/compositor-headless.c
index 55206b3..d23ee0a 100644
--- a/src/compositor-headless.c
+++ b/src/compositor-headless.c
@@ -66,6 +66,9 @@ headless_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, 16);
return;
diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c
index 339032a..c75bcda 100644
--- a/src/compositor-rpi.c
+++ b/src/compositor-rpi.c
@@ -914,6 +914,7 @@ rpi_output_repaint(struct weston_output *base, pixman_region32_t *damage)
{
struct rpi_output *output = to_rpi_output(base);
struct rpi_compositor *compositor = output->compositor;
+ struct weston_plane *primary_plane = &compositor->base.primary_plane;
struct rpi_element *element;
DISPMANX_UPDATE_HANDLE_T update;
int layer = 10000;
@@ -942,6 +943,9 @@ rpi_output_repaint(struct weston_output *base, pixman_region32_t *damage)
*/
compositor->base.renderer->repaint_output(&output->base, damage);
+ pixman_region32_subtract(&primary_plane->damage,
+ &primary_plane->damage, damage);
+
/* Move the list of elements into the old_element_list. */
wl_list_insert_list(&output->old_element_list, &output->element_list);
wl_list_init(&output->element_list);
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 5376a20..24dccd1 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -137,6 +137,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
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index ba18297..b26da09 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -314,6 +314,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);
}
diff --git a/src/compositor.c b/src/compositor.c
index 2ca48b8..6eb0b8c 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -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);
--
1.7.10.4
More information about the wayland-devel
mailing list