[Spice-devel] [PATCH 2/2] Fix scaling with large magnification
Alon Levy
alevy at redhat.com
Tue Aug 31 04:59:30 PDT 2010
----- alexl at redhat.com wrote:
> From: Alexander Larsson <alexl at redhat.com>
>
> When scaling part of an image we need to specify the source
> coordinates in transformed coordinates. For large magnifications this
> means we will get pretty large values.
>
> Now, if e.g. src_x * transform is larger than 32765, then the
> coordinate ends up outside the pixman 16bit image size, so the
> rendering will not work.
>
> The fix is to make the src_x/y offset part of the transformation.
> This means its automatically transformed by the correct scaling, and
> the coordinates passed into pixman are not (typically) over 16bit.
> ---
> common/sw_canvas.c | 36 ++++++++++++++++--------------------
> 1 files changed, 16 insertions(+), 20 deletions(-)
>
> diff --git a/common/sw_canvas.c b/common/sw_canvas.c
> index a92cff6..f579b4c 100644
> --- a/common/sw_canvas.c
> +++ b/common/sw_canvas.c
> @@ -454,7 +454,6 @@ static void __scale_image(SpiceCanvas
> *spice_canvas,
> SwCanvas *canvas = (SwCanvas *)spice_canvas;
> pixman_transform_t transform;
> pixman_fixed_t fsx, fsy;
> - int scaled_src_x, scaled_src_y;
>
> fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
> fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
> @@ -462,6 +461,9 @@ static void __scale_image(SpiceCanvas
> *spice_canvas,
> pixman_image_set_clip_region32(canvas->image, region);
>
> pixman_transform_init_scale(&transform, fsx, fsy);
> + pixman_transform_translate(&transform, NULL,
> + pixman_int_to_fixed (src_x),
> + pixman_int_to_fixed (src_y));
>
> pixman_image_set_transform(src, &transform);
> pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> @@ -472,12 +474,9 @@ static void __scale_image(SpiceCanvas
> *spice_canvas,
> PIXMAN_FILTER_NEAREST :
> PIXMAN_FILTER_GOOD,
> NULL, 0);
>
> - scaled_src_x = ((pixman_fixed_48_16_t)src_x * 65536 + fsx/2 ) /
> fsx;
> - scaled_src_y = ((pixman_fixed_48_16_t)src_y * 65536 + fsy/2 ) /
> fsy;
> -
> pixman_image_composite32(PIXMAN_OP_SRC,
> src, NULL, canvas->image,
> - scaled_src_x, scaled_src_y, /* src */
> + 0, 0, /* src */
> 0, 0, /* mask */
> dest_x, dest_y, /* dst */
> dest_width, dest_height);
> @@ -530,7 +529,6 @@ static void __scale_image_rop(SpiceCanvas
> *spice_canvas,
> pixman_box32_t *rects;
> int n_rects, i;
> pixman_fixed_t fsx, fsy;
> - int scaled_src_x, scaled_src_y;
>
> fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
> fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
> @@ -544,6 +542,9 @@ static void __scale_image_rop(SpiceCanvas
> *spice_canvas,
> pixman_image_set_clip_region32(scaled, region);
>
> pixman_transform_init_scale(&transform, fsx, fsy);
> + pixman_transform_translate(&transform, NULL,
> + pixman_int_to_fixed (src_x),
> + pixman_int_to_fixed (src_y));
>
> pixman_image_set_transform(src, &transform);
> pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> @@ -554,12 +555,9 @@ static void __scale_image_rop(SpiceCanvas
> *spice_canvas,
> PIXMAN_FILTER_NEAREST :
> PIXMAN_FILTER_GOOD,
> NULL, 0);
>
> - scaled_src_x = ((pixman_fixed_48_16_t)src_x * 65536 + fsx/2 ) /
> fsx;
> - scaled_src_y = ((pixman_fixed_48_16_t)src_y * 65536 + fsy/2 ) /
> fsy;
> -
> pixman_image_composite32(PIXMAN_OP_SRC,
> src, NULL, scaled,
> - scaled_src_x, scaled_src_y, /* src */
> + 0, 0, /* src */
> 0, 0, /* mask */
> 0, 0, /* dst */
> dest_width,
> @@ -729,7 +727,6 @@ static void __blend_scale_image(SpiceCanvas
> *spice_canvas,
> pixman_transform_t transform;
> pixman_image_t *mask, *dest;
> pixman_fixed_t fsx, fsy;
> - int scaled_src_x, scaled_src_y;
>
> fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
> fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
> @@ -739,6 +736,9 @@ static void __blend_scale_image(SpiceCanvas
> *spice_canvas,
> pixman_image_set_clip_region32(dest, region);
>
> pixman_transform_init_scale(&transform, fsx, fsy);
> + pixman_transform_translate(&transform, NULL,
> + pixman_int_to_fixed (src_x),
> + pixman_int_to_fixed (src_y));
>
> mask = NULL;
> if (overall_alpha != 0xff) {
> @@ -756,12 +756,9 @@ static void __blend_scale_image(SpiceCanvas
> *spice_canvas,
> PIXMAN_FILTER_NEAREST :
> PIXMAN_FILTER_GOOD,
> NULL, 0);
>
> - scaled_src_x = ((pixman_fixed_48_16_t)src_x * 65536 + fsx/2 ) /
> fsx;
> - scaled_src_y = ((pixman_fixed_48_16_t)src_y * 65536 + fsy/2 ) /
> fsy;
> -
> pixman_image_composite32(PIXMAN_OP_OVER,
> src, mask, dest,
> - scaled_src_x, scaled_src_y, /* src */
> + 0, 0, /* src */
> 0, 0, /* mask */
> dest_x, dest_y, /* dst */
> dest_width, dest_height);
> @@ -888,7 +885,6 @@ static void __colorkey_scale_image(SpiceCanvas
> *spice_canvas,
> pixman_box32_t *rects;
> int n_rects, i;
> pixman_fixed_t fsx, fsy;
> - int scaled_src_x, scaled_src_y;
>
> fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
> fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
> @@ -902,6 +898,9 @@ static void __colorkey_scale_image(SpiceCanvas
> *spice_canvas,
> pixman_image_set_clip_region32(scaled, region);
>
> pixman_transform_init_scale(&transform, fsx, fsy);
> + pixman_transform_translate(&transform, NULL,
> + pixman_int_to_fixed (src_x),
> + pixman_int_to_fixed (src_y));
>
> pixman_image_set_transform(src, &transform);
> pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
> @@ -909,12 +908,9 @@ static void __colorkey_scale_image(SpiceCanvas
> *spice_canvas,
> PIXMAN_FILTER_NEAREST,
> NULL, 0);
>
> - scaled_src_x = ((pixman_fixed_48_16_t)src_x * 65536 + fsx/2 ) /
> fsx;
> - scaled_src_y = ((pixman_fixed_48_16_t)src_y * 65536 + fsy/2 ) /
> fsy;
> -
> pixman_image_composite32(PIXMAN_OP_SRC,
> src, NULL, scaled,
> - scaled_src_x, scaled_src_y, /* src */
> + 0, 0, /* src */
> 0, 0, /* mask */
> 0, 0, /* dst */
> dest_width,
> --
> 1.7.2.1
>
I wouldn't mind seeing some consolidation of the various scaling functions, other then that
ACK
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
More information about the Spice-devel
mailing list