[PATCH v16 07/23] compositor-drm: Use plane_state_coords_for_view for scanout

Daniel Stone daniels at collabora.com
Thu Jul 5 17:16:34 UTC 2018


Now that we have a helper to fill the plane state co-ordinates from a
view, use this for the scanout plane.

We now explicitly check that the view fills exactly the fullscreen area
and nothing else. We then use the new helper to fill out the plane state
values, and do further checks against the filled-in co-ordinates, i.e.
that we're not trying to show an offset into the buffer, or to scale the
image.

An audit of the error paths found some places where we would leave a
plane state hanging; this makes them all consistent.

Signed-off-by: Daniel Stone <daniels at collabora.com>
Tested-by: Emre Ucan <eucan at de.adit-jv.com>
---
 libweston/compositor-drm.c | 64 +++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 35 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index c8eb7ef59..2927a0ebf 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1635,8 +1635,8 @@ drm_output_prepare_scanout_view(struct drm_output_state *output_state,
 	struct drm_plane *scanout_plane = output->scanout_plane;
 	struct drm_plane_state *state;
 	struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
-	struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
 	struct gbm_bo *bo;
+	pixman_box32_t *extents;
 
 	/* Don't import buffers which span multiple outputs. */
 	if (ev->output_mask != (1u << output->base.id))
@@ -1651,23 +1651,13 @@ drm_output_prepare_scanout_view(struct drm_output_state *output_state,
 	if (wl_shm_buffer_get(buffer->resource))
 		return NULL;
 
-	/* Make sure our view is exactly compatible with the output. */
-	if (ev->geometry.x != output->base.x ||
-	    ev->geometry.y != output->base.y)
-		return NULL;
-	if (buffer->width != output->base.current_mode->width ||
-	    buffer->height != output->base.current_mode->height)
-		return NULL;
-
-	if (ev->transform.enabled)
-		return NULL;
-	if (ev->geometry.scissor_enabled)
-		return NULL;
-	if (viewport->buffer.transform != output->base.transform)
-		return NULL;
-	if (viewport->buffer.scale != output->base.current_scale)
-		return NULL;
-	if (!drm_view_transform_supported(ev, &output->base))
+	/* Check the view spans exactly the output size, calculated in the
+	 * logical co-ordinate space. */
+	extents = pixman_region32_extents(&ev->transform.boundingbox);
+	if (extents->x1 != output->base.x ||
+	    extents->y1 != output->base.y ||
+	    extents->x2 != output->base.x + output->base.width ||
+	    extents->y2 != output->base.y + output->base.height)
 		return NULL;
 
 	if (ev->alpha != 1.0f)
@@ -1682,44 +1672,48 @@ drm_output_prepare_scanout_view(struct drm_output_state *output_state,
 		return NULL;
 	}
 
+	state->output = output;
+	if (!drm_plane_state_coords_for_view(state, ev))
+		goto err;
+
+	/* The legacy API does not let us perform cropping or scaling. */
+	if (state->src_x != 0 || state->src_y != 0 ||
+	    state->src_w != state->dest_w << 16 ||
+	    state->src_h != state->dest_h << 16 ||
+	    state->dest_x != 0 || state->dest_y != 0 ||
+	    state->dest_w != (unsigned) output->base.current_mode->width ||
+	    state->dest_h != (unsigned) output->base.current_mode->height)
+		goto err;
+
 	bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
 			   buffer->resource, GBM_BO_USE_SCANOUT);
 
 	/* Unable to use the buffer for scanout */
 	if (!bo)
-		return NULL;
+		goto err;
 
 	state->fb = drm_fb_get_from_bo(bo, b, drm_view_is_opaque(ev),
 				       BUFFER_CLIENT);
 	if (!state->fb) {
-		drm_plane_state_put_back(state);
+		/* We need to explicitly destroy the BO. */
 		gbm_bo_destroy(bo);
-		return NULL;
+		goto err;
 	}
 
 	/* Can't change formats with just a pageflip */
 	if (state->fb->format->format != output->gbm_format) {
 		/* No need to destroy the GBM BO here, as it's now owned
 		 * by the FB. */
-		drm_plane_state_put_back(state);
-		return NULL;
+		goto err;
 	}
 
 	drm_fb_set_buffer(state->fb, buffer);
 
-	state->output = output;
-
-	state->src_x = 0;
-	state->src_y = 0;
-	state->src_w = state->fb->width << 16;
-	state->src_h = state->fb->height << 16;
-
-	state->dest_x = 0;
-	state->dest_y = 0;
-	state->dest_w = output->base.current_mode->width;
-	state->dest_h = output->base.current_mode->height;
-
 	return &scanout_plane->base;
+
+err:
+	drm_plane_state_put_back(state);
+	return NULL;
 }
 
 static struct drm_fb *
-- 
2.17.1



More information about the wayland-devel mailing list