[weston,v2,06/20] pixman-renderer: Use output->matrix for region transformations and enable output zoom

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

Details

Message ID 1413474938-2407-7-git-send-email-derekf@osg.samsung.com
State Changes Requested
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/pixman-renderer.c | 70 +++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 10 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
index 18b6476..d3650d1 100644
--- a/src/pixman-renderer.c
+++ b/src/pixman-renderer.c
@@ -128,12 +128,68 @@  pixman_renderer_read_pixels(struct weston_output *output,
 }
 
 static void
+weston_matrix_transform_region(pixman_region32_t *dest,
+			       struct weston_matrix *matrix,
+			       pixman_region32_t *src)
+{
+	pixman_box32_t *src_rects, *dest_rects;
+	int nrects, i;
+
+	src_rects = pixman_region32_rectangles(src, &nrects);
+	dest_rects = malloc(nrects * sizeof(*dest_rects));
+	if (!dest_rects)
+		return;
+	
+	for (i = 0; i < nrects; i++) {
+		struct weston_vector vec1 = {{
+			src_rects[i].x1, src_rects[i].y1, 0, 1
+		}};
+		weston_matrix_transform(matrix, &vec1);
+		vec1.f[0] /= vec1.f[3];
+		vec1.f[1] /= vec1.f[3];
+
+		struct weston_vector vec2 = {{
+			src_rects[i].x2, src_rects[i].y2, 0, 1
+		}};
+		weston_matrix_transform(matrix, &vec2);
+		vec2.f[0] /= vec2.f[3];
+		vec2.f[1] /= vec2.f[3];
+
+		if (vec1.f[0] < vec2.f[0]) {
+			dest_rects[i].x1 = floor(vec1.f[0]);
+			dest_rects[i].x2 = ceil(vec2.f[0]);
+		} else {
+			dest_rects[i].x1 = floor(vec2.f[0]);
+			dest_rects[i].x2 = ceil(vec1.f[0]);
+		}
+
+
+		if (vec1.f[1] < vec2.f[1]) {
+			dest_rects[i].y1 = floor(vec1.f[1]);
+			dest_rects[i].y2 = ceil(vec2.f[1]);
+		} else {
+			dest_rects[i].y1 = floor(vec2.f[1]);
+			dest_rects[i].y2 = ceil(vec1.f[1]);
+		}
+	}
+
+	pixman_region32_clear(dest);
+	pixman_region32_init_rects(dest, dest_rects, nrects);
+	free(dest_rects);
+}
+
+static void
 region_global_to_output(struct weston_output *output, pixman_region32_t *region)
 {
-	pixman_region32_translate(region, -output->x, -output->y);
-	weston_transformed_region(output->width, output->height,
-				  output->transform, output->current_scale,
-				  region, region);
+	if (output->zoom.active) {
+		weston_matrix_transform_region(region, &output->matrix, region);
+	} else {
+		pixman_region32_translate(region, -output->x, -output->y);
+		weston_transformed_region(output->width, output->height,
+					  output->transform,
+					  output->current_scale,
+					  region, region);
+	}
 }
 
 #define D2F(v) pixman_double_to_fixed((double)v)
@@ -270,7 +326,6 @@  static void
 draw_view(struct weston_view *ev, struct weston_output *output,
 	  pixman_region32_t *damage) /* in global coordinates */
 {
-	static int zoom_logged = 0;
 	struct pixman_surface_state *ps = get_surface_state(ev->surface);
 	/* repaint bounding region in global coordinates: */
 	pixman_region32_t repaint;
@@ -289,11 +344,6 @@  draw_view(struct weston_view *ev, struct weston_output *output,
 	if (!pixman_region32_not_empty(&repaint))
 		goto out;
 
-	if (output->zoom.active && !zoom_logged) {
-		weston_log("pixman renderer does not support zoom\n");
-		zoom_logged = 1;
-	}
-
 	/* TODO: Implement repaint_region_complex() using pixman_composite_trapezoids() */
 	if (ev->alpha != 1.0 ||
 	    (ev->transform.enabled &&