[PATCH] compositor-drm: fix z-order inversion in plane assignment

Matt Hoosier matt.hoosier at gmail.com
Thu Aug 24 14:24:20 UTC 2017


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.
---
 libweston/compositor-drm.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 8e1e788f..81dc8fe6 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1495,6 +1495,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;
 
 	/*
 	 * Find a surface for each sprite in the output using some heuristics:
@@ -1516,6 +1517,8 @@ drm_assign_planes(struct weston_output *output_base, void *repaint_data)
 	output->cursor_plane.x = INT32_MIN;
 	output->cursor_plane.y = INT32_MIN;
 
+	picked_scanout = false;
+
 	wl_list_for_each_safe(ev, next, &output_base->compositor->view_list, link) {
 		struct weston_surface *es = ev->surface;
 
@@ -1545,10 +1548,22 @@ drm_assign_planes(struct weston_output *output_base, void *repaint_data)
 			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 && !picked_scanout) {
 			next_plane = drm_output_prepare_scanout_view(output, ev);
-		if (next_plane == NULL)
+			if (next_plane)
+				picked_scanout = true;
+		}
+
+		/* Similarly, it's incorrect to elevate a view to an overlay if some higher-stacked
+		 * view is already identified as full-screen scanout.
+		 */
+		if (next_plane == NULL && !picked_scanout)
 			next_plane = drm_output_prepare_overlay_view(output, ev);
+
 		if (next_plane == NULL)
 			next_plane = primary;
 
-- 
2.13.3



More information about the wayland-devel mailing list