[PATCH weston 1/3] compositor-drm: Support overlays with transformed buffers

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Wed Dec 5 05:14:04 PST 2012


Make overlays work when the client uses a buffer with the same
transformation as the output.

In order to calculate the destination rectangle, the same logic in
weston_surface_to_buffer_float() is needed, but with the output
dimensions instead. For that reason, this patch generalizes this
function into weston_transformed_{coord,rect} and moves it to util.c.
The surface functions are then implemented using those.

---
Hi,

I'm not sure if its worth keeping weston_surface_to_buffer_rect(),
since this just reduces a few lines in one place in gl-renderer.c.
---
 src/compositor-drm.c |   32 ++++++++++++++-------
 src/compositor.c     |   66 +++++---------------------------------------
 src/compositor.h     |    9 ++++++
 src/util.c           |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 113 insertions(+), 69 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 24a71f1..2e2b67f 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -588,11 +588,11 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
 	int found = 0;
 	struct gbm_bo *bo;
 	pixman_region32_t dest_rect, src_rect;
-	pixman_box32_t *box;
+	pixman_box32_t *box, tbox;
 	uint32_t format;
 	wl_fixed_t sx1, sy1, sx2, sy2;
 
-	if (output_base->transform != WL_OUTPUT_TRANSFORM_NORMAL)
+	if (es->buffer_transform != output_base->transform)
 		return NULL;
 
 	if (c->sprites_are_broken)
@@ -661,10 +661,13 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
 				  &output_base->region);
 	pixman_region32_translate(&dest_rect, -output_base->x, -output_base->y);
 	box = pixman_region32_extents(&dest_rect);
-	s->dest_x = box->x1;
-	s->dest_y = box->y1;
-	s->dest_w = box->x2 - box->x1;
-	s->dest_h = box->y2 - box->y1;
+	tbox = weston_transformed_rect(output_base->width,
+				       output_base->height,
+				       output_base->transform, *box);
+	s->dest_x = tbox.x1;
+	s->dest_y = tbox.y1;
+	s->dest_w = tbox.x2 - tbox.x1;
+	s->dest_h = tbox.y2 - tbox.y1;
 	pixman_region32_fini(&dest_rect);
 
 	pixman_region32_init(&src_rect);
@@ -690,10 +693,19 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
 	if (sy2 > wl_fixed_from_int(es->geometry.height))
 		sy2 = wl_fixed_from_int(es->geometry.height);
 
-	s->src_x = sx1 << 8;
-	s->src_y = sy1 << 8;
-	s->src_w = (sx2 - sx1) << 8;
-	s->src_h = (sy2 - sy1) << 8;
+	tbox.x1 = sx1;
+	tbox.y1 = sy1;
+	tbox.x2 = sx2;
+	tbox.y2 = sy2;
+
+	tbox = weston_transformed_rect(wl_fixed_from_int(es->geometry.width),
+				       wl_fixed_from_int(es->geometry.height),
+				       es->buffer_transform, tbox);
+
+	s->src_x = tbox.x1 << 8;
+	s->src_y = tbox.y1 << 8;
+	s->src_w = (tbox.x2 - tbox.x1) << 8;
+	s->src_h = (tbox.y2 - tbox.y1) << 8;
 	pixman_region32_fini(&src_rect);
 
 	return &s->plane;
diff --git a/src/compositor.c b/src/compositor.c
index 565212d..9044007 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -314,71 +314,19 @@ WL_EXPORT void
 weston_surface_to_buffer_float(struct weston_surface *surface,
 			       float sx, float sy, float *bx, float *by)
 {
-	switch (surface->buffer_transform) {
-	case WL_OUTPUT_TRANSFORM_NORMAL:
-	default:
-		*bx = sx;
-		*by = sy;
-		break;
-	case WL_OUTPUT_TRANSFORM_FLIPPED:
-		*bx = surface->geometry.width - sx;
-		*by = sy;
-		break;
-	case WL_OUTPUT_TRANSFORM_90:
-		*bx = surface->geometry.height - sy;
-		*by = sx;
-		break;
-	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-		*bx = surface->geometry.height - sy;
-		*by = surface->geometry.width - sx;
-		break;
-	case WL_OUTPUT_TRANSFORM_180:
-		*bx = surface->geometry.width - sx;
-		*by = surface->geometry.height - sy;
-		break;
-	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
-		*bx = sx;
-		*by = surface->geometry.height - sy;
-		break;
-	case WL_OUTPUT_TRANSFORM_270:
-		*bx = sy;
-		*by = surface->geometry.width - sx;
-		break;
-	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-		*bx = sy;
-		*by = sx;
-		break;
-	}
+	weston_transformed_coord(surface->geometry.width,
+				 surface->geometry.height,
+				 surface->buffer_transform,
+				 sx, sy, bx, by);
 }
 
 WL_EXPORT pixman_box32_t
 weston_surface_to_buffer_rect(struct weston_surface *surface,
 			      pixman_box32_t rect)
 {
-	float x1, x2, y1, y2;
-
-	pixman_box32_t ret;
-
-	weston_surface_to_buffer_float(surface, rect.x1, rect.y1, &x1, &y1);
-	weston_surface_to_buffer_float(surface, rect.x2, rect.y2, &x2, &y2);
-
-	if (x1 <= x2) {
-		ret.x1 = x1;
-		ret.x2 = x2;
-	} else {
-		ret.x1 = x2;
-		ret.x2 = x1;
-	}
-
-	if (y1 <= y2) {
-		ret.y1 = y1;
-		ret.y2 = y2;
-	} else {
-		ret.y1 = y2;
-		ret.y2 = y1;
-	}
-
-	return ret;
+	return weston_transformed_rect(surface->geometry.width,
+				       surface->geometry.height,
+				       surface->buffer_transform, rect);
 }
 
 WL_EXPORT void
diff --git a/src/compositor.h b/src/compositor.h
index 2547da1..27598bd 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -824,4 +824,13 @@ backend_init(struct wl_display *display, int argc, char *argv[],
 int
 module_init(struct weston_compositor *compositor);
 
+void
+weston_transformed_coord(int width, int height,
+			 enum wl_output_transform transform,
+			 float sx, float sy, float *bx, float *by);
+pixman_box32_t
+weston_transformed_rect(int width, int height,
+			enum wl_output_transform transform,
+			pixman_box32_t rect);
+
 #endif
diff --git a/src/util.c b/src/util.c
index 2134392..5f8e9c8 100644
--- a/src/util.c
+++ b/src/util.c
@@ -557,3 +557,78 @@ weston_environment_get_fd(const char *env)
 
 	return fd;
 }
+
+WL_EXPORT void
+weston_transformed_coord(int width, int height,
+			 enum wl_output_transform transform,
+			 float sx, float sy, float *bx, float *by)
+{
+	switch (transform) {
+	case WL_OUTPUT_TRANSFORM_NORMAL:
+	default:
+		*bx = sx;
+		*by = sy;
+		break;
+	case WL_OUTPUT_TRANSFORM_FLIPPED:
+		*bx = width - sx;
+		*by = sy;
+		break;
+	case WL_OUTPUT_TRANSFORM_90:
+		*bx = height - sy;
+		*by = sx;
+		break;
+	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+		*bx = height - sy;
+		*by = width - sx;
+		break;
+	case WL_OUTPUT_TRANSFORM_180:
+		*bx = width - sx;
+		*by = height - sy;
+		break;
+	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+		*bx = sx;
+		*by = height - sy;
+		break;
+	case WL_OUTPUT_TRANSFORM_270:
+		*bx = sy;
+		*by = width - sx;
+		break;
+	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+		*bx = sy;
+		*by = sx;
+		break;
+	}
+}
+
+WL_EXPORT pixman_box32_t
+weston_transformed_rect(int width, int height,
+			enum wl_output_transform transform,
+			pixman_box32_t rect)
+{
+	float x1, x2, y1, y2;
+
+	pixman_box32_t ret;
+
+	weston_transformed_coord(width, height, transform,
+				 rect.x1, rect.y1, &x1, &y1);
+	weston_transformed_coord(width, height, transform,
+				 rect.x2, rect.y2, &x2, &y2);
+
+	if (x1 <= x2) {
+		ret.x1 = x1;
+		ret.x2 = x2;
+	} else {
+		ret.x1 = x2;
+		ret.x2 = x1;
+	}
+
+	if (y1 <= y2) {
+		ret.y1 = y1;
+		ret.y2 = y2;
+	} else {
+		ret.y1 = y2;
+		ret.y2 = y1;
+	}
+
+	return ret;
+}
-- 
1.7.10.4



More information about the wayland-devel mailing list