[Spice-devel] [PATCH 05/30] Add pixman_image_t referencing the cairo_canvas bits

Alexander Larsson alexl at redhat.com
Thu Feb 18 12:58:31 PST 2010


This references the same data as the cairo surface and can be used
for drawing to the surface using direct pixman calls instead.
---
 common/cairo_canvas.c |    7 +++++++
 common/canvas_base.c  |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/common/cairo_canvas.c b/common/cairo_canvas.c
index a5d4146..4f3c780 100644
--- a/common/cairo_canvas.c
+++ b/common/cairo_canvas.c
@@ -17,16 +17,19 @@
 */
 
 #include "cairo_canvas.h"
+#define CANVAS_USE_PIXMAN
 #include "canvas_base.c"
 #include "rop3.h"
 #include "rect.h"
 #include "region.h"
+#include "pixman_utils.h"
 
 struct CairoCanvas {
     CanvasBase base;
     cairo_t *cairo;
     uint32_t *private_data;
     int private_data_size;
+    pixman_image_t *image;
 };
 
 static void canvas_set_path(CairoCanvas *canvas, void *addr)
@@ -1581,6 +1584,7 @@ void canvas_destroy(CairoCanvas *canvas)
     if (!canvas) {
         return;
     }
+    pixman_image_unref (canvas->image);
     canvas_base_destroy(&canvas->base);
     if (canvas->private_data) {
         free(canvas->private_data);
@@ -1654,6 +1658,9 @@ CairoCanvas *canvas_create(cairo_t *cairo, int bits
     canvas->private_data = NULL;
     canvas->private_data_size = 0;
     cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE);
+
+    canvas->image = pixman_image_from_surface (cairo_get_target (cairo));
+
     return canvas;
 }
 
diff --git a/common/canvas_base.c b/common/canvas_base.c
index 356ef9d..ebb9846 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -26,6 +26,7 @@
 #include "quic.h"
 #include "lz.h"
 #include "canvas_base.h"
+#include "pixman_utils.h"
 #include "canvas_utils.h"
 #include "rect.h"
 
@@ -214,6 +215,43 @@ typedef struct ATTR_PACKED DataChunk {
 
 #endif
 
+#ifdef CANVAS_USE_PIXMAN
+
+static pixman_format_code_t
+pixman_format_from_cairo_format (cairo_format_t format)
+{
+    switch (format) {
+    case CAIRO_FORMAT_A1:
+        return PIXMAN_a1;
+    case CAIRO_FORMAT_A8:
+        return PIXMAN_a8;
+    case CAIRO_FORMAT_RGB24:
+        return PIXMAN_x8r8g8b8;
+    case CAIRO_FORMAT_ARGB32:
+    default:
+        return PIXMAN_a8r8g8b8;
+    }
+}
+
+static pixman_image_t *
+pixman_image_from_surface (cairo_surface_t *surface)
+{
+  pixman_image_t *image;
+  cairo_format_t format;
+
+
+  format = cairo_image_surface_get_format (surface);
+
+  image = pixman_image_create_bits (pixman_format_from_cairo_format (format),
+                                    cairo_image_surface_get_width (surface),
+                                    cairo_image_surface_get_height (surface),
+                                    (uint32_t *)cairo_image_surface_get_data (surface),
+                                    cairo_image_surface_get_stride (surface));
+
+  return image;
+}
+
+#endif
 
 static inline void canvas_localize_palette(CanvasBase *canvas, SpicePalette *palette)
 {
-- 
1.6.6



More information about the Spice-devel mailing list