[PATCH v14 19/41] compositor-drm: Extract buffer->plane co-ord translation

Pekka Paalanen ppaalanen at gmail.com
Tue Jan 23 14:20:35 UTC 2018


On Wed, 20 Dec 2017 12:26:36 +0000
Daniel Stone <daniels at collabora.com> wrote:

> Pull this into a helper function, so we can use it everywhere.
> 
> Signed-off-by: Daniel Stone <daniels at collabora.com>
> ---
>  libweston/compositor-drm.c | 157 +++++++++++++++++++++++++--------------------
>  1 file changed, 88 insertions(+), 69 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index d61be4f1b..71bf94edd 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -1179,6 +1179,92 @@ drm_plane_state_put_back(struct drm_plane_state *state)
>  	(void) drm_plane_state_alloc(state_output, plane);
>  }
>  
> +/**
> + * Given a weston_view, fill the drm_plane_state's co-ordinates to display on
> + * a given plane.
> + */
> +static void
> +drm_plane_state_coords_for_view(struct drm_plane_state *state,
> +				struct weston_view *ev)
> +{
> +	struct drm_output *output = state->output;
> +	struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
> +	pixman_region32_t dest_rect, src_rect;
> +	pixman_box32_t *box, tbox;
> +	wl_fixed_t sx1, sy1, sx2, sy2;
> +
> +	/* Update the base weston_plane co-ordinates. */
> +	box = pixman_region32_extents(&ev->transform.boundingbox);
> +	state->plane->base.x = box->x1;
> +	state->plane->base.y = box->y1;
> +
> +	/* First calculate the destination co-ordinates by taking the
> +	 * area of the view which is visible on this output, performing any
> +	 * transforms to account for output rotation and scale as necessary. */
> +	pixman_region32_init(&dest_rect);
> +	pixman_region32_intersect(&dest_rect, &ev->transform.boundingbox,
> +				  &output->base.region);
> +	pixman_region32_translate(&dest_rect, -output->base.x, -output->base.y);
> +	box = pixman_region32_extents(&dest_rect);
> +	tbox = weston_transformed_rect(output->base.width,
> +				       output->base.height,
> +				       output->base.transform,
> +				       output->base.current_scale,
> +				       *box);
> +	state->dest_x = tbox.x1;
> +	state->dest_y = tbox.y1;
> +	state->dest_w = tbox.x2 - tbox.x1;
> +	state->dest_h = tbox.y2 - tbox.y1;
> +	pixman_region32_fini(&dest_rect);
> +
> +	/* Now calculate the source rectangle, by finding the points in the
> +	 * view and working backwards to source co-ordinates. */
> +	pixman_region32_init(&src_rect);
> +	pixman_region32_intersect(&src_rect, &ev->transform.boundingbox,
> +				  &output->base.region);
> +	box = pixman_region32_extents(&src_rect);
> +
> +	/* Accounting for any transformations made to this particular surface
> +	 * view, find the source rectangle to use. */
> +	weston_view_from_global_fixed(ev,
> +				      wl_fixed_from_int(box->x1),
> +				      wl_fixed_from_int(box->y1),
> +				      &sx1, &sy1);
> +	weston_view_from_global_fixed(ev,
> +				      wl_fixed_from_int(box->x2),
> +				      wl_fixed_from_int(box->y2),
> +				      &sx2, &sy2);
> +
> +	/* XXX: How is this possible ... ? */

One hypothesis is that since we started with the bounding box which is
in integer global coordinates, it could have been rounded slightly
bigger if the view transformation is not exactly integer-to-integer in
global coordinates, e.g. fractional translation by half a global-pixel
when both buffer and output scales are 2.

See the floorf() and ceilf() calls in compositor.c:view_compute_bbox().

> +	if (sx1 < 0)
> +		sx1 = 0;
> +	if (sy1 < 0)
> +		sy1 = 0;
> +	if (sx2 > wl_fixed_from_int(ev->surface->width))
> +		sx2 = wl_fixed_from_int(ev->surface->width);
> +	if (sy2 > wl_fixed_from_int(ev->surface->height))
> +		sy2 = wl_fixed_from_int(ev->surface->height);

If the clamps changed something, we'd need equivalent adjustment in the
dest, but that seems to be ignored for now.

> +
> +	tbox.x1 = sx1;
> +	tbox.y1 = sy1;
> +	tbox.x2 = sx2;
> +	tbox.y2 = sy2;
> +
> +	/* Apply viewport transforms in reverse, to get the source co-ordinates
> +	 * in buffer space. */
> +	tbox = weston_transformed_rect(wl_fixed_from_int(ev->surface->width),
> +				       wl_fixed_from_int(ev->surface->height),
> +				       viewport->buffer.transform,
> +				       viewport->buffer.scale,
> +				       tbox);
> +

Perhaps one more comment: DRM src rect is 16.16 fixed-point, wl_fixed
is 23.8 fixed point, hence the remaining shift is 8.

> +	state->src_x = tbox.x1 << 8;
> +	state->src_y = tbox.y1 << 8;
> +	state->src_w = (tbox.x2 - tbox.x1) << 8;
> +	state->src_h = (tbox.y2 - tbox.y1) << 8;
> +	pixman_region32_fini(&src_rect);
> +}
> +

Anyway,

Reviewed-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20180123/a99ce656/attachment.sig>


More information about the wayland-devel mailing list