[weston,v2,01/20] weston_surface: Add surface-to-buffer and buffer-to-surface matrices

Submitted by Derek Foreman on Oct. 16, 2014, 3:55 p.m.

Details

Message ID 1413474938-2407-2-git-send-email-derekf@osg.samsung.com
State Superseded
Delegated to: Pekka Paalanen
Headers show

Not browsing as part of any series.

Commit Message

Derek Foreman Oct. 16, 2014, 3:55 p.m.
From: Jason Ekstrand <jason@jlekstrand.net>

---
 src/compositor.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/compositor.h |  6 ++++
 2 files changed, 90 insertions(+)

Patch hide | download patch | download mbox

diff --git a/src/compositor.c b/src/compositor.c
index 4540911..c85cf2e 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -615,6 +615,9 @@  weston_surface_create(struct weston_compositor *compositor)
 	wl_list_init(&surface->subsurface_list);
 	wl_list_init(&surface->subsurface_list_pending);
 
+	weston_matrix_init(&surface->buffer_to_surface_matrix);
+	weston_matrix_init(&surface->surface_to_buffer_matrix);
+
 	return surface;
 }
 
@@ -2304,6 +2307,82 @@  weston_surface_commit_subsurface_order(struct weston_surface *surface)
 }
 
 static void
+weston_surface_build_buffer_matrix(struct weston_surface *surface,
+				   struct weston_matrix *matrix)
+{
+	struct weston_buffer_viewport *vp = &surface->buffer_viewport;
+	double src_width, src_height, dest_width, dest_height;
+
+	weston_matrix_init(matrix);
+
+	if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
+		src_width = surface->width_from_buffer;
+		src_height = surface->height_from_buffer;
+	} else {
+		src_width = wl_fixed_to_double(vp->buffer.src_width);
+		src_height = wl_fixed_to_double(vp->buffer.src_height);
+	}
+
+	if (vp->surface.width == -1) {
+		dest_width = src_width;
+		dest_height = src_height;
+	} else {
+		dest_width = vp->surface.width;
+		dest_height = vp->surface.height;
+	}
+
+	if (src_width != dest_width || src_height != dest_height)
+		weston_matrix_scale(matrix,
+				    src_width / dest_width,
+				    src_height / dest_height, 1);
+
+	if (vp->buffer.src_width != wl_fixed_from_int(-1))
+		weston_matrix_translate(matrix,
+					wl_fixed_to_double(vp->buffer.src_x),
+					wl_fixed_to_double(vp->buffer.src_y),
+					0);
+
+	switch (vp->buffer.transform) {
+	case WL_OUTPUT_TRANSFORM_FLIPPED:
+	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+		weston_matrix_scale(matrix, -1, 1, 1);
+		weston_matrix_translate(matrix,
+					surface->width_from_buffer, 0, 0);
+		break;
+	}
+
+	switch (vp->buffer.transform) {
+	default:
+	case WL_OUTPUT_TRANSFORM_NORMAL:
+	case WL_OUTPUT_TRANSFORM_FLIPPED:
+		break;
+	case WL_OUTPUT_TRANSFORM_90:
+	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+		weston_matrix_rotate_xy(matrix, 0, 1);
+		weston_matrix_translate(matrix,
+					surface->height_from_buffer, 0, 0);
+		break;
+	case WL_OUTPUT_TRANSFORM_180:
+	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+		weston_matrix_rotate_xy(matrix, -1, 0);
+		weston_matrix_translate(matrix,
+					surface->width_from_buffer,
+					surface->height_from_buffer, 0);
+		break;
+	case WL_OUTPUT_TRANSFORM_270:
+	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+		weston_matrix_rotate_xy(matrix, 0, -1);
+		weston_matrix_translate(matrix,
+					0, surface->width_from_buffer, 0);
+		break;
+	}
+
+	weston_matrix_scale(matrix, vp->buffer.scale, vp->buffer.scale, 1);
+}
+
+static void
 weston_surface_commit_state(struct weston_surface *surface,
 			    struct weston_surface_state *state)
 {
@@ -2320,6 +2399,11 @@  weston_surface_commit_state(struct weston_surface *surface,
 		weston_surface_attach(surface, state->buffer);
 	weston_surface_state_set_buffer(state, NULL);
 
+	weston_surface_build_buffer_matrix(surface,
+					   &surface->surface_to_buffer_matrix);
+	weston_matrix_invert(&surface->buffer_to_surface_matrix,
+			     &surface->surface_to_buffer_matrix);
+
 	if (state->newly_attached || state->buffer_viewport.changed) {
 		weston_surface_update_size(surface);
 		if (surface->configure)
diff --git a/src/compositor.h b/src/compositor.h
index 0fbca33..95900ed 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -893,6 +893,12 @@  struct weston_surface {
 	/* All the pending state, that wl_surface.commit will apply. */
 	struct weston_surface_state pending;
 
+	/* Matrices representating of the full transformation between
+	 * buffer and surface coordinates.  These matrices are updated
+	 * using the weston_surface_build_buffer_matrix function. */
+	struct weston_matrix buffer_to_surface_matrix;
+	struct weston_matrix surface_to_buffer_matrix;
+
 	/*
 	 * If non-NULL, this function will be called on
 	 * wl_surface::commit after a new buffer has been set up for

Comments

I have a comment below, the rest looks good to me.


2014-10-16 18:55 GMT+03:00 Derek Foreman <derekf@osg.samsung.com>:
> From: Jason Ekstrand <jason@jlekstrand.net>
>
> ---
>  src/compositor.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/compositor.h |  6 ++++
>  2 files changed, 90 insertions(+)
>
> diff --git a/src/compositor.c b/src/compositor.c
> index 4540911..c85cf2e 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -615,6 +615,9 @@ weston_surface_create(struct weston_compositor *compositor)
>         wl_list_init(&surface->subsurface_list);
>         wl_list_init(&surface->subsurface_list_pending);
>
> +       weston_matrix_init(&surface->buffer_to_surface_matrix);
> +       weston_matrix_init(&surface->surface_to_buffer_matrix);
> +
>         return surface;
>  }
>
> @@ -2304,6 +2307,82 @@ weston_surface_commit_subsurface_order(struct weston_surface *surface)
>  }
>
>  static void
> +weston_surface_build_buffer_matrix(struct weston_surface *surface,
> +                                  struct weston_matrix *matrix)
> +{
> +       struct weston_buffer_viewport *vp = &surface->buffer_viewport;
> +       double src_width, src_height, dest_width, dest_height;
> +
> +       weston_matrix_init(matrix);
> +
> +       if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
> +               src_width = surface->width_from_buffer;
> +               src_height = surface->height_from_buffer;
> +       } else {
> +               src_width = wl_fixed_to_double(vp->buffer.src_width);
> +               src_height = wl_fixed_to_double(vp->buffer.src_height);
> +       }
> +
> +       if (vp->surface.width == -1) {
> +               dest_width = src_width;
> +               dest_height = src_height;
> +       } else {
> +               dest_width = vp->surface.width;
> +               dest_height = vp->surface.height;
> +       }
> +
> +       if (src_width != dest_width || src_height != dest_height)
> +               weston_matrix_scale(matrix,
> +                                   src_width / dest_width,
> +                                   src_height / dest_height, 1);
> +
> +       if (vp->buffer.src_width != wl_fixed_from_int(-1))
> +               weston_matrix_translate(matrix,
> +                                       wl_fixed_to_double(vp->buffer.src_x),
> +                                       wl_fixed_to_double(vp->buffer.src_y),
> +                                       0);
> +
> +       switch (vp->buffer.transform) {
> +       case WL_OUTPUT_TRANSFORM_FLIPPED:
> +       case WL_OUTPUT_TRANSFORM_FLIPPED_90:
> +       case WL_OUTPUT_TRANSFORM_FLIPPED_180:
> +       case WL_OUTPUT_TRANSFORM_FLIPPED_270:
> +               weston_matrix_scale(matrix, -1, 1, 1);
> +               weston_matrix_translate(matrix,
> +                                       surface->width_from_buffer, 0, 0);
> +               break;
> +       }
> +
> +       switch (vp->buffer.transform) {
> +       default:
> +       case WL_OUTPUT_TRANSFORM_NORMAL:
> +       case WL_OUTPUT_TRANSFORM_FLIPPED:
> +               break;
> +       case WL_OUTPUT_TRANSFORM_90:
> +       case WL_OUTPUT_TRANSFORM_FLIPPED_90:
> +               weston_matrix_rotate_xy(matrix, 0, 1);
> +               weston_matrix_translate(matrix,
> +                                       surface->height_from_buffer, 0, 0);

This may be me and matrices not being good friends, but shouldn't this
be 'width_from_buffer'?

> +               break;
> +       case WL_OUTPUT_TRANSFORM_180:
> +       case WL_OUTPUT_TRANSFORM_FLIPPED_180:
> +               weston_matrix_rotate_xy(matrix, -1, 0);
> +               weston_matrix_translate(matrix,
> +                                       surface->width_from_buffer,
> +                                       surface->height_from_buffer, 0);
> +               break;
> +       case WL_OUTPUT_TRANSFORM_270:
> +       case WL_OUTPUT_TRANSFORM_FLIPPED_270:
> +               weston_matrix_rotate_xy(matrix, 0, -1);
> +               weston_matrix_translate(matrix,
> +                                       0, surface->width_from_buffer, 0);
> +               break;
> +       }
> +
> +       weston_matrix_scale(matrix, vp->buffer.scale, vp->buffer.scale, 1);
> +}
> +
> +static void
>  weston_surface_commit_state(struct weston_surface *surface,
>                             struct weston_surface_state *state)
>  {
> @@ -2320,6 +2399,11 @@ weston_surface_commit_state(struct weston_surface *surface,
>                 weston_surface_attach(surface, state->buffer);
>         weston_surface_state_set_buffer(state, NULL);
>
> +       weston_surface_build_buffer_matrix(surface,
> +                                          &surface->surface_to_buffer_matrix);
> +       weston_matrix_invert(&surface->buffer_to_surface_matrix,
> +                            &surface->surface_to_buffer_matrix);
> +
>         if (state->newly_attached || state->buffer_viewport.changed) {
>                 weston_surface_update_size(surface);
>                 if (surface->configure)
> diff --git a/src/compositor.h b/src/compositor.h
> index 0fbca33..95900ed 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -893,6 +893,12 @@ struct weston_surface {
>         /* All the pending state, that wl_surface.commit will apply. */
>         struct weston_surface_state pending;
>
> +       /* Matrices representating of the full transformation between
> +        * buffer and surface coordinates.  These matrices are updated
> +        * using the weston_surface_build_buffer_matrix function. */
> +       struct weston_matrix buffer_to_surface_matrix;
> +       struct weston_matrix surface_to_buffer_matrix;
> +
>         /*
>          * If non-NULL, this function will be called on
>          * wl_surface::commit after a new buffer has been set up for
> --
> 2.1.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
On 09/01/15 02:52 PM, Giulio Camuffo wrote:
> I have a comment below, the rest looks good to me.
> 
> 
> 2014-10-16 18:55 GMT+03:00 Derek Foreman <derekf@osg.samsung.com>:
>> From: Jason Ekstrand <jason@jlekstrand.net>
>>
>> ---
>>  src/compositor.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  src/compositor.h |  6 ++++
>>  2 files changed, 90 insertions(+)
>>
>> diff --git a/src/compositor.c b/src/compositor.c
>> index 4540911..c85cf2e 100644
>> --- a/src/compositor.c
>> +++ b/src/compositor.c
>> @@ -615,6 +615,9 @@ weston_surface_create(struct weston_compositor *compositor)
>>         wl_list_init(&surface->subsurface_list);
>>         wl_list_init(&surface->subsurface_list_pending);
>>
>> +       weston_matrix_init(&surface->buffer_to_surface_matrix);
>> +       weston_matrix_init(&surface->surface_to_buffer_matrix);
>> +
>>         return surface;
>>  }
>>
>> @@ -2304,6 +2307,82 @@ weston_surface_commit_subsurface_order(struct weston_surface *surface)
>>  }
>>
>>  static void
>> +weston_surface_build_buffer_matrix(struct weston_surface *surface,
>> +                                  struct weston_matrix *matrix)
>> +{
>> +       struct weston_buffer_viewport *vp = &surface->buffer_viewport;
>> +       double src_width, src_height, dest_width, dest_height;
>> +
>> +       weston_matrix_init(matrix);
>> +
>> +       if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
>> +               src_width = surface->width_from_buffer;
>> +               src_height = surface->height_from_buffer;
>> +       } else {
>> +               src_width = wl_fixed_to_double(vp->buffer.src_width);
>> +               src_height = wl_fixed_to_double(vp->buffer.src_height);
>> +       }
>> +
>> +       if (vp->surface.width == -1) {
>> +               dest_width = src_width;
>> +               dest_height = src_height;
>> +       } else {
>> +               dest_width = vp->surface.width;
>> +               dest_height = vp->surface.height;
>> +       }
>> +
>> +       if (src_width != dest_width || src_height != dest_height)
>> +               weston_matrix_scale(matrix,
>> +                                   src_width / dest_width,
>> +                                   src_height / dest_height, 1);
>> +
>> +       if (vp->buffer.src_width != wl_fixed_from_int(-1))
>> +               weston_matrix_translate(matrix,
>> +                                       wl_fixed_to_double(vp->buffer.src_x),
>> +                                       wl_fixed_to_double(vp->buffer.src_y),
>> +                                       0);
>> +
>> +       switch (vp->buffer.transform) {
>> +       case WL_OUTPUT_TRANSFORM_FLIPPED:
>> +       case WL_OUTPUT_TRANSFORM_FLIPPED_90:
>> +       case WL_OUTPUT_TRANSFORM_FLIPPED_180:
>> +       case WL_OUTPUT_TRANSFORM_FLIPPED_270:
>> +               weston_matrix_scale(matrix, -1, 1, 1);
>> +               weston_matrix_translate(matrix,
>> +                                       surface->width_from_buffer, 0, 0);
>> +               break;
>> +       }
>> +
>> +       switch (vp->buffer.transform) {
>> +       default:
>> +       case WL_OUTPUT_TRANSFORM_NORMAL:
>> +       case WL_OUTPUT_TRANSFORM_FLIPPED:
>> +               break;
>> +       case WL_OUTPUT_TRANSFORM_90:
>> +       case WL_OUTPUT_TRANSFORM_FLIPPED_90:
>> +               weston_matrix_rotate_xy(matrix, 0, 1);
>> +               weston_matrix_translate(matrix,
>> +                                       surface->height_from_buffer, 0, 0);
> 
> This may be me and matrices not being good friends, but shouldn't this
> be 'width_from_buffer'?

I think this math is ok.  It's a 90 degree rotation so the shift we want
is height pixels.  We rotate then translate so the translation isn't
altered by the rotation...

(also, I just checked, and this rotation works properly :)

>> +               break;
>> +       case WL_OUTPUT_TRANSFORM_180:
>> +       case WL_OUTPUT_TRANSFORM_FLIPPED_180:
>> +               weston_matrix_rotate_xy(matrix, -1, 0);
>> +               weston_matrix_translate(matrix,
>> +                                       surface->width_from_buffer,
>> +                                       surface->height_from_buffer, 0);
>> +               break;
>> +       case WL_OUTPUT_TRANSFORM_270:
>> +       case WL_OUTPUT_TRANSFORM_FLIPPED_270:
>> +               weston_matrix_rotate_xy(matrix, 0, -1);
>> +               weston_matrix_translate(matrix,
>> +                                       0, surface->width_from_buffer, 0);
>> +               break;
>> +       }
>> +
>> +       weston_matrix_scale(matrix, vp->buffer.scale, vp->buffer.scale, 1);
>> +}
>> +
>> +static void
>>  weston_surface_commit_state(struct weston_surface *surface,
>>                             struct weston_surface_state *state)
>>  {
>> @@ -2320,6 +2399,11 @@ weston_surface_commit_state(struct weston_surface *surface,
>>                 weston_surface_attach(surface, state->buffer);
>>         weston_surface_state_set_buffer(state, NULL);
>>
>> +       weston_surface_build_buffer_matrix(surface,
>> +                                          &surface->surface_to_buffer_matrix);
>> +       weston_matrix_invert(&surface->buffer_to_surface_matrix,
>> +                            &surface->surface_to_buffer_matrix);
>> +
>>         if (state->newly_attached || state->buffer_viewport.changed) {
>>                 weston_surface_update_size(surface);
>>                 if (surface->configure)
>> diff --git a/src/compositor.h b/src/compositor.h
>> index 0fbca33..95900ed 100644
>> --- a/src/compositor.h
>> +++ b/src/compositor.h
>> @@ -893,6 +893,12 @@ struct weston_surface {
>>         /* All the pending state, that wl_surface.commit will apply. */
>>         struct weston_surface_state pending;
>>
>> +       /* Matrices representating of the full transformation between
>> +        * buffer and surface coordinates.  These matrices are updated
>> +        * using the weston_surface_build_buffer_matrix function. */
>> +       struct weston_matrix buffer_to_surface_matrix;
>> +       struct weston_matrix surface_to_buffer_matrix;
>> +
>>         /*
>>          * If non-NULL, this function will be called on
>>          * wl_surface::commit after a new buffer has been set up for
>> --
>> 2.1.1
>>
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> _______________________________________________
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>