summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Hoosier <matt.hoosier@gmail.com>2017-08-24 09:24:20 -0500
committerDaniel Stone <daniels@collabora.com>2017-12-04 19:11:46 +0000
commitdf573031d0ba0a810d84784002d18453b0d9b2eb (patch)
tree54bc7f39fc2130092ac8fb60533167712b060676
parentd4512f6aa1a8db0b811918593f21e7877041f0c0 (diff)
compositor-drm: fix z-order inversion in plane assignment
As discussed in the following thread: https://lists.freedesktop.org/archives/wayland-devel/2017-August/034755.html the existing plane assignment in the DRM backend is vulnerable to accidental masking of the intended fullscreen surface. This change adds a simple stateful memory to the plane assignment algorithm to prevent that. Reviewed-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--libweston/compositor-drm.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 1b4db513..b77209c4 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1869,6 +1869,7 @@ drm_assign_planes(struct weston_output *output_base, void *repaint_data)
struct weston_view *ev, *next;
pixman_region32_t overlap, surface_overlap;
struct weston_plane *primary, *next_plane;
+ bool picked_scanout = false;
/*
* Find a surface for each sprite in the output using some heuristics:
@@ -1915,14 +1916,23 @@ drm_assign_planes(struct weston_output *output_base, void *repaint_data)
&ev->transform.boundingbox);
next_plane = NULL;
- if (pixman_region32_not_empty(&surface_overlap))
+ if (pixman_region32_not_empty(&surface_overlap) || picked_scanout)
next_plane = primary;
if (next_plane == NULL)
next_plane = drm_output_prepare_cursor_view(output, ev);
- if (next_plane == NULL)
+
+ /* If a higher-stacked view already got assigned to scanout, it's incorrect to
+ * assign a subsequent (lower-stacked) view to scanout.
+ */
+ if (next_plane == NULL) {
next_plane = drm_output_prepare_scanout_view(output, ev);
+ if (next_plane)
+ picked_scanout = true;
+ }
+
if (next_plane == NULL)
next_plane = drm_output_prepare_overlay_view(output, ev);
+
if (next_plane == NULL)
next_plane = primary;