[Spice-commits] 6 commits - common/canvas_base.c server/red_parse_qxl.c server/red_worker.c

Alexander Larsson alexl at kemper.freedesktop.org
Wed Sep 22 07:55:43 PDT 2010


 common/canvas_base.c   |   64 +++++++++++++++++++++++++++++++++----------------
 server/red_parse_qxl.c |    3 ++
 server/red_worker.c    |   32 +++++++++++++++---------
 3 files changed, 67 insertions(+), 32 deletions(-)

New commits:
commit c425ed626c19ac5c2401cb8765033dd3e9d558b8
Author: Alexander Larsson <alexl at redhat.com>
Date:   Wed Sep 22 14:36:40 2010 +0200

    Handle surface images in DrawOpaque

diff --git a/common/canvas_base.c b/common/canvas_base.c
index acf9ae5..c2763bc 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -2414,6 +2414,7 @@ static void canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, Spice
     CanvasBase *canvas = (CanvasBase *)spice_canvas;
     pixman_image_t *src_image;
     pixman_region32_t dest_region;
+    SpiceCanvas *surface_canvas;
     SpiceROP rop;
 
     pixman_region32_init_rect(&dest_region,
@@ -2436,30 +2437,52 @@ static void canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, Spice
         return;
     }
 
-    src_image = canvas_get_image(canvas, opaque->src_bitmap, FALSE);
-
-    if (rect_is_same_size(bbox, &opaque->src_area)) {
-        spice_canvas->ops->blit_image(spice_canvas, &dest_region,
-                                      src_image,
-                                      bbox->left - opaque->src_area.left,
-                                      bbox->top - opaque->src_area.top);
+    surface_canvas = canvas_get_surface(canvas, opaque->src_bitmap);
+    if (surface_canvas) {
+        if (rect_is_same_size(bbox, &opaque->src_area)) {
+            spice_canvas->ops->blit_image_from_surface(spice_canvas, &dest_region,
+                                                       surface_canvas,
+                                                       bbox->left - opaque->src_area.left,
+                                                       bbox->top - opaque->src_area.top);
+        } else {
+            spice_canvas->ops->scale_image_from_surface(spice_canvas, &dest_region,
+                                                        surface_canvas,
+                                                        opaque->src_area.left,
+                                                        opaque->src_area.top,
+                                                        opaque->src_area.right - opaque->src_area.left,
+                                                        opaque->src_area.bottom - opaque->src_area.top,
+                                                        bbox->left,
+                                                        bbox->top,
+                                                        bbox->right - bbox->left,
+                                                        bbox->bottom - bbox->top,
+                                                        opaque->scale_mode);
+        }
     } else {
-        spice_canvas->ops->scale_image(spice_canvas, &dest_region,
-                                       src_image,
-                                       opaque->src_area.left,
-                                       opaque->src_area.top,
-                                       opaque->src_area.right - opaque->src_area.left,
-                                       opaque->src_area.bottom - opaque->src_area.top,
-                                       bbox->left,
-                                       bbox->top,
-                                       bbox->right - bbox->left,
-                                       bbox->bottom - bbox->top,
-                                       opaque->scale_mode);
+        src_image = canvas_get_image(canvas, opaque->src_bitmap, FALSE);
+
+        if (rect_is_same_size(bbox, &opaque->src_area)) {
+            spice_canvas->ops->blit_image(spice_canvas, &dest_region,
+                                          src_image,
+                                          bbox->left - opaque->src_area.left,
+                                          bbox->top - opaque->src_area.top);
+        } else {
+            spice_canvas->ops->scale_image(spice_canvas, &dest_region,
+                                           src_image,
+                                           opaque->src_area.left,
+                                           opaque->src_area.top,
+                                           opaque->src_area.right - opaque->src_area.left,
+                                           opaque->src_area.bottom - opaque->src_area.top,
+                                           bbox->left,
+                                           bbox->top,
+                                           bbox->right - bbox->left,
+                                           bbox->bottom - bbox->top,
+                                           opaque->scale_mode);
+        }
+        pixman_image_unref(src_image);
     }
 
     draw_brush(spice_canvas, &dest_region, &opaque->brush, rop);
 
-    pixman_image_unref(src_image);
     pixman_region32_fini(&dest_region);
 }
 
commit 587584a4e468dfe46649df9864d12f51a80d34a6
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 21 20:14:50 2010 +0200

    server: Handle self_image in localize_bitmap
    
    When drawing a drawable with a NULL src bitmap that means we should
    be using the previously generated self_bitmap. Not doing this causes
    a segfault due to accessing the NULL.

diff --git a/server/red_worker.c b/server/red_worker.c
index f307aef..d59726f 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -3715,10 +3715,17 @@ static void image_cache_eaging(ImageCache *cache)
 #endif
 }
 
-static void localize_bitmap(RedWorker *worker, SpiceImage **image_ptr, SpiceImage *image_store)
+static void localize_bitmap(RedWorker *worker, SpiceImage **image_ptr, SpiceImage *image_store, Drawable *drawable)
 {
     SpiceImage *image = *image_ptr;
 
+    if (image == NULL) {
+        ASSERT(drawable != NULL);
+        ASSERT(drawable->self_bitmap != NULL);
+        *image_ptr = drawable->self_bitmap;
+        return;
+    }
+
     if (image_cache_hit(&worker->image_cache, image->descriptor.id)) {
         image_store->descriptor = image->descriptor;
         image_store->descriptor.type = SPICE_IMAGE_TYPE_FROM_CACHE;
@@ -3753,14 +3760,14 @@ static void localize_bitmap(RedWorker *worker, SpiceImage **image_ptr, SpiceImag
 static void localize_brush(RedWorker *worker, SpiceBrush *brush, SpiceImage *image_store)
 {
     if (brush->type == SPICE_BRUSH_TYPE_PATTERN) {
-        localize_bitmap(worker, &brush->u.pattern.pat, image_store);
+        localize_bitmap(worker, &brush->u.pattern.pat, image_store, NULL);
     }
 }
 
 static void localize_mask(RedWorker *worker, SpiceQMask *mask, SpiceImage *image_store)
 {
     if (mask->bitmap) {
-        localize_bitmap(worker, &mask->bitmap, image_store);
+        localize_bitmap(worker, &mask->bitmap, image_store, NULL);
     }
 }
 
@@ -3793,7 +3800,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
         SpiceOpaque opaque = drawable->red_drawable->u.opaque;
         SpiceImage img1, img2, img3;
         localize_brush(worker, &opaque.brush, &img1);
-        localize_bitmap(worker, &opaque.src_bitmap, &img2);
+        localize_bitmap(worker, &opaque.src_bitmap, &img2, drawable);
         localize_mask(worker, &opaque.mask, &img3);
         canvas->ops->draw_opaque(canvas, &drawable->red_drawable->bbox, &clip, &opaque);
         break;
@@ -3801,7 +3808,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
     case QXL_DRAW_COPY: {
         SpiceCopy copy = drawable->red_drawable->u.copy;
         SpiceImage img1, img2;
-        localize_bitmap(worker, &copy.src_bitmap, &img1);
+        localize_bitmap(worker, &copy.src_bitmap, &img1, drawable);
         localize_mask(worker, &copy.mask, &img2);
         canvas->ops->draw_copy(canvas, &drawable->red_drawable->bbox,
                                &clip, &copy);
@@ -3810,7 +3817,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
     case QXL_DRAW_TRANSPARENT: {
         SpiceTransparent transparent = drawable->red_drawable->u.transparent;
         SpiceImage img1;
-        localize_bitmap(worker, &transparent.src_bitmap, &img1);
+        localize_bitmap(worker, &transparent.src_bitmap, &img1, drawable);
         canvas->ops->draw_transparent(canvas,
                                       &drawable->red_drawable->bbox, &clip, &transparent);
         break;
@@ -3818,7 +3825,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
     case QXL_DRAW_ALPHA_BLEND: {
         SpiceAlphaBlend alpha_blend = drawable->red_drawable->u.alpha_blend;
         SpiceImage img1;
-        localize_bitmap(worker, &alpha_blend.src_bitmap, &img1);
+        localize_bitmap(worker, &alpha_blend.src_bitmap, &img1, drawable);
         canvas->ops->draw_alpha_blend(canvas,
                                       &drawable->red_drawable->bbox, &clip, &alpha_blend);
         break;
@@ -3831,7 +3838,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
     case QXL_DRAW_BLEND: {
         SpiceBlend blend = drawable->red_drawable->u.blend;
         SpiceImage img1, img2;
-        localize_bitmap(worker, &blend.src_bitmap, &img1);
+        localize_bitmap(worker, &blend.src_bitmap, &img1, drawable);
         localize_mask(worker, &blend.mask, &img2);
         canvas->ops->draw_blend(canvas, &drawable->red_drawable->bbox,
                                 &clip, &blend);
@@ -3865,7 +3872,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
         SpiceRop3 rop3 = drawable->red_drawable->u.rop3;
         SpiceImage img1, img2, img3;
         localize_brush(worker, &rop3.brush, &img1);
-        localize_bitmap(worker, &rop3.src_bitmap, &img2);
+        localize_bitmap(worker, &rop3.src_bitmap, &img2, drawable);
         localize_mask(worker, &rop3.mask, &img3);
         canvas->ops->draw_rop3(canvas, &drawable->red_drawable->bbox,
                                &clip, &rop3);
commit 485ba90b0303f6c8b7995f22936560b518eec012
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 21 20:12:51 2010 +0200

    server: Handle NULL image in red_update_streamable
    
    A NULL src bitmap means self_bitmap, which is not a stream, so abort.

diff --git a/server/red_worker.c b/server/red_worker.c
index 5a2477a..f307aef 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -3130,7 +3130,8 @@ static inline void red_update_streamable(RedWorker *worker, Drawable *drawable,
     }
 
     image = red_drawable->u.copy.src_bitmap;
-    if (image->descriptor.type != SPICE_IMAGE_TYPE_BITMAP) {
+    if (image == NULL ||
+        image->descriptor.type != SPICE_IMAGE_TYPE_BITMAP) {
         return;
     }
 
commit 763e05ee30c67014c3e843b8e4bc5a7d7e9aac74
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 21 20:11:18 2010 +0200

    server: Use the right image size for self_bitmap
    
    The self_bitmap is the size of self_bitmap_area, not the bbox.
    This is especially important since we later copy the self_bitmap_area
    into the new bitmap, and if that is larger than bbox then we will
    overwrite random memory.

diff --git a/server/red_worker.c b/server/red_worker.c
index ef1c998..5a2477a 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -3271,8 +3271,8 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
 
     bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
 
-    width = drawable->red_drawable->bbox.right - drawable->red_drawable->bbox.left;
-    height = drawable->red_drawable->bbox.bottom - drawable->red_drawable->bbox.top;
+    width = drawable->red_drawable->self_bitmap_area.right - drawable->red_drawable->self_bitmap_area.left;
+    height = drawable->red_drawable->self_bitmap_area.bottom - drawable->red_drawable->self_bitmap_area.top;
     dest_stride = SPICE_ALIGN(width * bpp, 4);
 
     image = spice_new0(SpiceImage, 1);
commit 5322d4314684531f7b09dc74a2b37f7c5d55929b
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 21 20:09:59 2010 +0200

    server: Don't leak QUIC image chunks
    
    red_put_image() needs to free the chunks for QUIC images, as we
    allocate these when creating the image.

diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
index 5b32f6b..ab01d63 100644
--- a/server/red_parse_qxl.c
+++ b/server/red_parse_qxl.c
@@ -412,6 +412,9 @@ void red_put_image(SpiceImage *red)
         }
         spice_chunks_destroy(red->u.bitmap.data);
         break;
+    case SPICE_IMAGE_TYPE_QUIC:
+        spice_chunks_destroy(red->u.quic.data);
+        break;
     }
     free(red);
 }
commit 1cd80764154472cff2744117a792423550e55cd0
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 21 20:08:46 2010 +0200

    Fix crash when resetting pixman image transform
    
    Resetting the transform is done by setting it to the identity
    transform, not passing in NULL. Passing in NULL causes a crash.

diff --git a/common/canvas_base.c b/common/canvas_base.c
index bbb135d..acf9ae5 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -1751,7 +1751,8 @@ static pixman_image_t *canvas_scale_surface(pixman_image_t *src, const SpiceRect
                              0, 0, /* dst */
                              width, height);
 
-    pixman_image_set_transform(src, NULL);
+    pixman_transform_init_identity(&transform);
+    pixman_image_set_transform(src, &transform);
 
     return surface;
 }


More information about the Spice-commits mailing list