summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>2012-10-31 17:55:45 +0200
committerKristian Høgsberg <krh@bitplanet.net>2012-10-31 13:37:01 -0400
commit4bcf3a5fced20b2265094c71f1a8672df97e1009 (patch)
tree35cfc8c241035628422a672c188f1254b7cb614d
parent424ae0151e5655d098f795f27f983149c76492a0 (diff)
downloadweston-4bcf3a5fced20b2265094c71f1a8672df97e1009.tar.gz
compositor: Fix culling of repaints behind opaque surfaces
Culling of the repaint of a surface behind an opaque surface on the same plane was broken by commit 547149a9 [1]. The idea of that commit is that the damage obscured by an overlay would remain on the primary plane damage and be repainted when the overlay moved. However, in the case the two surfaces are on the same plane, the opaque one is not obscured, so it ends up being repainted. This commit adds an opaque field to struct weston_plane, that is built incrementally when accumulating damage. The opaque region of surfaces on the same plane are removed from the plane's damage, restoring the previous culling behavior. But since damage behind opaque region of other planes is maintained, the bug solved in the mentioned commit is not regressed. https://bugs.freedesktop.org/show_bug.cgi?id=56537
-rw-r--r--src/compositor-drm.c16
-rw-r--r--src/compositor.c10
-rw-r--r--src/compositor.h1
3 files changed, 27 insertions, 0 deletions
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 1730cb2b..11332817 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -793,10 +793,26 @@ drm_assign_planes(struct weston_output *output)
{
struct drm_compositor *c =
(struct drm_compositor *) output->compositor;
+ struct drm_output *drm_output = (struct drm_output *) output;
+ struct drm_sprite *s;
struct weston_surface *es, *next;
pixman_region32_t overlap, surface_overlap;
struct weston_plane *primary, *next_plane;
+ /* Reset the opaque region of the planes */
+ pixman_region32_fini(&drm_output->cursor_plane.opaque);
+ pixman_region32_init(&drm_output->cursor_plane.opaque);
+ pixman_region32_fini(&drm_output->fb_plane.opaque);
+ pixman_region32_init(&drm_output->fb_plane.opaque);
+
+ wl_list_for_each (s, &c->sprite_list, link) {
+ if (!drm_sprite_crtc_supported(output, s->possible_crtcs))
+ continue;
+
+ pixman_region32_fini(&s->plane.opaque);
+ pixman_region32_init(&s->plane.opaque);
+ }
+
/*
* Find a surface for each sprite in the output using some heuristics:
* 1) size
diff --git a/src/compositor.c b/src/compositor.c
index 56474a5e..2d5b2631 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -925,10 +925,15 @@ surface_accumulate_damage(struct weston_surface *surface,
surface->geometry.y - surface->plane->y);
}
+ pixman_region32_subtract(&surface->damage,
+ &surface->damage, &surface->plane->opaque);
pixman_region32_union(&surface->plane->damage,
&surface->plane->damage, &surface->damage);
empty_region(&surface->damage);
pixman_region32_copy(&surface->clip, opaque);
+ pixman_region32_union(&surface->plane->opaque,
+ &surface->plane->opaque,
+ &surface->transform.opaque);
pixman_region32_union(opaque, opaque, &surface->transform.opaque);
}
@@ -968,6 +973,9 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
pixman_region32_init(&opaque);
+ pixman_region32_fini(&ec->primary_plane.opaque);
+ pixman_region32_init(&ec->primary_plane.opaque);
+
wl_list_for_each(es, &ec->surface_list, link)
surface_accumulate_damage(es, &opaque);
@@ -1455,6 +1463,7 @@ WL_EXPORT void
weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y)
{
pixman_region32_init(&plane->damage);
+ pixman_region32_init(&plane->opaque);
plane->x = x;
plane->y = y;
}
@@ -1463,6 +1472,7 @@ WL_EXPORT void
weston_plane_release(struct weston_plane *plane)
{
pixman_region32_fini(&plane->damage);
+ pixman_region32_fini(&plane->opaque);
}
static void
diff --git a/src/compositor.h b/src/compositor.h
index 3176bfd2..121f6bf3 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -270,6 +270,7 @@ struct weston_layer {
struct weston_plane {
pixman_region32_t damage;
+ pixman_region32_t opaque;
int32_t x, y;
};