From: Nobuhiko Tanibata <nobuhiko_tanib...@xddp.denso.co.jp>

Transform matrix for transforming a surface to global_matrix is
calculated from
* ivi_layout_surface_properties
* ivi_layout_layer_properties

This patch pareares sub-method like following,
1/ calc_surface_to_global_matrix()
 calc_transformation_matrix() is called twice with
 ivi_layout_surface/layer_properties respectively.

2/ calc_transformation_matrix()
 This calcurates matrix from orientation, source rectangle and
 destination rectangle.
 2-1/ To calculate rotation, fit centor of source rectangle to (0,0)
      temporarily. This is moved back in 2-4.
 2-2/ Apply rotation variant
 2-3/ Apply scale variant
 2-4/ Apply positioning variant, taking account into 2-1 temporary
      positioning.

Signed-off-by: Nobuhiko Tanibata <nobuhiko_tanib...@xddp.denso.co.jp>
Acked-by: Pekka Paalanen <pekka.paala...@collabora.co.uk>
---
 ivi-shell/ivi-layout-private.h |   1 +
 ivi-shell/ivi-layout.c         | 169 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 168 insertions(+), 2 deletions(-)

diff --git a/ivi-shell/ivi-layout-private.h b/ivi-shell/ivi-layout-private.h
index 4debfd6..9c04c30 100644
--- a/ivi-shell/ivi-layout-private.h
+++ b/ivi-shell/ivi-layout-private.h
@@ -39,6 +39,7 @@ struct ivi_layout_surface {
        struct ivi_layout *layout;
        struct weston_surface *surface;
 
+       struct weston_transform transform;
 
        struct ivi_layout_surface_properties prop;
        uint32_t event_mask;
diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
index 8e0a9f1..2974bb7 100644
--- a/ivi-shell/ivi-layout.c
+++ b/ivi-shell/ivi-layout.c
@@ -111,6 +111,14 @@ struct ivi_layout_notification_callback {
        void *data;
 };
 
+struct ivi_rectangle
+{
+       int32_t x;
+       int32_t y;
+       int32_t width;
+       int32_t height;
+};
+
 static void
 remove_notification(struct wl_list *listener_list, void *callback, void 
*userdata);
 
@@ -348,6 +356,7 @@ ivi_layout_surface_destroy(struct ivi_layout_surface 
*ivisurf)
                return;
        }
 
+       wl_list_remove(&ivisurf->transform.link);
        wl_list_remove(&ivisurf->pending.link);
        wl_list_remove(&ivisurf->order.link);
        wl_list_remove(&ivisurf->link);
@@ -486,10 +495,141 @@ update_opacity(struct ivi_layout_layer *ivilayer,
 }
 
 static void
+get_rotate_values(enum wl_output_transform orientation,
+                 float *v_sin,
+                 float *v_cos)
+{
+       switch (orientation) {
+       case WL_OUTPUT_TRANSFORM_90:
+               *v_sin = 1.0f;
+               *v_cos = 0.0f;
+               break;
+       case WL_OUTPUT_TRANSFORM_180:
+               *v_sin = 0.0f;
+               *v_cos = -1.0f;
+               break;
+       case WL_OUTPUT_TRANSFORM_270:
+               *v_sin = -1.0f;
+               *v_cos = 0.0f;
+               break;
+       case WL_OUTPUT_TRANSFORM_NORMAL:
+       default:
+               *v_sin = 0.0f;
+               *v_cos = 1.0f;
+               break;
+       }
+}
+
+static void
+get_scale(enum wl_output_transform orientation,
+         float dest_width,
+         float dest_height,
+         float source_width,
+         float source_height,
+         float *scale_x,
+         float *scale_y)
+{
+       switch (orientation) {
+       case WL_OUTPUT_TRANSFORM_90:
+               *scale_x = dest_width / source_height;
+               *scale_y = dest_height / source_width;
+               break;
+       case WL_OUTPUT_TRANSFORM_180:
+               *scale_x = dest_width / source_width;
+               *scale_y = dest_height / source_height;
+               break;
+       case WL_OUTPUT_TRANSFORM_270:
+               *scale_x = dest_width / source_height;
+               *scale_y = dest_height / source_width;
+               break;
+       case WL_OUTPUT_TRANSFORM_NORMAL:
+       default:
+               *scale_x = dest_width / source_width;
+               *scale_y = dest_height / source_height;
+               break;
+       }
+}
+
+static void
+calc_transformation_matrix(struct ivi_rectangle *source_rect,
+                          struct ivi_rectangle *dest_rect,
+                          enum wl_output_transform orientation,
+                          struct weston_matrix *m)
+{
+       float source_center_x;
+       float source_center_y;
+       float vsin;
+       float vcos;
+       float scale_x;
+       float scale_y;
+       float translate_x;
+       float translate_y;
+
+       source_center_x = source_rect->x + source_rect->width * 0.5f;
+       source_center_y = source_rect->y + source_rect->height * 0.5f;
+       weston_matrix_translate(m, -source_center_x, -source_center_y, 0.0f);
+
+       get_rotate_values(orientation, &vsin, &vcos);
+       weston_matrix_rotate_xy(m, vcos, vsin);
+
+       get_scale(orientation,
+                 dest_rect->width,
+                 dest_rect->height,
+                 source_rect->width,
+                 source_rect->height,
+                 &scale_x,
+                 &scale_y);
+       weston_matrix_scale(m, scale_x, scale_y, 1.0f);
+
+       translate_x = dest_rect->width * 0.5f + dest_rect->x;
+       translate_y = dest_rect->height * 0.5f + dest_rect->y;
+       weston_matrix_translate(m, translate_x, translate_y, 0.0f);
+}
+
+/**
+ * This computes the whole transformation matrix from surface-local
+ * coordinates to global coordinates. It is assumed that
+ * weston_view::geometry.{x,y} are zero.
+ */
+static void
+calc_surface_to_global_matrix(struct ivi_layout_layer *ivilayer,
+                             struct ivi_layout_surface *ivisurf,
+                             struct weston_matrix *m)
+{
+       const struct ivi_layout_surface_properties *sp = &ivisurf->prop;
+       const struct ivi_layout_layer_properties *lp = &ivilayer->prop;
+       struct ivi_rectangle surface_source_rect = { sp->source_x,
+                                                    sp->source_y,
+                                                    sp->source_width,
+                                                    sp->source_height };
+       struct ivi_rectangle surface_dest_rect =   { sp->dest_x,
+                                                    sp->dest_y,
+                                                    sp->dest_width,
+                                                    sp->dest_height };
+       struct ivi_rectangle layer_source_rect =   { lp->source_x,
+                                                    lp->source_y,
+                                                    lp->source_width,
+                                                    lp->source_height };
+       struct ivi_rectangle layer_dest_rect =     { lp->dest_x,
+                                                    lp->dest_y,
+                                                    lp->dest_width,
+                                                    lp->dest_height };
+
+       calc_transformation_matrix(&surface_source_rect,
+                                  &surface_dest_rect,
+                                  sp->orientation, m);
+
+       calc_transformation_matrix(&layer_source_rect,
+                                  &layer_dest_rect,
+                                  lp->orientation, m);
+}
+
+static void
 update_prop(struct ivi_layout_layer *ivilayer,
            struct ivi_layout_surface *ivisurf)
 {
        struct weston_view *tmpview;
+       bool can_calc = true;
 
        if (!ivilayer->event_mask && !ivisurf->event_mask) {
                return;
@@ -497,14 +637,37 @@ update_prop(struct ivi_layout_layer *ivilayer,
 
        update_opacity(ivilayer, ivisurf);
 
-       ivisurf->update_count++;
-
        wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
                if (tmpview != NULL) {
                        break;
                }
        }
 
+       if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 
0) {
+               weston_log("ivi-shell: source rectangle is not yet set by 
ivi_layout_surface_set_source_rectangle\n");
+               can_calc = false;
+       }
+
+       if (ivisurf->prop.dest_width == 0 || ivisurf->prop.dest_height == 0) {
+               weston_log("ivi-shell: destination rectangle is not yet set by 
ivi_layout_surface_set_destination_rectangle\n");
+               can_calc = false;
+       }
+
+       if (can_calc) {
+               wl_list_remove(&ivisurf->transform.link);
+               weston_matrix_init(&ivisurf->transform.matrix);
+
+               calc_surface_to_global_matrix(ivilayer, ivisurf, 
&ivisurf->transform.matrix);
+
+               if (tmpview != NULL) {
+                       wl_list_insert(&tmpview->geometry.transformation_list, 
&ivisurf->transform.link);
+
+                       weston_view_set_transform_parent(tmpview, NULL);
+               }
+       }
+
+       ivisurf->update_count++;
+
        if (tmpview != NULL) {
                weston_view_geometry_dirty(tmpview);
        }
@@ -2626,6 +2789,8 @@ ivi_layout_surface_create(struct weston_surface 
*wl_surface,
        ivisurf->surface->width_from_buffer  = 0;
        ivisurf->surface->height_from_buffer = 0;
 
+       weston_matrix_init(&ivisurf->transform.matrix);
+       wl_list_init(&ivisurf->transform.link);
 
        init_surface_properties(&ivisurf->prop);
        ivisurf->event_mask = 0;
-- 
1.8.3.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to