[Spice-commits] 3 commits - common/sw_canvas.c server/red_worker.c

Alexander Larsson alexl at kemper.freedesktop.org
Sun Aug 29 23:43:43 PDT 2010


 common/sw_canvas.c  |   64 +++++++++++++++++++++++++++++-----------------------
 server/red_worker.c |    4 ++-
 2 files changed, 39 insertions(+), 29 deletions(-)

New commits:
commit 9ac9099842a7379a991a70627ddf6fe47462fc4a
Author: Alexander Larsson <alexl at redhat.com>
Date:   Fri Aug 27 16:33:35 2010 +0200

    canvas: Better coordinate rounding in scaling
    
    When scaling in pixman you give the source coordinates in transformed
    space rather than in the source coordinates. This is a bit problematic
    when both source and destination coordinates are at integer positions, but
    the scaling factor is not an exact 16.16 fixed point value. We used
    to calculate the transformed source based on the floating point
    transformation, which gave the wrong answer sometimes. Now we do the
    calculations based on the fixed point transform that we give pixman.
    
    However, even with this patch I can still sometimes see issues related
    to this, although they are less bad.

diff --git a/common/sw_canvas.c b/common/sw_canvas.c
index a4edfa2..a92cff6 100644
--- a/common/sw_canvas.c
+++ b/common/sw_canvas.c
@@ -453,16 +453,15 @@ static void __scale_image(SpiceCanvas *spice_canvas,
 {
     SwCanvas *canvas = (SwCanvas *)spice_canvas;
     pixman_transform_t transform;
-    double sx, sy;
+    pixman_fixed_t fsx, fsy;
+    int scaled_src_x, scaled_src_y;
 
-    sx = (double)(src_width) / (dest_width);
-    sy = (double)(src_height) / (dest_height);
+    fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
+    fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
 
     pixman_image_set_clip_region32(canvas->image, region);
 
-    pixman_transform_init_scale(&transform,
-                                pixman_double_to_fixed(sx),
-                                pixman_double_to_fixed(sy));
+    pixman_transform_init_scale(&transform, fsx, fsy);
 
     pixman_image_set_transform(src, &transform);
     pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
@@ -473,9 +472,12 @@ 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,
-                             ROUND(src_x / sx), ROUND(src_y / sy), /* src */
+                             scaled_src_x, scaled_src_y, /* src */
                              0, 0, /* mask */
                              dest_x, dest_y, /* dst */
                              dest_width, dest_height);
@@ -527,10 +529,11 @@ static void __scale_image_rop(SpiceCanvas *spice_canvas,
     pixman_image_t *scaled;
     pixman_box32_t *rects;
     int n_rects, i;
-    double sx, sy;
+    pixman_fixed_t fsx, fsy;
+    int scaled_src_x, scaled_src_y;
 
-    sx = (double)(src_width) / (dest_width);
-    sy = (double)(src_height) / (dest_height);
+    fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
+    fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
 
     scaled = pixman_image_create_bits(spice_pixman_image_get_format(src),
                                       dest_width,
@@ -540,9 +543,7 @@ static void __scale_image_rop(SpiceCanvas *spice_canvas,
     pixman_region32_translate(region, -dest_x, -dest_y);
     pixman_image_set_clip_region32(scaled, region);
 
-    pixman_transform_init_scale(&transform,
-                                pixman_double_to_fixed(sx),
-                                pixman_double_to_fixed(sy));
+    pixman_transform_init_scale(&transform, fsx, fsy);
 
     pixman_image_set_transform(src, &transform);
     pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
@@ -553,9 +554,12 @@ 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,
-                             ROUND(src_x / sx), ROUND(src_y / sy), /* src */
+                             scaled_src_x, scaled_src_y, /* src */
                              0, 0, /* mask */
                              0, 0, /* dst */
                              dest_width,
@@ -724,18 +728,17 @@ static void __blend_scale_image(SpiceCanvas *spice_canvas,
     SwCanvas *canvas = (SwCanvas *)spice_canvas;
     pixman_transform_t transform;
     pixman_image_t *mask, *dest;
-    double sx, sy;
+    pixman_fixed_t fsx, fsy;
+    int scaled_src_x, scaled_src_y;
 
-    sx = (double)(src_width) / (dest_width);
-    sy = (double)(src_height) / (dest_height);
+    fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
+    fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
 
     dest = canvas_get_as_surface(canvas, dest_has_alpha);
 
     pixman_image_set_clip_region32(dest, region);
 
-    pixman_transform_init_scale(&transform,
-                                pixman_double_to_fixed(sx),
-                                pixman_double_to_fixed(sy));
+    pixman_transform_init_scale(&transform, fsx, fsy);
 
     mask = NULL;
     if (overall_alpha != 0xff) {
@@ -753,9 +756,12 @@ 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,
-                             ROUND(src_x / sx), ROUND(src_y / sy), /* src */
+                             scaled_src_x, scaled_src_y, /* src */
                              0, 0, /* mask */
                              dest_x, dest_y, /* dst */
                              dest_width, dest_height);
@@ -881,10 +887,11 @@ static void __colorkey_scale_image(SpiceCanvas *spice_canvas,
     pixman_image_t *scaled;
     pixman_box32_t *rects;
     int n_rects, i;
-    double sx, sy;
+    pixman_fixed_t fsx, fsy;
+    int scaled_src_x, scaled_src_y;
 
-    sx = (double)(src_width) / (dest_width);
-    sy = (double)(src_height) / (dest_height);
+    fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
+    fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
 
     scaled = pixman_image_create_bits(spice_pixman_image_get_format (src),
                                       dest_width,
@@ -894,9 +901,7 @@ static void __colorkey_scale_image(SpiceCanvas *spice_canvas,
     pixman_region32_translate(region, -dest_x, -dest_y);
     pixman_image_set_clip_region32(scaled, region);
 
-    pixman_transform_init_scale(&transform,
-                                pixman_double_to_fixed(sx),
-                                pixman_double_to_fixed(sy));
+    pixman_transform_init_scale(&transform, fsx, fsy);
 
     pixman_image_set_transform(src, &transform);
     pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
@@ -904,9 +909,12 @@ 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,
-                             ROUND(src_x / sx), ROUND(src_y / sy), /* src */
+                             scaled_src_x, scaled_src_y, /* src */
                              0, 0, /* mask */
                              0, 0, /* dst */
                              dest_width,
commit 250203951bc02528d821fa775949edd09b8c6d8c
Author: Alexander Larsson <alexl at redhat.com>
Date:   Thu Aug 26 20:10:34 2010 +0200

    server: red_send_image() - append image data to right marshaller
    
    The actual bitmap data was added to the main marshaller rather than
    the submarshaller that pointed to the SpiceImage part. This made us
    send too short messages failing demarshalling in the client.

diff --git a/server/red_worker.c b/server/red_worker.c
index c39bdf0..173ee65 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -7957,7 +7957,8 @@ static void red_send_image(DisplayChannel *display_channel, ImageItem *item)
 
         spice_marshall_Image(src_bitmap_out, &red_image,
                              &bitmap_palette_out, &lzplt_palette_out);
-        spice_marshaller_add_ref(m, item->data, bitmap.y * bitmap.stride);
+        spice_marshaller_add_ref(src_bitmap_out, item->data,
+                                 bitmap.y * bitmap.stride);
         region_remove(surface_lossy_region, &copy.base.box);
     }
     display_begin_send_message(display_channel, &item->link);
commit c13f931b5f2df1938547f3d3e7f5d848a7137b5f
Author: Alexander Larsson <alexl at redhat.com>
Date:   Thu Aug 26 20:10:33 2010 +0200

    server: red_send_image() initialize bitmap.flags
    
    We're currently sending this to the network based on random memory.

diff --git a/server/red_worker.c b/server/red_worker.c
index 3efaa3e..c39bdf0 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -7855,6 +7855,7 @@ static void red_send_image(DisplayChannel *display_channel, ImageItem *item)
     red_image.descriptor.height = item->height;
 
     bitmap.format = item->image_format;
+    bitmap.flags = 0;
     if (item->top_down) {
         bitmap.flags |= SPICE_BITMAP_FLAGS_TOP_DOWN;
     }


More information about the Spice-commits mailing list