[PATCH 3/4 v2 weston] add surface_attach2 to support resize

Zhao Halley halley.zhao at intel.com
Thu Jun 7 02:42:53 PDT 2012


---
 src/compositor-drm.c |   34 +++++++++---------
 src/compositor.c     |   91 +++++++++++++++++++++++++++++++++++++------------
 src/compositor.h     |    9 ++++-
 src/shell.c          |   51 +++++++++++++++-------------
 src/util.c           |    8 ++--
 5 files changed, 124 insertions(+), 69 deletions(-)
 mode change 100644 => 100755 src/compositor.c
 mode change 100644 => 100755 src/compositor.h
 mode change 100644 => 100755 src/shell.c
 mode change 100644 => 100755 src/util.c

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index cb55753..0b84950 100755
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -242,16 +242,16 @@ drm_output_prepare_scanout_surface(struct drm_output *output)
 
 	if (es->geometry.x != output->base.x ||
 	    es->geometry.y != output->base.y ||
-	    es->geometry.width != output->base.current->width ||
-	    es->geometry.height != output->base.current->height ||
+	    es->geometry.dst_width != output->base.current->width ||
+	    es->geometry.dst_height != output->base.current->height ||
 	    es->transform.enabled ||
 	    es->image == EGL_NO_IMAGE_KHR)
 		return -1;
 
 	bo = gbm_bo_create_from_egl_image(c->gbm,
 					  c->base.display, es->image,
-					  es->geometry.width,
-					  es->geometry.height,
+					  es->geometry.src_width,
+					  es->geometry.src_height,
 					  GBM_BO_USE_SCANOUT);
 
 	/* Need to verify output->region contained in surface opaque
@@ -538,12 +538,12 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
 		return -1;
 
     // filter out cursor
-    if (es->geometry.width == 32 && es->geometry.height == 32) {
+    if (es->geometry.src_width == 32 && es->geometry.src_height == 32) {
         return -1;
     }
 
     // filter out shell and background which width is 1366
-    if (es->geometry.width >1360) {
+    if (es->geometry.src_width >1360) {
         return -1;
     }
 
@@ -563,7 +563,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
 		return -1;
 
 	bo = gbm_bo_create_from_egl_image(c->gbm, c->base.display, es->image,
-					  es->geometry.width, es->geometry.height,
+					  es->geometry.src_width, es->geometry.src_height,
 					  GBM_BO_USE_SCANOUT);
 	format = gbm_bo_get_format(bo);
 	handle = gbm_bo_get_handle(bo).s32;
@@ -581,7 +581,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
 	pitches[0] = stride;
 	offsets[0] = 0;
 
-	ret = drmModeAddFB2(c->drm.fd, es->geometry.width, es->geometry.height,
+	ret = drmModeAddFB2(c->drm.fd, es->geometry.src_width, es->geometry.src_height,
 			    format, handles, pitches, offsets,
 			    &fb_id, 0);
 	if (ret) {
@@ -595,7 +595,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
 		pixman_region32_fini(&old_surf->damage);
 		pixman_region32_init_rect(&old_surf->damage,
 					  old_surf->geometry.x, old_surf->geometry.y,
-					  old_surf->geometry.width, old_surf->geometry.height);
+					  old_surf->geometry.dst_width, old_surf->geometry.dst_height);
 	}
 
 	s->pending_fb_id = fb_id;
@@ -632,12 +632,12 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
 #else
     s->dest_x = es->geometry.x;
     s->dest_y = es->geometry.y;
-    s->dest_w = es->geometry.width;
-    s->dest_h = es->geometry.height;
+    s->dest_w = es->geometry.dst_width;
+    s->dest_h = es->geometry.dst_height;
     s->src_x  = 0;
     s->src_y  = 0;
-    s->src_w  = es->geometry.width;
-    s->src_h  = es->geometry.height;
+    s->src_w  = es->geometry.src_width;
+    s->src_h  = es->geometry.src_height;
     
 #endif
 
@@ -766,8 +766,8 @@ drm_output_set_cursor(struct weston_output *output_base,
 	    !wl_buffer_is_shm(eid->sprite->buffer))
 		goto out;
 
-	if (eid->sprite->geometry.width > 64 ||
-	    eid->sprite->geometry.height > 64)
+	if (eid->sprite->geometry.src_width > 64 ||
+	    eid->sprite->geometry.src_height > 64)
 		goto out;
 
 	output->current_cursor ^= 1;
@@ -779,9 +779,9 @@ drm_output_set_cursor(struct weston_output *output_base,
 	d = (unsigned char *) buf;
 	stride = wl_shm_buffer_get_stride(eid->sprite->buffer);
 	s = wl_shm_buffer_get_data(eid->sprite->buffer);
-	end = s + stride * eid->sprite->geometry.height;
+	end = s + stride * eid->sprite->geometry.src_height;
 	while (s < end) {
-		memcpy(d, s, eid->sprite->geometry.width * 4);
+		memcpy(d, s, eid->sprite->geometry.src_width * 4);
 		s += stride;
 		d += 64 * 4;
 	}
diff --git a/src/compositor.c b/src/compositor.c
old mode 100644
new mode 100755
index 4cb117a..b088e4d
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -351,8 +351,8 @@ weston_surface_update_transform_disable(struct weston_surface *surface)
 	pixman_region32_init_rect(&surface->transform.boundingbox,
 				  surface->geometry.x,
 				  surface->geometry.y,
-				  surface->geometry.width,
-				  surface->geometry.height);
+				  surface->geometry.dst_width,
+				  surface->geometry.dst_height);
 
 	if (surface->alpha == 255) {
 		pixman_region32_copy(&surface->transform.opaque,
@@ -387,8 +387,8 @@ weston_surface_update_transform_enable(struct weston_surface *surface)
 		return -1;
 	}
 
-	surface_compute_bbox(surface, 0, 0, surface->geometry.width,
-			     surface->geometry.height,
+	surface_compute_bbox(surface, 0, 0, surface->geometry.dst_width,
+			     surface->geometry.dst_height,
 			     &surface->transform.boundingbox);
 
 	return 0;
@@ -410,8 +410,8 @@ weston_surface_update_transform(struct weston_surface *surface)
 
 	if (region_is_undefined(&surface->input))
 		pixman_region32_init_rect(&surface->input, 0, 0, 
-					  surface->geometry.width,
-					  surface->geometry.height);
+					  surface->geometry.dst_width,
+					  surface->geometry.dst_height);
 
 	/* transform.position is always in transformation_list */
 	if (surface->geometry.transformation_list.next ==
@@ -563,10 +563,22 @@ WL_EXPORT void
 weston_surface_configure(struct weston_surface *surface,
 			 GLfloat x, GLfloat y, int width, int height)
 {
+	weston_surface_configure2(surface, x, y, 
+			 width, height, width, height);
+}
+
+WL_EXPORT void
+weston_surface_configure2(struct weston_surface *surface,
+			 GLfloat x, GLfloat y, 
+			 int src_width, int src_height,
+			 int dst_width, int dst_height)
+{
 	surface->geometry.x = x;
 	surface->geometry.y = y;
-	surface->geometry.width = width;
-	surface->geometry.height = height;
+	surface->geometry.src_width  = src_width;
+	surface->geometry.src_height = src_height;
+	surface->geometry.dst_width  = dst_width;
+	surface->geometry.dst_height = dst_height;
 	surface->geometry.dirty = 1;
 }
 
@@ -738,8 +750,8 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
 	wl_signal_add(&es->buffer->resource.destroy_signal,
 		      &es->buffer_destroy_listener);
 
-	if (es->geometry.width != buffer->width ||
-	    es->geometry.height != buffer->height) {
+	if (es->geometry.src_width != buffer->width ||
+	    es->geometry.src_height != buffer->height) {
 		undef_region(&es->input);
 		pixman_region32_fini(&es->opaque);
 		pixman_region32_init(&es->opaque);
@@ -789,7 +801,7 @@ texture_region(struct weston_surface *es, pixman_region32_t *region)
 	v = wl_array_add(&ec->vertices, n * 16 * sizeof *v);
 	p = wl_array_add(&ec->indices, n * 6 * sizeof *p);
 	inv_width = 1.0 / es->pitch;
-	inv_height = 1.0 / es->geometry.height;
+	inv_height = 1.0 / es->geometry.src_height;
 
 	for (i = 0; i < n; i++, v += 16, p += 6) {
 		surface_from_global_float(es, rectangles[i].x1,
@@ -865,7 +877,7 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output,
 	glUniform1f(es->shader->brightness_uniform, es->brightness / 255.0);
 	glUniform1f(es->shader->saturation_uniform, es->saturation / 255.0);
 	glUniform1f(es->shader->texwidth_uniform,
-		    (GLfloat)es->geometry.width / es->pitch);
+		    (GLfloat)es->geometry.src_width / es->pitch); // XXXX src_width, right?
 
 	if (es->transform.enabled || output->zoom.active)
 		filter = GL_LINEAR;
@@ -1247,9 +1259,10 @@ weston_surface_assign_output(struct weston_surface *es)
 }
 
 static void
-surface_attach(struct wl_client *client,
-	       struct wl_resource *resource,
-	       struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
+surface_attach2(struct wl_client *client,
+		   struct wl_resource *resource,
+		   struct wl_resource *buffer_resource, 
+		   int32_t sx, int32_t sy, int32_t dst_w, int32_t dst_h)
 {
 	struct weston_surface *es = resource->data;
 	struct wl_buffer *buffer = NULL;
@@ -1257,6 +1270,10 @@ surface_attach(struct wl_client *client,
 	if (buffer_resource)
 		buffer = buffer_resource->data;
 
+	
+	es->geometry.dst_width = dst_w;
+	es->geometry.dst_height = dst_h;
+	   
 	weston_surface_attach(&es->surface, buffer);
 
 	if (buffer && es->configure)
@@ -1264,6 +1281,28 @@ surface_attach(struct wl_client *client,
 }
 
 static void
+surface_attach(struct wl_client *client,
+		   struct wl_resource *resource,
+		   struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
+{
+	struct wl_buffer *buffer = NULL;
+
+	if (buffer_resource)
+		buffer = buffer_resource->data;
+
+	if (buffer) {
+		surface_attach2(client, resource, buffer_resource, 
+					sx, sy, buffer->width, buffer->height);
+	}
+	else {
+		surface_attach2(client, resource, buffer_resource, 
+				sx, sy, 0, 0);
+	}
+
+}
+
+
+static void
 texture_set_subimage(struct weston_surface *surface,
 		     int32_t x, int32_t y, int32_t width, int32_t height)
 {
@@ -1299,8 +1338,13 @@ surface_damage(struct wl_client *client,
 
 	weston_surface_damage_rectangle(es, x, y, width, height);
 
-	if (es->buffer && wl_buffer_is_shm(es->buffer))
-		texture_set_subimage(es, x, y, width, height);
+	if (es->buffer && wl_buffer_is_shm(es->buffer)) {
+        int32_t src_x = x*es->geometry.dst_width/es->geometry.src_width;
+        int32_t src_y = y*es->geometry.dst_width/es->geometry.src_width;
+        int32_t src_w = width*es->geometry.dst_width/es->geometry.src_width;
+        int32_t src_h = height*es->geometry.dst_width/es->geometry.src_width;
+		texture_set_subimage(es, src_x, src_y, src_w, src_h);
+    }
 }
 
 static void
@@ -1354,8 +1398,8 @@ surface_set_opaque_region(struct wl_client *client,
 	if (region_resource) {
 		region = region_resource->data;
 		pixman_region32_init_rect(&surface->opaque, 0, 0,
-					  surface->geometry.width,
-					  surface->geometry.height);
+					  surface->geometry.dst_width,
+					  surface->geometry.dst_height);
 		pixman_region32_intersect(&surface->opaque,
 					  &surface->opaque, &region->region);
 	} else {
@@ -1376,14 +1420,14 @@ surface_set_input_region(struct wl_client *client,
 	if (region_resource) {
 		region = region_resource->data;
 		pixman_region32_init_rect(&surface->input, 0, 0,
-					  surface->geometry.width,
-					  surface->geometry.height);
+					  surface->geometry.dst_width,
+					  surface->geometry.dst_height);
 		pixman_region32_intersect(&surface->input,
 					  &surface->input, &region->region);
 	} else {
 		pixman_region32_init_rect(&surface->input, 0, 0,
-					  surface->geometry.width,
-					  surface->geometry.height);
+					  surface->geometry.dst_width,
+					  surface->geometry.dst_height);
 	}
 
 	weston_compositor_schedule_repaint(surface->compositor);
@@ -1392,6 +1436,7 @@ surface_set_input_region(struct wl_client *client,
 static const struct wl_surface_interface surface_interface = {
 	surface_destroy,
 	surface_attach,
+	surface_attach2,
 	surface_damage,
 	surface_frame,
 	surface_set_opaque_region,
diff --git a/src/compositor.h b/src/compositor.h
old mode 100644
new mode 100755
index fbd3b54..5b4d904
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -336,7 +336,8 @@ struct weston_surface {
 	 */
 	struct {
 		GLfloat x, y; /* surface translation on display */
-		int32_t width, height;
+		int32_t src_width, src_height; /* client data/buffer size */
+        int32_t dst_width, dst_height; /* target region on display in case resize is required */
 
 		/* struct weston_transform */
 		struct wl_list transformation_list;
@@ -516,6 +517,12 @@ weston_surface_configure(struct weston_surface *surface,
 			 GLfloat x, GLfloat y, int width, int height);
 
 void
+weston_surface_configure2(struct weston_surface *surface,
+			 GLfloat x, GLfloat y, 
+			 int src_width, int src_height,
+			 int dst_width, int dst_height);
+
+void
 weston_surface_restack(struct weston_surface *surface, struct wl_list *below);
 
 void
diff --git a/src/shell.c b/src/shell.c
old mode 100644
new mode 100755
index a44074d..5665b08
--- a/src/shell.c
+++ b/src/shell.c
@@ -325,8 +325,9 @@ move_grab_motion(struct wl_pointer_grab *grab,
 
 	es = shsurf->surface;
 
-	weston_surface_configure(es, dx, dy,
-				 es->geometry.width, es->geometry.height);
+	weston_surface_configure2(es, dx, dy,
+				 es->geometry.src_width, es->geometry.src_height,
+				 es->geometry.dst_width, es->geometry.dst_height);
 }
 
 static void
@@ -628,8 +629,8 @@ weston_surface_resize(struct shell_surface *shsurf,
 	shell_grab_init(&resize->base, &resize_grab_interface, shsurf);
 
 	resize->edges = edges;
-	resize->width = shsurf->surface->geometry.width;
-	resize->height = shsurf->surface->geometry.height;
+	resize->width = shsurf->surface->geometry.dst_width;
+	resize->height = shsurf->surface->geometry.dst_height;
 
 	wl_input_device_start_pointer_grab(&wd->input_device,
 					   &resize->base.grab);
@@ -857,7 +858,7 @@ get_output_panel_height(struct desktop_shell *shell,
 
 	wl_list_for_each(priv, &shell->panels, link) {
 		if (priv->output == output) {
-			panel_height = priv->surface->geometry.height;
+			panel_height = priv->surface->geometry.dst_height;
 			break;
 		}
 	}
@@ -946,7 +947,7 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
 	case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE:
 		matrix = &shsurf->fullscreen.transform.matrix;
 		weston_matrix_init(matrix);
-		scale = (float)output->current->width/(float)surface->geometry.width;
+		scale = (float)output->current->width/(float)surface->geometry.src_width;
 		weston_matrix_scale(matrix, scale, scale, 1);
 		wl_list_remove(&shsurf->fullscreen.transform.link);
 		wl_list_insert(surface->geometry.transformation_list.prev,
@@ -956,8 +957,8 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
 	case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER:
 		if (shell_surface_is_top_fullscreen(shsurf)) {
 			struct weston_mode mode = {0, 
-				surface->geometry.width,
-				surface->geometry.height,
+				surface->geometry.src_width,
+				surface->geometry.src_height,
 				shsurf->fullscreen.framerate};
 
 			if (weston_output_switch_mode(output, &mode) == 0) {
@@ -1563,16 +1564,16 @@ resize_binding(struct wl_input_device *device, uint32_t time,
 				   wl_fixed_to_int(device->grab_y),
 				   &x, &y);
 
-	if (x < surface->geometry.width / 3)
+	if (x < surface->geometry.src_width / 3)
 		edges |= WL_SHELL_SURFACE_RESIZE_LEFT;
-	else if (x < 2 * surface->geometry.width / 3)
+	else if (x < 2 * surface->geometry.src_width / 3)
 		edges |= 0;
 	else
 		edges |= WL_SHELL_SURFACE_RESIZE_RIGHT;
 
-	if (y < surface->geometry.height / 3)
+	if (y < surface->geometry.src_height / 3)
 		edges |= WL_SHELL_SURFACE_RESIZE_TOP;
-	else if (y < 2 * surface->geometry.height / 3)
+	else if (y < 2 * surface->geometry.src_height / 3)
 		edges |= 0;
 	else
 		edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
@@ -1675,8 +1676,8 @@ rotate_grab_motion(struct wl_pointer_grab *grab,
 
 	surface = shsurf->surface;
 
-	cx = 0.5f * surface->geometry.width;
-	cy = 0.5f * surface->geometry.height;
+	cx = 0.5f * surface->geometry.dst_width;
+	cy = 0.5f * surface->geometry.dst_height;
 
 	dx = wl_fixed_to_double(device->x) - rotate->center.x;
 	dy = wl_fixed_to_double(device->y) - rotate->center.y;
@@ -1789,8 +1790,8 @@ rotate_binding(struct wl_input_device *device, uint32_t time,
 	shell_grab_init(&rotate->base, &rotate_grab_interface, surface);
 
 	weston_surface_to_global(surface->surface,
-				 surface->surface->geometry.width / 2,
-				 surface->surface->geometry.height / 2,
+				 surface->surface->geometry.dst_width / 2,
+				 surface->surface->geometry.dst_height / 2,
 				 &rotate->center.x, &rotate->center.y);
 
 	wl_input_device_start_pointer_grab(device, &rotate->base.grab);
@@ -1985,8 +1986,8 @@ static void
 center_on_output(struct weston_surface *surface, struct weston_output *output)
 {
 	struct weston_mode *mode = output->current;
-	GLfloat x = (mode->width - surface->geometry.width) / 2;
-	GLfloat y = (mode->height - surface->geometry.height) / 2;
+	GLfloat x = (mode->width - surface->geometry.dst_width) / 2;
+	GLfloat y = (mode->height - surface->geometry.dst_height) / 2;
 
 	weston_surface_set_position(surface, output->x + x, output->y + y);
 }
@@ -2005,8 +2006,8 @@ map(struct desktop_shell *shell, struct weston_surface *surface,
 	if (shsurf)
 		surface_type = shsurf->type;
 
-	surface->geometry.width = width;
-	surface->geometry.height = height;
+	surface->geometry.src_width = width;
+	surface->geometry.src_height = height;
 	surface->geometry.dirty = 1;
 
 	/* initial positioning, see also configure() */
@@ -2131,8 +2132,10 @@ configure(struct desktop_shell *shell, struct weston_surface *surface,
 
 	surface->geometry.x = x;
 	surface->geometry.y = y;
-	surface->geometry.width = width;
-	surface->geometry.height = height;
+	surface->geometry.src_width = width;
+	surface->geometry.src_height = height;
+	surface->geometry.dst_width = width;
+	surface->geometry.dst_height = height;
 	surface->geometry.dirty = 1;
 
 	switch (surface_type) {
@@ -2182,8 +2185,8 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
 	if (!weston_surface_is_mapped(es)) {
 		map(shell, es, es->buffer->width, es->buffer->height, sx, sy);
 	} else if (type_changed || sx != 0 || sy != 0 ||
-		   es->geometry.width != es->buffer->width ||
-		   es->geometry.height != es->buffer->height) {
+		   es->geometry.src_width != es->buffer->width ||
+		   es->geometry.src_height != es->buffer->height) {
 		GLfloat from_x, from_y;
 		GLfloat to_x, to_y;
 
diff --git a/src/util.c b/src/util.c
old mode 100644
new mode 100755
index c789d29..cd3fa2a
--- a/src/util.c
+++ b/src/util.c
@@ -146,12 +146,12 @@ weston_zoom_frame(struct weston_animation *animation,
 		(zoom->stop - zoom->start) * zoom->spring.current;
 	weston_matrix_init(&zoom->transform.matrix);
 	weston_matrix_translate(&zoom->transform.matrix,
-				-0.5f * es->geometry.width,
-				-0.5f * es->geometry.height, 0);
+				-0.5f * es->geometry.src_width,
+				-0.5f * es->geometry.src_height, 0);
 	weston_matrix_scale(&zoom->transform.matrix, scale, scale, scale);
 	weston_matrix_translate(&zoom->transform.matrix,
-				0.5f * es->geometry.width,
-				0.5f * es->geometry.height, 0);
+				0.5f * es->geometry.src_width,
+				0.5f * es->geometry.src_height, 0);
 
 	es->alpha = zoom->spring.current * 255;
 	if (es->alpha > 255)
-- 
1.7.5.4



More information about the wayland-devel mailing list