pixman-renderer: implement surface scaling and cropping
authorJonny Lamb <jonny.lamb@collabora.co.uk>
Tue, 26 Nov 2013 17:19:47 +0000 (18:19 +0100)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 17 Dec 2013 06:43:27 +0000 (22:43 -0800)
The pixman renderer doesn't use the weston_surface_to_buffer*
functions to alter coordinates depending on buffer transformation,
buffer scaling, and surface scaler (wl_surface_scaler).
pixman_transform_scale() is used instead to perform said
transformations without having to modify each coordinate.

src/pixman-renderer.c

index e854e2a..7a69578 100644 (file)
@@ -256,9 +256,31 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
                                           pixman_double_to_fixed ((double)-ev->geometry.y));
        }
 
+       if (ev->surface->buffer_viewport.scaler_set) {
+               double scaler_x, scaler_y, scaler_width, scaler_height;
+               double ratio_x, ratio_y;
 
-       fw = pixman_int_to_fixed(ev->surface->width);
-       fh = pixman_int_to_fixed(ev->surface->height);
+               scaler_x = wl_fixed_to_double(ev->surface->buffer_viewport.src_x);
+               scaler_y = wl_fixed_to_double(ev->surface->buffer_viewport.src_y);
+               scaler_width = wl_fixed_to_double(ev->surface->buffer_viewport.src_width);
+               scaler_height = wl_fixed_to_double(ev->surface->buffer_viewport.src_height);
+
+               ratio_x = scaler_width / ev->surface->buffer_viewport.dst_width;
+               ratio_y = scaler_height / ev->surface->buffer_viewport.dst_height;
+
+               pixman_transform_scale(&transform, NULL,
+                                      pixman_double_to_fixed(ratio_x),
+                                      pixman_double_to_fixed(ratio_y));
+               pixman_transform_translate(&transform, NULL, pixman_double_to_fixed(scaler_x),
+                                                            pixman_double_to_fixed(scaler_y));
+       }
+
+       pixman_transform_scale(&transform, NULL,
+                              pixman_double_to_fixed(ev->surface->buffer_viewport.scale),
+                              pixman_double_to_fixed(ev->surface->buffer_viewport.scale));
+
+       fw = pixman_int_to_fixed(pixman_image_get_width(ps->image));
+       fh = pixman_int_to_fixed(pixman_image_get_height(ps->image));
 
        switch (ev->surface->buffer_viewport.transform) {
        case WL_OUTPUT_TRANSFORM_FLIPPED:
@@ -294,10 +316,6 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
                break;
        }
 
-       pixman_transform_scale(&transform, NULL,
-                              pixman_double_to_fixed ((double)ev->surface->buffer_viewport.scale),
-                              pixman_double_to_fixed ((double)ev->surface->buffer_viewport.scale));
-
        pixman_image_set_transform(ps->image, &transform);
 
        if (ev->transform.enabled || output->current_scale != ev->surface->buffer_viewport.scale)