[PATCH weston 3/4] compositor: put weston_matrix_pointer into transformation_list

Pekka Paalanen ppaalanen at gmail.com
Tue Dec 18 03:58:49 PST 2012


Define struct weston_matrix_pointer, which acts as pointer to a matrix,
not a matrix itself. This type is stored into
weston_surface::geometry.transformation_list instead of
weston_transform.

This is a step towards making surface transformations properly
inheritable. Transformation list can refer to another matrix, without
adding hooks to maintain a copy of that matrix.

Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
---
 src/compositor.c |   18 +++++++++++-------
 src/compositor.h |   27 +++++++++++++++++++--------
 src/shell.c      |   49 +++++++++++++++++++++++++++----------------------
 src/util.c       |    5 +++--
 4 files changed, 60 insertions(+), 39 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 24ae6e3..1533cbc 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -293,9 +293,12 @@ weston_surface_create(struct weston_compositor *compositor)
 	wl_list_init(&surface->frame_callback_list);
 
 	wl_list_init(&surface->geometry.transformation_list);
-	wl_list_insert(&surface->geometry.transformation_list,
-		       &surface->transform.position.link);
+
 	weston_matrix_init(&surface->transform.position.matrix);
+	weston_transform_init(&surface->transform.position);
+	wl_list_insert(&surface->geometry.transformation_list,
+		       &surface->transform.position.ptr.link);
+
 	pixman_region32_init(&surface->transform.boundingbox);
 	surface->transform.dirty = 1;
 
@@ -539,7 +542,7 @@ weston_surface_update_transform_enable(struct weston_surface *surface)
 {
 	struct weston_matrix *matrix = &surface->transform.matrix;
 	struct weston_matrix *inverse = &surface->transform.inverse;
-	struct weston_transform *tform;
+	struct weston_matrix_pointer *ptr;
 
 	surface->transform.enabled = 1;
 
@@ -548,8 +551,9 @@ weston_surface_update_transform_enable(struct weston_surface *surface)
 	surface->transform.position.matrix.d[13] = surface->geometry.y;
 
 	weston_matrix_init(matrix);
-	wl_list_for_each(tform, &surface->geometry.transformation_list, link)
-		weston_matrix_multiply(matrix, &tform->matrix);
+	wl_list_for_each(ptr, &surface->geometry.transformation_list, link) {
+		weston_matrix_multiply(matrix, ptr->matrix);
+	}
 
 	if (weston_matrix_invert(inverse, matrix) < 0) {
 		/* Oops, bad total transformation, not invertible */
@@ -581,9 +585,9 @@ weston_surface_update_transform(struct weston_surface *surface)
 
 	/* transform.position is always in transformation_list */
 	if (surface->geometry.transformation_list.next ==
-	    &surface->transform.position.link &&
+	    &surface->transform.position.ptr.link &&
 	    surface->geometry.transformation_list.prev ==
-	    &surface->transform.position.link) {
+	    &surface->transform.position.ptr.link) {
 		weston_surface_update_transform_disable(surface);
 	} else {
 		if (weston_surface_update_transform_enable(surface) < 0)
diff --git a/src/compositor.h b/src/compositor.h
index 3a3580a..b681481 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -37,11 +37,6 @@
 	const __typeof__( ((type *)0)->member ) *__mptr = (ptr);	\
 	(type *)( (char *)__mptr - offsetof(type,member) );})
 
-struct weston_transform {
-	struct weston_matrix matrix;
-	struct wl_list link;
-};
-
 struct weston_surface;
 struct shell_surface;
 struct weston_seat;
@@ -345,6 +340,16 @@ struct weston_compositor {
 	struct weston_xkb_info xkb_info;
 };
 
+struct weston_matrix_pointer {
+	struct weston_matrix *matrix;
+	struct wl_list link;
+};
+
+struct weston_transform {
+	struct weston_matrix matrix;
+	struct weston_matrix_pointer ptr;
+};
+
 struct weston_buffer_reference {
 	struct wl_buffer *buffer;
 	struct wl_listener destroy_listener;
@@ -357,8 +362,8 @@ struct weston_region {
 
 /* Using weston_surface transformations
  *
- * To add a transformation to a surface, create a struct weston_transform, and
- * add it to the list surface->geometry.transformation_list. Whenever you
+ * To add a transformation to a surface, create a struct weston_matrix_pointer,
+ * and add it to the list surface->geometry.transformation_list. Whenever you
  * change the list, anything under surface->geometry, or anything in the
  * weston_transforms linked into the list, you must call
  * weston_surface_geometry_dirty().
@@ -402,7 +407,7 @@ struct weston_surface {
 		float x, y; /* surface translation on display */
 		int32_t width, height;
 
-		/* struct weston_transform */
+		/* struct weston_matrix_pointer::link */
 		struct wl_list transformation_list;
 	} geometry;
 
@@ -845,4 +850,10 @@ weston_transformed_rect(int width, int height,
 			enum wl_output_transform transform,
 			pixman_box32_t rect);
 
+static inline void
+weston_transform_init(struct weston_transform *tform)
+{
+	tform->ptr.matrix = &tform->matrix;
+}
+
 #endif
diff --git a/src/shell.c b/src/shell.c
index 5b9acd7..e25140d 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -587,9 +587,9 @@ surface_translate(struct weston_surface *surface, double d)
 	struct weston_transform *transform;
 
 	transform = &shsurf->workspace_transform;
-	if (wl_list_empty(&transform->link))
+	if (wl_list_empty(&transform->ptr.link))
 		wl_list_insert(surface->geometry.transformation_list.prev,
-			       &shsurf->workspace_transform.link);
+			       &shsurf->workspace_transform.ptr.link);
 
 	weston_matrix_init(&shsurf->workspace_transform.matrix);
 	weston_matrix_translate(&shsurf->workspace_transform.matrix,
@@ -666,9 +666,9 @@ workspace_deactivate_transforms(struct workspace *ws)
 
 	wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
 		shsurf = get_shell_surface(surface);
-		if (!wl_list_empty(&shsurf->workspace_transform.link)) {
-			wl_list_remove(&shsurf->workspace_transform.link);
-			wl_list_init(&shsurf->workspace_transform.link);
+		if (!wl_list_empty(&shsurf->workspace_transform.ptr.link)) {
+			wl_list_remove(&shsurf->workspace_transform.ptr.link);
+			wl_list_init(&shsurf->workspace_transform.ptr.link);
 		}
 		weston_surface_geometry_dirty(surface);
 	}
@@ -919,9 +919,9 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
 		update_workspace(shell, index, from, to);
 	else {
 		shsurf = get_shell_surface(surface);
-		if (wl_list_empty(&shsurf->workspace_transform.link))
+		if (wl_list_empty(&shsurf->workspace_transform.ptr.link))
 			wl_list_insert(&shell->workspaces.anim_sticky_list,
-				       &shsurf->workspace_transform.link);
+				       &shsurf->workspace_transform.ptr.link);
 
 		animate_workspace_change(shell, index, from, to);
 	}
@@ -1434,8 +1434,8 @@ shell_unset_fullscreen(struct shell_surface *shsurf)
 	}
 	shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
 	shsurf->fullscreen.framerate = 0;
-	wl_list_remove(&shsurf->fullscreen.transform.link);
-	wl_list_init(&shsurf->fullscreen.transform.link);
+	wl_list_remove(&shsurf->fullscreen.transform.ptr.link);
+	wl_list_init(&shsurf->fullscreen.transform.ptr.link);
 	if (shsurf->fullscreen.black_surface)
 		weston_surface_destroy(shsurf->fullscreen.black_surface);
 	shsurf->fullscreen.black_surface = NULL;
@@ -1444,7 +1444,7 @@ shell_unset_fullscreen(struct shell_surface *shsurf)
 				    shsurf->saved_x, shsurf->saved_y);
 	if (shsurf->saved_rotation_valid) {
 		wl_list_insert(&shsurf->surface->geometry.transformation_list,
-        	               &shsurf->rotation.transform.link);
+        	               &shsurf->rotation.transform.ptr.link);
 		shsurf->saved_rotation_valid = false;
 	}
 
@@ -1508,9 +1508,9 @@ set_surface_type(struct shell_surface *shsurf)
 		shsurf->saved_y = surface->geometry.y;
 		shsurf->saved_position_valid = true;
 
-		if (!wl_list_empty(&shsurf->rotation.transform.link)) {
-			wl_list_remove(&shsurf->rotation.transform.link);
-			wl_list_init(&shsurf->rotation.transform.link);
+		if (!wl_list_empty(&shsurf->rotation.transform.ptr.link)) {
+			wl_list_remove(&shsurf->rotation.transform.ptr.link);
+			wl_list_init(&shsurf->rotation.transform.ptr.link);
 			weston_surface_geometry_dirty(shsurf->surface);
 			shsurf->saved_rotation_valid = true;
 		}
@@ -1686,9 +1686,9 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
 				(float) surface->geometry.height;
 
 		weston_matrix_scale(matrix, scale, scale, 1);
-		wl_list_remove(&shsurf->fullscreen.transform.link);
+		wl_list_remove(&shsurf->fullscreen.transform.ptr.link);
 		wl_list_insert(&surface->geometry.transformation_list,
-			       &shsurf->fullscreen.transform.link);
+			       &shsurf->fullscreen.transform.ptr.link);
 		x = output->x + (output->width - surface->geometry.width * scale) / 2;
 		y = output->y + (output->height - surface->geometry.height * scale) / 2;
 		weston_surface_set_position(surface, x, y);
@@ -1881,7 +1881,7 @@ shell_map_popup(struct shell_surface *shsurf)
 			parent->geometry.y;
 	}
 	wl_list_insert(es->geometry.transformation_list.prev,
-		       &shsurf->popup.parent_transform.link);
+		       &shsurf->popup.parent_transform.ptr.link);
 
 	shsurf->popup.initial_up = 0;
 	weston_surface_set_position(es, shsurf->popup.x, shsurf->popup.y);
@@ -2018,7 +2018,7 @@ create_shell_surface(void *shell, struct weston_surface *surface,
 	shsurf->fullscreen.framerate = 0;
 	shsurf->fullscreen.black_surface = NULL;
 	shsurf->ping_timer = NULL;
-	wl_list_init(&shsurf->fullscreen.transform.link);
+	wl_list_init(&shsurf->fullscreen.transform.ptr.link);
 
 	wl_signal_init(&shsurf->resource.destroy_signal);
 	shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy;
@@ -2029,10 +2029,15 @@ create_shell_surface(void *shell, struct weston_surface *surface,
 	wl_list_init(&shsurf->link);
 
 	/* empty when not in use */
-	wl_list_init(&shsurf->rotation.transform.link);
+	wl_list_init(&shsurf->rotation.transform.ptr.link);
+	weston_transform_init(&shsurf->rotation.transform);
 	weston_matrix_init(&shsurf->rotation.rotation);
 
-	wl_list_init(&shsurf->workspace_transform.link);
+	weston_transform_init(&shsurf->popup.parent_transform);
+	weston_transform_init(&shsurf->fullscreen.transform);
+
+	wl_list_init(&shsurf->workspace_transform.ptr.link);
+	weston_transform_init(&shsurf->workspace_transform);
 
 	shsurf->type = SHELL_SURFACE_NONE;
 	shsurf->next_type = SHELL_SURFACE_NONE;
@@ -2497,7 +2502,7 @@ rotate_grab_motion(struct wl_pointer_grab *grab,
 	dy = wl_fixed_to_double(pointer->y) - rotate->center.y;
 	r = sqrtf(dx * dx + dy * dy);
 
-	wl_list_remove(&shsurf->rotation.transform.link);
+	wl_list_remove(&shsurf->rotation.transform.ptr.link);
 	weston_surface_geometry_dirty(shsurf->surface);
 
 	if (r > 20.0f) {
@@ -2518,9 +2523,9 @@ rotate_grab_motion(struct wl_pointer_grab *grab,
 
 		wl_list_insert(
 			&shsurf->surface->geometry.transformation_list,
-			&shsurf->rotation.transform.link);
+			&shsurf->rotation.transform.ptr.link);
 	} else {
-		wl_list_init(&shsurf->rotation.transform.link);
+		wl_list_init(&shsurf->rotation.transform.ptr.link);
 		weston_matrix_init(&shsurf->rotation.rotation);
 		weston_matrix_init(&rotate->rotation);
 	}
diff --git a/src/util.c b/src/util.c
index bae1bb9..91c83a6 100644
--- a/src/util.c
+++ b/src/util.c
@@ -115,7 +115,7 @@ weston_surface_animation_destroy(struct weston_surface_animation *animation)
 {
 	wl_list_remove(&animation->animation.link);
 	wl_list_remove(&animation->listener.link);
-	wl_list_remove(&animation->transform.link);
+	wl_list_remove(&animation->transform.ptr.link);
 	weston_surface_geometry_dirty(animation->surface);
 	if (animation->done)
 		animation->done(animation, animation->data);
@@ -177,8 +177,9 @@ weston_surface_animation_run(struct weston_surface *surface,
 	animation->start = start;
 	animation->stop = stop;
 	weston_matrix_init(&animation->transform.matrix);
+	weston_transform_init(&animation->transform);
 	wl_list_insert(&surface->geometry.transformation_list,
-		       &animation->transform.link);
+		       &animation->transform.ptr.link);
 	weston_spring_init(&animation->spring, 200.0, 0.0, 1.0);
 	animation->spring.friction = 700;
 	animation->animation.frame_counter = 0;
-- 
1.7.8.6



More information about the wayland-devel mailing list