summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/canvas.h30
-rw-r--r--common/cairo_canvas.c151
-rw-r--r--common/canvas_base.c323
-rw-r--r--common/canvas_base.h8
-rw-r--r--common/canvas_utils.c152
-rw-r--r--common/canvas_utils.h30
-rw-r--r--common/gdi_canvas.c156
-rw-r--r--common/gdi_canvas.h2
-rw-r--r--common/gl_canvas.c171
-rw-r--r--common/rop3.c56
-rw-r--r--common/rop3.h8
-rw-r--r--server/red_worker.c12
12 files changed, 555 insertions, 544 deletions
diff --git a/client/canvas.h b/client/canvas.h
index 3074d0d1..1bd3180f 100644
--- a/client/canvas.h
+++ b/client/canvas.h
@@ -40,14 +40,14 @@ struct QRegion;
class PixmapCacheTreat {
public:
- static inline cairo_surface_t *get(cairo_surface_t *surf)
+ static inline pixman_image_t *get(pixman_image_t *surf)
{
- return cairo_surface_reference(surf);
+ return pixman_image_ref(surf);
}
- static inline void release(cairo_surface_t *surf)
+ static inline void release(pixman_image_t *surf)
{
- cairo_surface_destroy(surf);
+ pixman_image_unref(surf);
}
static const char* name() { return "pixmap";}
@@ -55,19 +55,19 @@ public:
class SpiceImageCacheBase;
-typedef SharedCache<cairo_surface_t, PixmapCacheTreat, 1024, SpiceImageCacheBase> PixmapCache;
+typedef SharedCache<pixman_image_t, PixmapCacheTreat, 1024, SpiceImageCacheBase> PixmapCache;
class SpiceImageCacheBase {
public:
SpiceImageCache base;
- static void op_put(SpiceImageCache *c, uint64_t id, cairo_surface_t *surface)
+ static void op_put(SpiceImageCache *c, uint64_t id, pixman_image_t *surface)
{
PixmapCache* cache = reinterpret_cast<PixmapCache*>(c);
cache->add(id, surface);
}
- static cairo_surface_t* op_get(SpiceImageCache *c, uint64_t id)
+ static pixman_image_t* op_get(SpiceImageCache *c, uint64_t id)
{
PixmapCache* cache = reinterpret_cast<PixmapCache*>(c);
return cache->get(id);
@@ -185,20 +185,20 @@ public:
class GlzDecodedSurface: public GlzDecodedImage {
public:
GlzDecodedSurface(uint64_t id, uint64_t win_head_id, uint8_t *data, int size,
- int bytes_per_pixel, cairo_surface_t *surface)
+ int bytes_per_pixel, pixman_image_t *surface)
: GlzDecodedImage(id, win_head_id, data, size, bytes_per_pixel)
, _surface (surface)
{
- cairo_surface_reference(_surface);
+ pixman_image_ref(_surface);
}
virtual ~GlzDecodedSurface()
{
- cairo_surface_destroy(_surface);
+ pixman_image_unref(_surface);
}
private:
- cairo_surface_t *_surface;
+ pixman_image_t *_surface;
};
class GlzDecodeSurfaceHandler: public GlzDecodeHandler {
@@ -208,10 +208,10 @@ public:
int width, int height, int gross_pixels,
int n_bytes_per_pixel, bool top_down)
{
- cairo_surface_t *surface = alloc_lz_image_surface((LzDecodeUsrData *)opaque_usr_info,
- type, width, height, gross_pixels,
- top_down);
- uint8_t *data = cairo_image_surface_get_data(surface);
+ pixman_image_t *surface = alloc_lz_image_surface((LzDecodeUsrData *)opaque_usr_info,
+ type, width, height, gross_pixels,
+ top_down);
+ uint8_t *data = (uint8_t *)pixman_image_get_data(surface);
if (!top_down) {
data = data - (gross_pixels / height) * n_bytes_per_pixel * (height - 1);
}
diff --git a/common/cairo_canvas.c b/common/cairo_canvas.c
index 4b8c3059..5ee7ccb3 100644
--- a/common/cairo_canvas.c
+++ b/common/cairo_canvas.c
@@ -297,7 +297,7 @@ static inline void canvas_invers_1bpp_be(uint8_t* dest, int dest_stride, uint8_t
}
}
-static cairo_surface_t *canvas_bitmap_to_invers_surface(CairoCanvas *canvas, SpiceBitmap* bitmap,
+static pixman_image_t *canvas_bitmap_to_invers_surface(CairoCanvas *canvas, SpiceBitmap* bitmap,
SpicePalette *palette)
{
uint8_t* src = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
@@ -305,21 +305,20 @@ static cairo_surface_t *canvas_bitmap_to_invers_surface(CairoCanvas *canvas, Spi
uint8_t* end;
uint8_t* dest;
int dest_stride;
- cairo_surface_t* cairo_surface;
+ pixman_image_t* surface;
src_stride = bitmap->stride;
end = src + (bitmap->y * src_stride);
access_test(&canvas->base, src, bitmap->y * src_stride);
- cairo_surface = cairo_image_surface_create((bitmap->format == SPICE_BITMAP_FMT_RGBA) ?
- CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
- bitmap->x, bitmap->y);
- if (cairo_surface_status(cairo_surface) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(cairo_surface)));
+ surface = pixman_image_create_bits((bitmap->format == SPICE_BITMAP_FMT_RGBA) ?
+ PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
+ bitmap->x, bitmap->y, NULL, 0);
+ if (surface == NULL) {
+ CANVAS_ERROR("create surface failed");
}
- dest = cairo_image_surface_get_data(cairo_surface);
- dest_stride = cairo_image_surface_get_stride(cairo_surface);
+ dest = (uint8_t *)pixman_image_get_data(surface);
+ dest_stride = pixman_image_get_stride(surface);
if (!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
ASSERT(bitmap->y > 0);
@@ -347,7 +346,7 @@ static cairo_surface_t *canvas_bitmap_to_invers_surface(CairoCanvas *canvas, Spi
canvas_invers_1bpp_be(dest, dest_stride, src, src_stride, bitmap->x, end, palette);
break;
}
- return cairo_surface;
+ return surface;
}
#if defined(CAIRO_CANVAS_CACHE) || defined(CAIRO_CANVAS_IMAGE_CACHE)
@@ -386,11 +385,11 @@ static void free_palette(SpiceBitmap *bitmap, SpicePalette *palette)
#endif
-static cairo_surface_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
+static pixman_image_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
{
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
- cairo_surface_t *surface;
- cairo_surface_t *invers = NULL;
+ pixman_image_t *surface;
+ pixman_image_t *invers = NULL;
access_test(&canvas->base, descriptor, sizeof(SpiceImageDescriptor));
@@ -469,13 +468,13 @@ static cairo_surface_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRE
}
invers = canvas_handle_inverse_user_data(surface);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
return invers;
}
#else
-static cairo_surface_t *canvas_get_invers(CairoCanvas *canvas, SpiceBitmap *bitmap)
+static pixman_image_t *canvas_get_invers(CairoCanvas *canvas, SpiceBitmap *bitmap)
{
SpicePalette *palette;
@@ -486,7 +485,7 @@ static cairo_surface_t *canvas_get_invers(CairoCanvas *canvas, SpiceBitmap *bitm
if (canvas->color_shift == 5) {
int size = sizeof(SpicePalette) + (palette->num_ents << 2);
SpicePalette *local_palette = malloc(size);
- cairo_surface_t* surface;
+ pixman_image_t* surface;
memcpy(local_palette, palette, size);
canvas_localize_palette(canvas, palette);
@@ -498,7 +497,7 @@ static cairo_surface_t *canvas_get_invers(CairoCanvas *canvas, SpiceBitmap *bitm
}
}
-static cairo_surface_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
+static pixman_image_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
{
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
@@ -522,28 +521,28 @@ static cairo_surface_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRE
#endif
-static cairo_surface_t* canvas_surface_from_self(CairoCanvas *canvas, SpicePoint *pos,
- int32_t width, int32_t heigth)
+static pixman_image_t* canvas_surface_from_self(CairoCanvas *canvas, SpicePoint *pos,
+ int32_t width, int32_t heigth)
{
- cairo_surface_t *surface;
- cairo_surface_t *src_surface;
+ pixman_image_t *surface;
+ pixman_image_t *src_surface;
uint8_t *dest;
int dest_stride;
uint8_t *src;
int src_stride;
int i;
- surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, heigth);
- if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(surface)));
+ surface = pixman_image_create_bits(PIXMAN_x8r8g8b8, width, heigth, NULL, 0);
+ if (surface == NULL) {
+ CANVAS_ERROR("create surface failed");
}
- dest = cairo_image_surface_get_data(surface);
- dest_stride = cairo_image_surface_get_stride(surface);
- src_surface = cairo_get_target(canvas->cairo);
- src = cairo_image_surface_get_data(src_surface);
- src_stride = cairo_image_surface_get_stride(src_surface);
+ dest = (uint8_t *)pixman_image_get_data(surface);
+ dest_stride = pixman_image_get_stride(surface);
+
+ src_surface = canvas->image;
+ src = (uint8_t *)pixman_image_get_data(src_surface);
+ src_stride = pixman_image_get_stride(src_surface);
src += pos->y * src_stride + (pos->x << 2);
for (i = 0; i < heigth; i++, dest += dest_stride, src += src_stride) {
memcpy(dest, src, width << 2);
@@ -566,7 +565,8 @@ static cairo_pattern_t *canvas_get_brush(CairoCanvas *canvas, SpiceBrush *brush,
return cairo_pattern_create_rgb(r, g, b);
}
case SPICE_BRUSH_TYPE_PATTERN: {
- cairo_surface_t* surface;
+ pixman_image_t* surface;
+ cairo_surface_t* cairo_surface;
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
@@ -575,13 +575,15 @@ static cairo_pattern_t *canvas_get_brush(CairoCanvas *canvas, SpiceBrush *brush,
} else {
surface = canvas_get_image(&canvas->base, brush->u.pattern.pat);
}
- pattern = cairo_pattern_create_for_surface(surface);
+ cairo_surface = surface_from_pixman_image (surface);
+ pixman_image_unref (surface);
+ pattern = cairo_pattern_create_for_surface(cairo_surface);
if (cairo_pattern_status(pattern) != CAIRO_STATUS_SUCCESS) {
- cairo_surface_destroy(surface);
+ cairo_surface_destroy(cairo_surface);
CANVAS_ERROR("create pattern failed, %s",
cairo_status_to_string(cairo_pattern_status(pattern)));
}
- cairo_surface_destroy(surface);
+ cairo_surface_destroy(cairo_surface);
cairo_matrix_init_translate(&matrix, -brush->u.pattern.pos.x, -brush->u.pattern.pos.y);
cairo_pattern_set_matrix(pattern, &matrix);
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
@@ -666,20 +668,23 @@ static inline void canvas_draw(CairoCanvas *canvas, SpiceBrush *brush, uint16_t
static cairo_pattern_t *canvas_get_mask_pattern(CairoCanvas *canvas, SpiceQMask *mask, int x, int y)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
+ cairo_surface_t *cairo_surface;
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
if (!(surface = canvas_get_mask(&canvas->base, mask))) {
return NULL;
}
- pattern = cairo_pattern_create_for_surface(surface);
+ cairo_surface = surface_from_pixman_image (surface);
+ pixman_image_unref (surface);
+ pattern = cairo_pattern_create_for_surface(cairo_surface);
if (cairo_pattern_status(pattern) != CAIRO_STATUS_SUCCESS) {
- cairo_surface_destroy(surface);
+ cairo_surface_destroy(cairo_surface);
CANVAS_ERROR("create pattern failed, %s",
cairo_status_to_string(cairo_pattern_status(pattern)));
}
- cairo_surface_destroy(surface);
+ cairo_surface_destroy(cairo_surface);
cairo_matrix_init_translate(&matrix, mask->pos.x - x, mask->pos.y - y);
cairo_pattern_set_matrix(pattern, &matrix);
@@ -724,7 +729,8 @@ static cairo_pattern_t *canvas_src_image_to_pat(CairoCanvas *canvas, SPICE_ADDRE
int scale_mode)
{
cairo_pattern_t *pattern;
- cairo_surface_t *surface;
+ pixman_image_t *surface;
+ cairo_surface_t *cairo_surface;
cairo_matrix_t matrix;
ASSERT(src_bitmap);
@@ -735,8 +741,10 @@ static cairo_pattern_t *canvas_src_image_to_pat(CairoCanvas *canvas, SPICE_ADDRE
surface = canvas_get_image(&canvas->base, src_bitmap);
}
- pattern = cairo_pattern_create_for_surface(surface);
- cairo_surface_destroy(surface);
+ cairo_surface = surface_from_pixman_image (surface);
+ pixman_image_unref (surface);
+ pattern = cairo_pattern_create_for_surface(cairo_surface);
+ cairo_surface_destroy(cairo_surface);
if (cairo_pattern_status(pattern) != CAIRO_STATUS_SUCCESS) {
CANVAS_ERROR("create pattern failed, %s",
cairo_status_to_string(cairo_pattern_status(pattern)));
@@ -1124,8 +1132,9 @@ void canvas_draw_rop3(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
{
cairo_t *cairo = canvas->cairo;
cairo_pattern_t *mask;
+ pixman_image_t *dd;
cairo_surface_t *d;
- cairo_surface_t *s;
+ pixman_image_t *s;
SpicePoint pos;
int width;
int heigth;
@@ -1142,13 +1151,13 @@ void canvas_draw_rop3(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
cairo_user_to_device(cairo, &x_pos, &y_pos);
pos.x = (int32_t)x_pos;
pos.y = (int32_t)y_pos;
- d = canvas_surface_from_self(canvas, &pos, width, heigth);
+ dd = canvas_surface_from_self(canvas, &pos, width, heigth);
s = canvas_get_image(&canvas->base, rop3->src_bitmap);
if (!rect_is_same_size(bbox, &rop3->src_area)) {
- cairo_surface_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, width, heigth,
+ pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, width, heigth,
rop3->scale_mode);
- cairo_surface_destroy(s);
+ pixman_image_unref(s);
s = scaled_s;
src_pos.x = 0;
src_pos.y = 0;
@@ -1156,26 +1165,28 @@ void canvas_draw_rop3(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
src_pos.x = rop3->src_area.left;
src_pos.y = rop3->src_area.top;
}
- if (cairo_image_surface_get_width(s) - src_pos.x < width ||
- cairo_image_surface_get_height(s) - src_pos.y < heigth) {
+ if (pixman_image_get_width(s) - src_pos.x < width ||
+ pixman_image_get_height(s) - src_pos.y < heigth) {
CANVAS_ERROR("bad src bitmap size");
}
if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
- cairo_surface_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat);
+ pixman_image_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat);
SpicePoint pat_pos;
- pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % cairo_image_surface_get_width(p);
- pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % cairo_image_surface_get_height(p);
- do_rop3_with_pattern(rop3->rop3, d, s, &src_pos, p, &pat_pos);
- cairo_surface_destroy(p);
+ pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
+ pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
+ do_rop3_with_pattern(rop3->rop3, dd, s, &src_pos, p, &pat_pos);
+ pixman_image_unref(p);
} else {
uint32_t color = (canvas->base.color_shift) == 8 ? rop3->brush.u.color :
canvas_16bpp_to_32bpp(rop3->brush.u.color);
- do_rop3_with_color(rop3->rop3, d, s, &src_pos, color);
+ do_rop3_with_color(rop3->rop3, dd, s, &src_pos, color);
}
- cairo_surface_destroy(s);
+ pixman_image_unref(s);
+ d = surface_from_pixman_image (dd);
cairo_set_source_surface(cairo, d, bbox->left, bbox->top);
cairo_surface_destroy(d);
+ pixman_image_unref (dd);
if ((mask = canvas_get_mask_pattern(canvas, &rop3->mask, bbox->left, bbox->top))) {
cairo_rectangle(cairo,
bbox->left,
@@ -1360,7 +1371,8 @@ static inline void __canvas_copy_region_bits(uint8_t *data, int stride, SpiceRec
void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
{
cairo_t *cairo = canvas->cairo;
- cairo_surface_t *surface;
+ cairo_surface_t *cairo_surface;
+ pixman_image_t *surface;
int32_t width;
int32_t heigth;
@@ -1368,22 +1380,20 @@ void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
#ifdef FAST_COPY_BITS
switch (clip->type) {
case SPICE_CLIP_TYPE_NONE: {
- surface = cairo_get_target(cairo);
- __canvas_copy_rect_bits(cairo_image_surface_get_data(surface),
- cairo_image_surface_get_stride(surface),
+ __canvas_copy_rect_bits((uint8_t *)pixman_image_get_data(canvas->image),
+ pixman_image_get_stride(canvas->image),
bbox, src_pos);
break;
}
case SPICE_CLIP_TYPE_RECTS: {
- surface = cairo_get_target(cairo);
uint32_t *n = (uint32_t *)SPICE_GET_ADDRESS(clip->data);
access_test(&canvas->base, n, sizeof(uint32_t));
SpiceRect *now = (SpiceRect *)(n + 1);
SpiceRect *end = now + *n;
access_test(&canvas->base, now, (unsigned long)end - (unsigned long)now);
- uint8_t *data = cairo_image_surface_get_data(surface);
- int stride = cairo_image_surface_get_stride(surface);
+ uint8_t *data = (uint8_t *)pixman_image_get_data(canvas->image);
+ int stride = pixman_image_get_stride(canvas->image);
//using QRegion in order to sort and remove intersections
QRegion region;
@@ -1402,11 +1412,13 @@ void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
width = bbox->right - bbox->left;
heigth = bbox->bottom - bbox->top;
surface = canvas_surface_from_self(canvas, src_pos, width, heigth);
- cairo_set_source_surface(cairo, surface, bbox->left, bbox->top);
- cairo_surface_destroy(surface);
+ cairo_surface = surface_from_pixman_image (surface);
+ cairo_set_source_surface(cairo, cairo_surface, bbox->left, bbox->top);
cairo_rectangle(cairo, bbox->left, bbox->top, width, heigth);
cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY);
cairo_fill(cairo);
+ cairo_surface_destroy(cairo_surface);
+ pixman_image_unref (surface);
#ifdef FAST_COPY_BITS
}
@@ -1417,16 +1429,18 @@ void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
static void canvas_draw_raster_str(CairoCanvas *canvas, SpiceString *str, int bpp,
SpiceBrush *brush, uint16_t rop_decriptor)
{
- cairo_surface_t *str_mask;
+ pixman_image_t *str_mask;
+ cairo_surface_t *cairo_str_mask;
DrawMaskData draw_data;
cairo_matrix_t matrix;
SpicePoint pos;
str_mask = canvas_get_str_mask(&canvas->base, str, bpp, &pos);
+ cairo_str_mask = surface_from_pixman_image (str_mask);
draw_data.cairo = canvas->cairo;
- draw_data.mask = cairo_pattern_create_for_surface(str_mask);
+ draw_data.mask = cairo_pattern_create_for_surface(cairo_str_mask);
if (cairo_pattern_status(draw_data.mask) != CAIRO_STATUS_SUCCESS) {
- cairo_surface_destroy(str_mask);
+ cairo_surface_destroy(cairo_str_mask);
CANVAS_ERROR("create pattern failed, %s",
cairo_status_to_string(cairo_pattern_status(draw_data.mask)));
}
@@ -1434,7 +1448,8 @@ static void canvas_draw_raster_str(CairoCanvas *canvas, SpiceString *str, int bp
cairo_pattern_set_matrix(draw_data.mask, &matrix);
canvas_draw(canvas, brush, rop_decriptor, __draw_mask, &draw_data);
cairo_pattern_destroy(draw_data.mask);
- cairo_surface_destroy(str_mask);
+ pixman_image_unref(str_mask);
+ cairo_surface_destroy(cairo_str_mask);
}
static void canvas_draw_vector_str(CairoCanvas *canvas, SpiceString *str, SpiceBrush *brush,
diff --git a/common/canvas_base.c b/common/canvas_base.c
index 0ddbaf44..f5a6d336 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <setjmp.h>
#include <stdio.h>
+#include <math.h>
#include <spice/draw.h>
#include "quic.h"
@@ -76,6 +77,8 @@
#define MAX(x, y) (((x) >= (y)) ? (x) : (y))
#endif
+#define ROUND(_x) floor((_x) + 0.5)
+
#ifdef WIN32
typedef struct __declspec (align(1)) LZImage {
#else
@@ -88,12 +91,7 @@ typedef struct __attribute__ ((__packed__)) LZImage {
};
} LZImage;
-static const cairo_user_data_key_t invers_data_type = {0};
-
-#ifdef CAIRO_CANVAS_CACH_IS_SHARED
-/* should be defined and initialized once in application.cpp */
-extern mutex_t cairo_surface_user_data_mutex;
-#endif
+static const cairo_user_data_key_t pixman_data_type = {0};
static inline double fix_to_double(SPICE_FIXED28_4 fixed)
{
@@ -234,9 +232,13 @@ 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_t *)cairo_surface_get_user_data(surface, &pixman_data_type);
+
+ if (image)
+ return pixman_image_ref (image);
+
image = pixman_image_create_bits (pixman_format_from_cairo_format (format),
cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface),
@@ -246,6 +248,44 @@ pixman_image_from_surface (cairo_surface_t *surface)
return image;
}
+static cairo_format_t
+cairo_format_from_depth (int depth)
+{
+ switch (depth) {
+ case 1:
+ return CAIRO_FORMAT_A1;
+ case 8:
+ return CAIRO_FORMAT_A8;
+ case 24:
+ return CAIRO_FORMAT_RGB24;
+ case 32:
+ default:
+ return CAIRO_FORMAT_ARGB32;
+ }
+}
+
+static cairo_surface_t *
+surface_from_pixman_image (pixman_image_t *image)
+{
+ cairo_surface_t *surface;
+ int depth;
+
+ depth = pixman_image_get_depth (image);
+
+ surface = cairo_image_surface_create_for_data ((uint8_t *)pixman_image_get_data (image),
+ cairo_format_from_depth (depth),
+ pixman_image_get_width (image),
+ pixman_image_get_height (image),
+ pixman_image_get_stride (image));
+
+
+ if (cairo_surface_set_user_data (surface, &pixman_data_type,
+ image, (cairo_destroy_func_t) pixman_image_unref) == CAIRO_STATUS_SUCCESS)
+ pixman_image_ref (image);
+
+ return surface;
+}
+
#endif
static inline void canvas_localize_palette(CanvasBase *canvas, SpicePalette *palette)
@@ -261,11 +301,11 @@ static inline void canvas_localize_palette(CanvasBase *canvas, SpicePalette *pal
//#define DEBUG_DUMP_COMPRESS
#ifdef DEBUG_DUMP_COMPRESS
-static void dump_surface(cairo_surface_t *surface, int cache);
+static void dump_surface(pixman_image_t *surface, int cache);
#endif
-static cairo_surface_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *image, int invers)
+static pixman_image_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *image, int invers)
{
- cairo_surface_t *surface = NULL;
+ pixman_image_t *surface = NULL;
QuicData *quic_data = &canvas->quic_data;
QuicImageType type;
uint8_t *dest;
@@ -279,7 +319,7 @@ static cairo_surface_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *imag
#endif
if (setjmp(quic_data->jmp_env)) {
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
CANVAS_ERROR("quic error, %s", quic_data->message_buf);
}
@@ -320,18 +360,18 @@ static cairo_surface_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *imag
#ifdef WIN32
canvas->dc,
#endif
- alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
+ alpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
width, height, FALSE);
- if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(surface)));
+ if (surface == NULL) {
+ CANVAS_ERROR("create surface failed");
}
- dest = cairo_image_surface_get_data(surface);
- stride = cairo_image_surface_get_stride(surface);
+ dest = (uint8_t *)pixman_image_get_data(surface);
+ stride = pixman_image_get_stride(surface);
if (quic_decode(quic_data->quic, alpha ? QUIC_IMAGE_TYPE_RGBA : QUIC_IMAGE_TYPE_RGB32,
dest, stride) == QUIC_ERROR) {
+ pixman_image_unref(surface);
CANVAS_ERROR("quic decode failed");
}
@@ -463,33 +503,32 @@ static inline void canvas_copy_1bpp_be(uint8_t* dest, int dest_stride, uint8_t*
}
}
-static cairo_surface_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap* bitmap,
- SpicePalette *palette)
+static pixman_image_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap* bitmap,
+ SpicePalette *palette)
{
uint8_t* src = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
int src_stride;
uint8_t* end;
uint8_t* dest;
int dest_stride;
- cairo_surface_t* cairo_surface;
+ pixman_image_t* image;
src_stride = bitmap->stride;
end = src + (bitmap->y * src_stride);
access_test(canvas, src, bitmap->y * src_stride);
- cairo_surface = surface_create(
+ image = surface_create(
#ifdef WIN32
canvas->dc,
#endif
- (bitmap->format == SPICE_BITMAP_FMT_RGBA) ? CAIRO_FORMAT_ARGB32 :
- CAIRO_FORMAT_RGB24,
+ (bitmap->format == SPICE_BITMAP_FMT_RGBA) ? PIXMAN_a8r8g8b8 :
+ PIXMAN_x8r8g8b8,
bitmap->x, bitmap->y, FALSE);
- if (cairo_surface_status(cairo_surface) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(cairo_surface)));
+ if (image == NULL) {
+ CANVAS_ERROR("create surface failed");
}
- dest = cairo_image_surface_get_data(cairo_surface);
- dest_stride = cairo_image_surface_get_stride(cairo_surface);
+ dest = (uint8_t *)pixman_image_get_data(image);
+ dest_stride = pixman_image_get_stride(image);
if (!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
ASSERT(bitmap->y > 0);
dest += dest_stride * ((int)bitmap->y - 1);
@@ -517,7 +556,7 @@ static cairo_surface_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap
canvas_copy_1bpp_be(dest, dest_stride, src, src_stride, bitmap->x, end, palette);
break;
}
- return cairo_surface;
+ return image;
}
#ifdef CAIRO_CANVAS_CACHE
@@ -544,7 +583,7 @@ static inline SpicePalette *canvas_get_palett(CanvasBase *canvas, SPICE_ADDRESS
return palette;
}
-static cairo_surface_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int invers)
+static pixman_image_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int invers)
{
LzData *lz_data = &canvas->lz_data;
uint8_t *comp_buf = NULL;
@@ -612,7 +651,7 @@ static cairo_surface_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int in
alloc_lz_image_surface(&lz_data->decode_data, alpha ? LZ_IMAGE_TYPE_RGBA : LZ_IMAGE_TYPE_RGB32,
width, height, n_comp_pixels, top_down);
- src = cairo_image_surface_get_data(lz_data->decode_data.out_surface);
+ src = (uint8_t *)pixman_image_get_data(lz_data->decode_data.out_surface);
stride = (n_comp_pixels / height) * 4;
if (!top_down) {
@@ -644,7 +683,7 @@ static cairo_surface_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int in
// don't handle plts since bitmaps with plt can be decoded globaly to RGB32 (because
// same byte sequence can be transformed to different RGB pixels by different plts)
-static cairo_surface_t *canvas_get_glz(CanvasBase *canvas, LZImage *image)
+static pixman_image_t *canvas_get_glz(CanvasBase *canvas, LZImage *image)
{
ASSERT(image->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB);
#ifdef WIN32
@@ -696,9 +735,9 @@ static void dump_bitmap(SpiceBitmap *bitmap, SpicePalette *palette)
#endif
-static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
+static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
{
- cairo_surface_t* surface;
+ pixman_image_t* surface;
SpicePalette *palette;
palette = canvas_get_palett(canvas, bitmap->palette, bitmap->flags);
@@ -720,7 +759,7 @@ static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
#else
-static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
+static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
{
SpicePalette *palette;
@@ -731,7 +770,7 @@ static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
if (canvas->color_shift == 5) {
int size = sizeof(SpicePalette) + (palette->num_ents << 2);
SpicePalette *local_palette = malloc(size);
- cairo_surface_t* surface;
+ pixman_image_t* surface;
memcpy(local_palette, palette, size);
canvas_localize_palette(canvas, local_palette);
@@ -754,21 +793,21 @@ static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
#if defined(DEBUG_DUMP_SURFACE) || defined(DEBUG_DUMP_COMPRESS)
-static void dump_surface(cairo_surface_t *surface, int cache)
+static void dump_surface(pixman_image_t *surface, int cache)
{
static uint32_t file_id = 0;
int i, j;
char file_str[200];
- cairo_format_t format = cairo_image_surface_get_format(surface);
+ int depth = pixman_image_get_depth(surface);
- if (format != CAIRO_FORMAT_RGB24 && format != CAIRO_FORMAT_ARGB32) {
+ if (depth != 24 && depth != 32) {
return;
}
- uint8_t *data = cairo_image_surface_get_data(surface);
- int width = cairo_image_surface_get_width(surface);
- int height = cairo_image_surface_get_height(surface);
- int stride = cairo_image_surface_get_stride(surface);
+ uint8_t *data = (uint8_t *)pixman_image_get_data(surface);
+ int width = pixman_image_get_width(surface);
+ int height = pixman_image_get_height(surface);
+ int stride = pixman_image_surface_get_stride(surface);
uint32_t id = ++file_id;
#ifdef WIN32
@@ -800,17 +839,12 @@ static void dump_surface(cairo_surface_t *surface, int cache)
#if defined(CAIRO_CANVAS_CACHE) || defined(CAIRO_CANVAS_IMAGE_CACHE)
-static void __release_surface(void *inv_surf)
-{
- cairo_surface_destroy((cairo_surface_t *)inv_surf);
-}
-
//#define DEBUG_LZ
-static cairo_surface_t *canvas_get_image(CanvasBase *canvas, SPICE_ADDRESS addr)
+static pixman_image_t *canvas_get_image(CanvasBase *canvas, SPICE_ADDRESS addr)
{
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
- cairo_surface_t *surface;
+ pixman_image_t *surface;
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
#ifdef DEBUG_LZ
LOG_DEBUG("canvas_get_image image type: " << (int)descriptor->type);
@@ -872,7 +906,7 @@ static cairo_surface_t *canvas_get_image(CanvasBase *canvas, SPICE_ADDRESS addr)
#else
-static cairo_surface_t *canvas_get_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
+static pixman_image_t *canvas_get_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
{
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
@@ -909,9 +943,9 @@ static inline uint8_t revers_bits(uint8_t byte)
return ret;
}
-static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* bitmap, int invers)
+static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* bitmap, int invers)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
uint8_t *src_line;
uint8_t *end_line;
uint8_t *dest_line;
@@ -923,10 +957,9 @@ static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap*
#ifdef WIN32
canvas->dc,
#endif
- CAIRO_FORMAT_A1, bitmap->x, bitmap->y, TRUE);
- if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(surface)));
+ PIXMAN_a1, bitmap->x, bitmap->y, TRUE);
+ if (surface == NULL) {
+ CANVAS_ERROR("create surface failed");
}
src_line = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
@@ -935,8 +968,8 @@ static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap*
access_test(canvas, src_line, end_line - src_line);
line_size = ALIGN(bitmap->x, 8) >> 3;
- dest_stride = cairo_image_surface_get_stride(surface);
- dest_line = cairo_image_surface_get_data(surface);
+ dest_stride = pixman_image_get_stride(surface);
+ dest_line = (uint8_t *)pixman_image_get_data(surface);
#if defined(GL_CANVAS)
if ((bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
#else
@@ -979,7 +1012,8 @@ static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap*
}
break;
default:
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
+ surface = NULL;
CANVAS_ERROR("invalid bitmap format");
}
} else {
@@ -1009,26 +1043,27 @@ static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap*
}
break;
default:
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
+ surface = NULL;
CANVAS_ERROR("invalid bitmap format");
}
}
return surface;
}
-static inline cairo_surface_t *canvas_A1_invers(cairo_surface_t *src_surf)
+static inline pixman_image_t *canvas_A1_invers(pixman_image_t *src_surf)
{
- int width = cairo_image_surface_get_width(src_surf);
- int height = cairo_image_surface_get_height(src_surf);
+ int width = pixman_image_get_width(src_surf);
+ int height = pixman_image_get_height(src_surf);
- cairo_surface_t * invers = cairo_image_surface_create(CAIRO_FORMAT_A1, width, height);
- if (cairo_surface_status(invers) == CAIRO_STATUS_SUCCESS) {
- uint8_t *src_line = cairo_image_surface_get_data(src_surf);
- int src_stride = cairo_image_surface_get_stride(src_surf);
+ pixman_image_t * invers = pixman_image_create_bits(PIXMAN_a1, width, height, NULL, 0);
+ if (invers != NULL) {
+ uint8_t *src_line = (uint8_t *)pixman_image_get_data(src_surf);
+ int src_stride = pixman_image_get_stride(src_surf);
uint8_t *end_line = src_line + (height * src_stride);
int line_size = ALIGN(width, 8) >> 3;
- uint8_t *dest_line = cairo_image_surface_get_data(invers);
- int dest_stride = cairo_image_surface_get_stride(invers);
+ uint8_t *dest_line = (uint8_t *)pixman_image_get_data(invers);
+ int dest_stride = pixman_image_get_stride(invers);
for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
uint8_t *dest = dest_line;
@@ -1042,29 +1077,28 @@ static inline cairo_surface_t *canvas_A1_invers(cairo_surface_t *src_surf)
return invers;
}
-static cairo_surface_t *canvas_surf_to_invers(cairo_surface_t *surf)
+static pixman_image_t *canvas_surf_to_invers(pixman_image_t *surf)
{
- int width = cairo_image_surface_get_width(surf);
- int height = cairo_image_surface_get_height(surf);
+ int width = pixman_image_get_width(surf);
+ int height = pixman_image_get_height(surf);
uint8_t *dest_line;
uint8_t *dest_line_end;
uint8_t *src_line;
int dest_stride;
int src_stride;
- ASSERT(cairo_image_surface_get_format(surf) == CAIRO_FORMAT_RGB24);
- cairo_surface_t *invers = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
+ ASSERT(pixman_image_get_depth(surf) == 24);
+ pixman_image_t *invers = pixman_image_create_bits (PIXMAN_x8r8g8b8, width, height, NULL, 0);
- if (cairo_surface_status(invers) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(invers)));
+ if (invers == NULL) {
+ CANVAS_ERROR("create surface failed");
}
- dest_line = cairo_image_surface_get_data(invers);
- dest_stride = cairo_image_surface_get_stride(invers);
+ dest_line = (uint8_t *)pixman_image_get_data(invers);
+ dest_stride = pixman_image_get_stride(invers);
dest_line_end = dest_line + dest_stride * height;
- src_line = cairo_image_surface_get_data(surf);
- src_stride = cairo_image_surface_get_stride(surf);
+ src_line = (uint8_t *)pixman_image_get_data(surf);
+ src_stride = pixman_image_get_stride(surf);
for (; dest_line != dest_line_end; dest_line += dest_stride, src_line += src_stride) {
uint32_t *src = (uint32_t *)src_line;
@@ -1083,53 +1117,27 @@ static cairo_surface_t *canvas_surf_to_invers(cairo_surface_t *surf)
* the returned reference, you must call cairo_surface_destroy.
* Thread safe with respect to the user data.
*/
-static inline cairo_surface_t* canvas_handle_inverse_user_data(cairo_surface_t* surface)
+static inline pixman_image_t* canvas_handle_inverse_user_data(pixman_image_t* surface)
{
- cairo_surface_t *inv_surf = NULL;
-#ifdef CAIRO_CANVAS_CACH_IS_SHARED
- MUTEX_LOCK(cairo_surface_user_data_mutex);
-#endif
- inv_surf = (cairo_surface_t *)cairo_surface_get_user_data(surface, &invers_data_type);
-#ifdef CAIRO_CANVAS_CACH_IS_SHARED
- MUTEX_UNLOCK(cairo_surface_user_data_mutex);
-#endif
- if (!inv_surf) {
- if (cairo_image_surface_get_format(surface) == CAIRO_FORMAT_A1) {
- inv_surf = canvas_A1_invers(surface);
- } else {
- inv_surf = canvas_surf_to_invers(surface);
- }
+ pixman_image_t *inv_surf = NULL;
- if (cairo_surface_status(inv_surf) != CAIRO_STATUS_SUCCESS) {
- cairo_surface_destroy(inv_surf);
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(surface)));
- }
-#ifdef CAIRO_CANVAS_CACH_IS_SHARED
- MUTEX_LOCK(cairo_surface_user_data_mutex);
-
- // checking if other thread has already assigned the user data
- if (!cairo_surface_get_user_data(surface, &invers_data_type)) {
-#endif
- if (cairo_surface_set_user_data(surface, &invers_data_type, inv_surf,
- __release_surface) == CAIRO_STATUS_SUCCESS) {
- cairo_surface_reference(inv_surf);
- }
-#ifdef CAIRO_CANVAS_CACH_IS_SHARED
- }
- MUTEX_UNLOCK(cairo_surface_user_data_mutex);
-#endif
+ if (pixman_image_get_depth(surface) == 1) {
+ inv_surf = canvas_A1_invers(surface);
} else {
- cairo_surface_reference(inv_surf);
+ inv_surf = canvas_surf_to_invers(surface);
+ }
+
+ if (inv_surf == NULL) {
+ CANVAS_ERROR("create surface failed");
}
return inv_surf;
}
-static cairo_surface_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask)
+static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask)
{
SpiceImageDescriptor *descriptor;
- cairo_surface_t *surface;
+ pixman_image_t *surface;
int need_invers;
int is_invers;
int cache_me;
@@ -1172,11 +1180,11 @@ static cairo_surface_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask)
}
if (need_invers && !is_invers) { // surface is in cache
- cairo_surface_t *inv_surf;
+ pixman_image_t *inv_surf;
inv_surf = canvas_handle_inverse_user_data(surface);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
surface = inv_surf;
}
#endif
@@ -1332,12 +1340,12 @@ static void canvas_put_glyph_bits(SpiceRasterGlyph *glyph, int bpp, uint8_t *des
}
}
-static cairo_surface_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str, int bpp, SpicePoint *pos)
+static pixman_image_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str, int bpp, SpicePoint *pos)
{
SpiceRasterGlyph *glyph = (SpiceRasterGlyph *)str->data;
SpiceRasterGlyph *next_glyph;
SpiceRect bounds;
- cairo_surface_t *str_mask;
+ pixman_image_t *str_mask;
uint8_t *dest;
int dest_stride;
int i;
@@ -1360,15 +1368,14 @@ static cairo_surface_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str
rect_union(&bounds, &glyph_box);
}
- str_mask = cairo_image_surface_create((bpp == 1) ? CAIRO_FORMAT_A1 : CAIRO_FORMAT_A8,
- bounds.right - bounds.left,
- bounds.bottom - bounds.top);
- if (cairo_surface_status(str_mask) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(str_mask)));
+ str_mask = pixman_image_create_bits((bpp == 1) ? PIXMAN_a1 : PIXMAN_a8,
+ bounds.right - bounds.left,
+ bounds.bottom - bounds.top, NULL, 0);
+ if (str_mask == NULL) {
+ CANVAS_ERROR("create surface failed");
}
- dest = cairo_image_surface_get_data(str_mask);
- dest_stride = cairo_image_surface_get_stride(str_mask);
+ dest = (uint8_t *)pixman_image_get_data(str_mask);
+ dest_stride = pixman_image_get_stride(str_mask);
glyph = (SpiceRasterGlyph *)str->data;
for (i = 0; i < str->length; i++) {
#if defined(GL_CANVAS)
@@ -1390,47 +1397,39 @@ static inline SpiceVectorGlyph *canvas_next_vector_glyph(const SpiceVectorGlyph
return (SpiceVectorGlyph *)((uint8_t *)(glyph + 1) + glyph->data_size);
}
-static cairo_surface_t *canvas_scale_surface(cairo_surface_t *src, const SpiceRect *src_area, int width,
- int hight, int scale_mode)
+static pixman_image_t *canvas_scale_surface(pixman_image_t *src, const SpiceRect *src_area, int width,
+ int height, int scale_mode)
{
- cairo_t *cairo;
- cairo_surface_t *surface;
- cairo_pattern_t *pattern;
- cairo_matrix_t matrix;
+ pixman_image_t *surface;
+ pixman_transform_t transform;
double sx, sy;
- surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, hight);
- if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(surface)));
- }
-
- cairo = cairo_create(surface);
- if (cairo_status(cairo) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s", cairo_status_to_string(cairo_status(cairo)));
- }
-
- pattern = cairo_pattern_create_for_surface(src);
- if (cairo_pattern_status(pattern) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create pattern failed, %s",
- cairo_status_to_string(cairo_pattern_status(pattern)));
+ surface = pixman_image_create_bits(PIXMAN_x8r8g8b8, width, height, NULL, 0);
+ if (surface == NULL) {
+ CANVAS_ERROR("create surface failed");
}
sx = (double)(src_area->right - src_area->left) / width;
- sy = (double)(src_area->bottom - src_area->top) / hight;
+ sy = (double)(src_area->bottom - src_area->top) / height;
- cairo_matrix_init_translate(&matrix, src_area->left, src_area->top);
- cairo_matrix_scale(&matrix, sx, sy);
+ pixman_transform_init_scale(&transform, pixman_double_to_fixed(sx), pixman_double_to_fixed(sy));
- cairo_pattern_set_matrix(pattern, &matrix);
+ pixman_image_set_transform (src, &transform);
+ pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
ASSERT(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE || scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
- cairo_pattern_set_filter(pattern, (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
- CAIRO_FILTER_NEAREST : CAIRO_FILTER_GOOD);
+ pixman_image_set_filter(src,
+ (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
+ NULL, 0);
+
+ pixman_image_composite32(PIXMAN_OP_SRC,
+ src, NULL, surface,
+ ROUND(src_area->left / sx), ROUND (src_area->top / sy),
+ 0, 0, /* mask */
+ 0, 0, /* dst */
+ width, height);
+
+ pixman_image_set_transform(src, NULL);
- cairo_set_source(cairo, pattern);
- cairo_pattern_destroy(pattern);
- cairo_paint(cairo);
- cairo_destroy(cairo);
return surface;
}
diff --git a/common/canvas_base.h b/common/canvas_base.h
index cc750875..78ece624 100644
--- a/common/canvas_base.h
+++ b/common/canvas_base.h
@@ -20,7 +20,7 @@
#define _H_CANVAS_BASE
-#include "cairo.h"
+#include "pixman_utils.h"
#include "lz.h"
#include <spice/draw.h>
@@ -30,9 +30,9 @@ typedef struct _SpicePaletteCache SpicePaletteCache;
typedef struct {
void (*put)(SpiceImageCache *cache,
uint64_t id,
- cairo_surface_t *surface);
- cairo_surface_t *(*get)(SpiceImageCache *cache,
- uint64_t id);
+ pixman_image_t *surface);
+ pixman_image_t *(*get)(SpiceImageCache *cache,
+ uint64_t id);
} SpiceImageCacheOps;
struct _SpiceImageCache {
diff --git a/common/canvas_utils.c b/common/canvas_utils.c
index f6470cae..b70b17b3 100644
--- a/common/canvas_utils.c
+++ b/common/canvas_utils.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (C) 2009 Red Hat, Inc.
@@ -45,31 +46,50 @@ extern int gdi_handlers;
#define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
#endif
-const cairo_user_data_key_t bitmap_data_type = {0};
-const cairo_user_data_key_t bitmap_withstride_data_type = {0};
-
-#ifdef WIN32
-static void release_bitmap(void *bitmap_cache)
+static void release_data(pixman_image_t *image, void *release_data)
{
- DeleteObject((HBITMAP)((BitmapCache *)bitmap_cache)->bitmap);
- CloseHandle(((BitmapCache *)bitmap_cache)->mutex);
- free(bitmap_cache);
- gdi_handlers--;
-}
+ PixmanData *data = (PixmanData *)release_data;
+#ifdef WIN32
+ if (data->bitmap) {
+ DeleteObject((HBITMAP)data->bitmap);
+ CloseHandle(data->mutex);
+ gdi_handlers--;
+ }
#endif
+ if (data->data) {
+ free(data->data);
+ }
-static void release_withstride_bitmap(void *data)
-{
free(data);
}
-static inline cairo_surface_t *__surface_create_stride(cairo_format_t format, int width, int height,
- int stride)
+static PixmanData *
+pixman_image_add_data(pixman_image_t *image)
+{
+ PixmanData *data;
+
+ data = (PixmanData *)pixman_image_get_destroy_data(image);
+ if (data == NULL) {
+ data = (PixmanData *)calloc(1, sizeof(PixmanData));
+ if (data == NULL) {
+ CANVAS_ERROR("out of memory");
+ }
+ pixman_image_set_destroy_function(image,
+ release_data,
+ data);
+ }
+
+ return data;
+}
+
+static inline pixman_image_t *__surface_create_stride(pixman_format_code_t format, int width, int height,
+ int stride)
{
uint8_t *data;
uint8_t *stride_data;
- cairo_surface_t *surface;
+ pixman_image_t *surface;
+ PixmanData *pixman_data;
data = (uint8_t *)malloc(abs(stride) * height);
if (stride < 0) {
@@ -78,30 +98,24 @@ static inline cairo_surface_t *__surface_create_stride(cairo_format_t format, in
stride_data = data;
}
- surface = cairo_image_surface_create_for_data(stride_data, format, width, height, stride);
+ surface = pixman_image_create_bits(format, width, height, (uint32_t *)stride_data, stride);
- if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
+ if (surface == NULL) {
free(data);
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(surface)));
+ CANVAS_ERROR("create surface failed, out of memory");
}
- if (cairo_surface_set_user_data(surface, &bitmap_withstride_data_type, data,
- release_withstride_bitmap) != CAIRO_STATUS_SUCCESS) {
- free(data);
- cairo_surface_destroy(surface);
- CANVAS_ERROR("set_user_data surface failed, %s",
- cairo_status_to_string(cairo_surface_status(surface)));
- }
+ pixman_data = pixman_image_add_data(surface);
+ pixman_data->data = data;
return surface;
}
#ifdef WIN32
-cairo_surface_t *surface_create(HDC dc, cairo_format_t format,
+pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
int width, int height, int top_down)
#else
-cairo_surface_t * surface_create(cairo_format_t format, int width, int height, int top_down)
+pixman_image_t * surface_create(pixman_format_code_t format, int width, int height, int top_down)
#endif
{
#ifdef WIN32
@@ -120,8 +134,10 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
RGBQUAD palette[255];
} bitmap_info;
int nstride;
- cairo_surface_t *surface;
- BitmapCache *bitmap_cache;
+ pixman_image_t *surface;
+ PixmanData *pixman_data;
+ HBITMAP bitmap;
+ HANDLE mutex;
memset(&bitmap_info, 0, sizeof(bitmap_info));
bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
@@ -131,16 +147,16 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
bitmap_info.inf.bmiHeader.biPlanes = 1;
switch (format) {
- case CAIRO_FORMAT_ARGB32:
- case CAIRO_FORMAT_RGB24:
+ case PIXMAN_a8r8g8b8:
+ case PIXMAN_x8r8g8b8:
bitmap_info.inf.bmiHeader.biBitCount = 32;
nstride = width * 4;
break;
- case CAIRO_FORMAT_A8:
+ case PIXMAN_a8:
bitmap_info.inf.bmiHeader.biBitCount = 8;
nstride = ALIGN(width, 4);
break;
- case CAIRO_FORMAT_A1:
+ case PIXMAN_a1:
bitmap_info.inf.bmiHeader.biBitCount = 1;
nstride = ALIGN(width, 32) / 8;
break;
@@ -150,25 +166,15 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
- bitmap_cache = (BitmapCache *)malloc(sizeof(*bitmap_cache));
- if (!bitmap_cache) {
- CANVAS_ERROR("malloc failed");
- return NULL;
- }
-
- bitmap_cache->mutex = CreateMutex(NULL, 0, NULL);
- if (!bitmap_cache->mutex) {
- free(bitmap_cache);
+ mutex = CreateMutex(NULL, 0, NULL);
+ if (!mutex) {
CANVAS_ERROR("Unable to CreateMutex");
- return NULL;
}
- bitmap_cache->bitmap = CreateDIBSection(dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
- if (!bitmap_cache->bitmap) {
+ bitmap = CreateDIBSection(dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
+ if (!bitmap) {
CloseHandle(bitmap_cache->mutex);
- free(bitmap_cache);
CANVAS_ERROR("Unable to CreateDIBSection");
- return NULL;
}
if (top_down) {
@@ -178,41 +184,33 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
nstride = -nstride;
}
- surface = cairo_image_surface_create_for_data(src, format, width, height, nstride);
- if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
- CloseHandle(bitmap_cache->mutex);
- DeleteObject((HBITMAP)bitmap_cache->bitmap);
- free(bitmap_cache);
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(surface)));
- }
- if (cairo_surface_set_user_data(surface, &bitmap_data_type, bitmap_cache,
- release_bitmap) != CAIRO_STATUS_SUCCESS) {
- CloseHandle(bitmap_cache->mutex);
- cairo_surface_destroy(surface);
- DeleteObject((HBITMAP)bitmap_cache->bitmap);
- free(bitmap_cache);
- CANVAS_ERROR("set_user_data surface failed, %s",
- cairo_status_to_string(cairo_surface_status(surface)));
+ surface = pixman_image_create_bits(format, width, height, (uint32_t *)src, stride);
+ if (surface == NULL) {
+ CloseHandle(mutex);
+ DeleteObject(bitmap);
+ CANVAS_ERROR("create surface failed, out of memory");
}
+ pixman_data = pixman_image_add_data(surface);
+ pixman_data.bitmap = bitmap;
+ pixman_data.mutex = mutex;
gdi_handlers++;
return surface;
} else {
#endif
if (top_down) {
- return cairo_image_surface_create(format, width, height);
+ return pixman_image_create_bits(format, width, height, NULL, 0);
} else {
// NOTE: we assume here that the lz decoders always decode to RGB32.
int stride = 0;
switch (format) {
- case CAIRO_FORMAT_ARGB32:
- case CAIRO_FORMAT_RGB24:
+ case PIXMAN_a8r8g8b8:
+ case PIXMAN_x8r8g8b8:
stride = width * 4;
break;
- case CAIRO_FORMAT_A8:
+ case PIXMAN_a8:
stride = ALIGN(width, 4);
break;
- case CAIRO_FORMAT_A1:
+ case PIXMAN_a1:
stride = ALIGN(width, 32) / 8;
break;
default:
@@ -228,11 +226,11 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
}
#ifdef WIN32
-cairo_surface_t *surface_create_stride(HDC dc, cairo_format_t format, int width, int height,
- int stride)
+pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
+ int stride)
#else
-cairo_surface_t *surface_create_stride(cairo_format_t format, int width, int height,
- int stride)
+pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
+ int stride)
#endif
{
#ifdef WIN32
@@ -246,12 +244,12 @@ cairo_surface_t *surface_create_stride(cairo_format_t format, int width, int hei
return __surface_create_stride(format, width, height, stride);
}
-cairo_surface_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageType type, int width,
- int height, int gross_pixels, int top_down)
+pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageType type, int width,
+ int height, int gross_pixels, int top_down)
{
int stride;
int alpha;
- cairo_surface_t *surface = NULL;
+ pixman_image_t *surface = NULL;
stride = (gross_pixels / height) * 4;
@@ -270,7 +268,7 @@ cairo_surface_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageTyp
#ifdef WIN32
canvas_data->dc,
#endif
- alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height, stride);
+ alpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8, width, height, stride);
canvas_data->out_surface = surface;
return surface;
}
diff --git a/common/canvas_utils.h b/common/canvas_utils.h
index 10f2d640..4fdbe6a8 100644
--- a/common/canvas_utils.h
+++ b/common/canvas_utils.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (C) 2009 Red Hat, Inc.
@@ -20,31 +21,30 @@
#include <spice/types.h>
-#include "cairo.h"
+#include "pixman_utils.h"
#include "lz.h"
+typedef struct PixmanData {
#ifdef WIN32
-typedef struct BitmapCache {
HBITMAP bitmap;
HANDLE mutex;
-} BitmapCache;
#endif
-
-extern const cairo_user_data_key_t bitmap_data_type;
+ uint8_t *data;
+} PixmanData;
#ifdef WIN32
-cairo_surface_t *surface_create(HDC dc, cairo_format_t format,
- int width, int height, int top_down);
+pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
+ int width, int height, int top_down);
#else
-cairo_surface_t *surface_create(cairo_format_t format, int width, int height, int top_down);
+pixman_image_t *surface_create(pixman_format_code_t format, int width, int height, int top_down);
#endif
#ifdef WIN32
-cairo_surface_t *surface_create_stride(HDC dc, cairo_format_t format, int width, int height,
- int stride);
+pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
+ int stride);
#else
-cairo_surface_t *surface_create_stride(cairo_format_t format, int width, int height,
- int stride);
+pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
+ int stride);
#endif
@@ -52,10 +52,10 @@ typedef struct LzDecodeUsrData {
#ifdef WIN32
HDC dc;
#endif
- cairo_surface_t *out_surface;
+ pixman_image_t *out_surface;
} LzDecodeUsrData;
-cairo_surface_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageType type, int width,
- int height, int gross_pixels, int top_down);
+pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageType type, int width,
+ int height, int gross_pixels, int top_down);
#endif
diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c
index bc9f8b22..66f8a02c 100644
--- a/common/gdi_canvas.c
+++ b/common/gdi_canvas.c
@@ -305,15 +305,15 @@ uint32_t raster_ops[] = {
0x00FF0062 // 1 WHITENESS
};
-static inline void surface_to_image(cairo_surface_t *surface, GdiImage *image)
+static inline void surface_to_image(pixman_image_t *surface, GdiImage *image)
{
- cairo_format_t format = cairo_image_surface_get_format(surface);
+ int depth = pixman_image_surface_get_depth(surface);
- ASSERT(format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24);
- image->width = cairo_image_surface_get_width(surface);
- image->height = cairo_image_surface_get_height(surface);
- image->stride = cairo_image_surface_get_stride(surface);
- image->pixels = cairo_image_surface_get_data(surface);
+ ASSERT(depth == 32 || depth == 24);
+ image->width = pixman_image_get_width(surface);
+ image->height = pixman_image_get_height(surface);
+ image->stride = pixman_image_get_stride(surface);
+ image->pixels = pixman_image_get_data(surface);
}
static void set_path(GdiCanvas *canvas, void *addr)
@@ -645,7 +645,7 @@ static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush)
case SPICE_BRUSH_TYPE_PATTERN: {
GdiImage image;
HBRUSH hbrush;
- cairo_surface_t *surface;
+ pixman_image_t *surface;
HDC dc;
HBITMAP bitmap;
HBITMAP prev_bitmap;
@@ -664,7 +664,7 @@ static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush)
}
release_bitmap(dc, bitmap, prev_bitmap, 0);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
return hbrush;
}
case SPICE_BRUSH_TYPE_NONE:
@@ -779,27 +779,27 @@ uint8_t calc_rop3_src_brush(uint16_t rop3_bits)
static struct BitmapData get_mask_bitmap(struct GdiCanvas *canvas, struct SpiceQMask *mask)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
struct BitmapData bitmap;
- BitmapCache *bitmap_cache;
+ PixmanData *pixman_data;
bitmap.hbitmap = NULL;
if (!(surface = canvas_get_mask(&canvas->base, mask))) {
return bitmap;
}
- bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
- if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
+ pixman_data = pixman_image_get_destroy_data (surface);
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
bitmap.dc = create_compatible_dc();
- bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, bitmap_cache->bitmap);
- bitmap.hbitmap = bitmap_cache->bitmap;
- ReleaseMutex(bitmap_cache->mutex);
+ bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, pixman_data->bitmap);
+ bitmap.hbitmap = pixman_data->bitmap;
+ ReleaseMutex(pixman_data->mutex);
bitmap.cache = 1;
} else if (!create_bitmap(&bitmap.hbitmap, &bitmap.prev_hbitmap, &bitmap.dc,
- cairo_image_surface_get_data(surface),
- cairo_image_surface_get_width(surface),
- cairo_image_surface_get_height(surface),
- cairo_image_surface_get_stride(surface), 1, 0)) {
+ pixman_image_get_data(surface),
+ pixman_image_get_width(surface),
+ pixman_image_get_height(surface),
+ pixman_image_get_stride(surface), 1, 0)) {
bitmap.hbitmap = NULL;
} else {
bitmap.cache = 0;
@@ -865,7 +865,7 @@ static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
SpiceString *str, int n, SpiceRect *dest,
SpiceRect *src, SpiceBrush *brush)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
struct BitmapData bitmap;
SpicePoint pos;
int dest_stride;
@@ -882,9 +882,9 @@ static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
bitmap.cache = 0;
bitmap_data = create_bitmap(&bitmap.hbitmap, &bitmap.prev_hbitmap,
&bitmap.dc, NULL,
- cairo_image_surface_get_width(surface),
- cairo_image_surface_get_height(surface),
- cairo_image_surface_get_stride(surface), 32, 0);
+ pixman_image_get_width(surface),
+ pixman_image_get_height(surface),
+ pixman_image_get_stride(surface), 32, 0);
if (!bitmap_data) {
return;
@@ -896,14 +896,14 @@ static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
dest->left = pos.x;
dest->top = pos.y;
- dest->right = pos.x + cairo_image_surface_get_width(surface);
- dest->bottom = pos.y + cairo_image_surface_get_height(surface);
+ dest->right = pos.x + pixman_image_get_width(surface);
+ dest->bottom = pos.y + pixman_image_get_height(surface);
src->left = 0;
src->top = 0;
- src->right = cairo_image_surface_get_width(surface);
- src->bottom = cairo_image_surface_get_height(surface);
+ src->right = pixman_image_get_width(surface);
+ src->bottom = pixman_image_get_height(surface);
- dest_stride = cairo_image_surface_get_width(surface);
+ dest_stride = pixman_image_get_width(surface);
switch (n) {
case 1:
dest_stride = dest_stride / 8;
@@ -926,10 +926,10 @@ static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
unset_brush(bitmap.dc, prev_hbrush);
- copy_bitmap_alpha(cairo_image_surface_get_data(surface),
- cairo_image_surface_get_height(surface),
- cairo_image_surface_get_width(surface),
- cairo_image_surface_get_stride(surface),
+ copy_bitmap_alpha(pixman_image_get_data(surface),
+ pixman_image_get_height(surface),
+ pixman_image_get_width(surface),
+ pixman_image_get_stride(surface),
bitmap_data, dest_stride, n);
BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
@@ -1000,30 +1000,30 @@ void gdi_canvas_draw_fill(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
void gdi_canvas_draw_copy(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GdiImage image;
struct BitmapData bitmapmask;
- BitmapCache *bitmap_cache;
+ PixmanData *pixman_data;
bitmapmask = get_mask_bitmap(canvas, &copy->mask);
surface = canvas_get_image(&canvas->base, copy->src_bitmap);
- bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
Lock lock(*canvas->lock);
set_scale_mode(canvas, copy->scale_mode);
set_clip(canvas, clip);
- if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
HDC dc;
HBITMAP prev_bitmap;
dc = create_compatible_dc();
- prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
gdi_draw_bitmap_redrop(canvas->dc, &copy->src_area, bbox, dc,
&bitmapmask, copy->rop_decriptor, 0);
SelectObject(dc, prev_bitmap);
DeleteObject(dc);
- ReleaseMutex(bitmap_cache->mutex);
+ ReleaseMutex(pixman_data->mutex);
} else {
surface_to_image(surface, &image);
gdi_draw_image(canvas->dc, &copy->src_area, bbox, image.pixels,
@@ -1033,7 +1033,7 @@ void gdi_canvas_draw_copy(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
free_mask(&bitmapmask);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
}
void gdi_canvas_put_image(GdiCanvas *canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
@@ -1127,26 +1127,26 @@ static void gdi_draw_image_transparent(GdiCanvas *canvas, HDC dest_dc, const Spi
void gdi_canvas_draw_transparent(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
SpiceTransparent* transparent)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GdiImage image;
- BitmapCache *bitmap_cache;
+ PixmanData *pixman_data;
surface = canvas_get_image(&canvas->base, transparent->src_bitmap);
- bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
Lock lock(*canvas->lock);
set_clip(canvas, clip);
- if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
HDC dc;
HBITMAP prev_bitmap;
dc = create_compatible_dc();
- prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox, dc,
transparent->true_color);
SelectObject(dc, prev_bitmap);
DeleteObject(dc);
- ReleaseMutex(bitmap_cache->mutex);
+ ReleaseMutex(pixman_data->mutex);
} else {
surface_to_image(surface, &image);
gdi_draw_image_transparent(canvas, canvas->dc, &transparent->src_area, bbox, image.pixels,
@@ -1154,7 +1154,7 @@ void gdi_canvas_draw_transparent(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *
transparent->true_color, 0);
}
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
}
static void gdi_draw_bitmap_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
@@ -1198,28 +1198,28 @@ static void gdi_draw_image_alpha(HDC dest_dc, const SpiceRect *src, const SpiceR
void gdi_canvas_draw_alpha_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GdiImage image;
- BitmapCache *bitmap_cache;
+ PixmanData *pixman_data;
int use_bitmap_alpha;
surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap);
- use_bitmap_alpha = cairo_image_surface_get_format(surface) == CAIRO_FORMAT_ARGB32;
- bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
+ use_bitmap_alpha = pixman_image_get_depth(surface) == 32;
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
Lock lock(*canvas->lock);
set_clip(canvas, clip);
- if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
HDC dc;
HBITMAP prev_bitmap;
dc = create_compatible_dc();
- prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, dc, alpha_blend->alpha,
use_bitmap_alpha);
SelectObject(dc, prev_bitmap);
DeleteObject(dc);
- ReleaseMutex(bitmap_cache->mutex);
+ ReleaseMutex(pixman_data->mutex);
} else {
surface_to_image(surface, &image);
gdi_draw_image_alpha(canvas->dc, &alpha_blend->src_area, bbox, image.pixels,
@@ -1227,21 +1227,21 @@ void gdi_canvas_draw_alpha_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *
alpha_blend->alpha, 0, use_bitmap_alpha);
}
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
}
void gdi_canvas_draw_opaque(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GdiImage image;
struct BitmapData bitmapmask;
- BitmapCache *bitmap_cache;
+ PixmanData *pixman_data;
HBRUSH prev_hbrush;
HBRUSH hbrush;
uint8_t rop3;
surface = canvas_get_image(&canvas->base, opaque->src_bitmap);
- bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
bitmapmask = get_mask_bitmap(canvas, &opaque->mask);
rop3 = calc_rop3_src_brush(opaque->rop_decriptor);
hbrush = get_brush(canvas, &opaque->brush);
@@ -1252,16 +1252,16 @@ void gdi_canvas_draw_opaque(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
set_clip(canvas, clip);
prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush);
- if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
HDC dc;
HBITMAP prev_bitmap;
dc = create_compatible_dc();
- prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3);
SelectObject(dc, prev_bitmap);
DeleteObject(dc);
- ReleaseMutex(bitmap_cache->mutex);
+ ReleaseMutex(pixman_data->mutex);
} else {
surface_to_image(surface, &image);
gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, image.pixels,
@@ -1272,35 +1272,35 @@ void gdi_canvas_draw_opaque(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
free_mask(&bitmapmask);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
}
void gdi_canvas_draw_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GdiImage image;
struct BitmapData bitmapmask;
- BitmapCache *bitmap_cache;
+ PixmanData *pixman_data;
bitmapmask = get_mask_bitmap(canvas, &blend->mask);
surface = canvas_get_image(&canvas->base, blend->src_bitmap);
- bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
Lock lock(*canvas->lock);
set_scale_mode(canvas, blend->scale_mode);
set_clip(canvas, clip);
- if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
HDC dc;
HBITMAP prev_bitmap;
dc = create_compatible_dc();
- prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, dc,
&bitmapmask, blend->rop_decriptor, 0);
SelectObject(dc, prev_bitmap);
DeleteObject(dc);
- ReleaseMutex(bitmap_cache->mutex);
+ ReleaseMutex(pixman_data->mutex);
} else {
surface_to_image(surface, &image);
gdi_draw_image(canvas->dc, &blend->src_area, bbox, image.pixels, image.stride, image.width,
@@ -1309,7 +1309,7 @@ void gdi_canvas_draw_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
free_mask(&bitmapmask);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
}
void gdi_canvas_draw_blackness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
@@ -1353,16 +1353,16 @@ void gdi_canvas_draw_whiteness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
void gdi_canvas_draw_rop3(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GdiImage image;
struct BitmapData bitmapmask;
HBRUSH prev_hbrush;
HBRUSH hbrush;
- BitmapCache *bitmap_cache;
+ PixmanData *pixman_data;
hbrush = get_brush(canvas, &rop3->brush);
surface = canvas_get_image(&canvas->base, rop3->src_bitmap);
- bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
bitmapmask = get_mask_bitmap(canvas, &rop3->mask);
Lock lock(*canvas->lock);
@@ -1370,17 +1370,17 @@ void gdi_canvas_draw_rop3(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
set_clip(canvas, clip);
prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush);
- if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
HDC dc;
HBITMAP prev_bitmap;
dc = create_compatible_dc();
- prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc,
&bitmapmask, rop3->rop3);
SelectObject(dc, prev_bitmap);
DeleteObject(dc);
- ReleaseMutex(bitmap_cache->mutex);
+ ReleaseMutex(pixman_data->mutex);
} else {
surface_to_image(surface, &image);
gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, image.pixels,
@@ -1390,7 +1390,7 @@ void gdi_canvas_draw_rop3(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
unset_brush(canvas->dc, prev_hbrush);
free_mask(&bitmapmask);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
}
void gdi_canvas_copy_bits(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
@@ -1517,7 +1517,7 @@ void gdi_canvas_draw_stroke(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
int ps_join = 0;
int line_cap = 0;
uint32_t *user_style = NULL;
- cairo_surface_t *surface = NULL;
+ pixman_image_t *surface = NULL;
if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
surface = canvas_get_image(&canvas->base, stroke->brush.u.pattern.pat);
@@ -1630,7 +1630,7 @@ void gdi_canvas_draw_stroke(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
logbrush.lbStyle = BS_DIBPATTERN | DIB_RGB_COLORS;
logbrush.lbColor = 0;
#endif
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
}
#if 0
diff --git a/common/gdi_canvas.h b/common/gdi_canvas.h
index 18a48438..febd9675 100644
--- a/common/gdi_canvas.h
+++ b/common/gdi_canvas.h
@@ -22,7 +22,7 @@
#include <stdint.h>
#include <spice/draw.h>
-#include "cairo.h"
+#include "pixman_utils.h"
#include "canvas_base.h"
#include "region.h"
diff --git a/common/gl_canvas.c b/common/gl_canvas.c
index 329d97b2..b6d584f1 100644
--- a/common/gl_canvas.c
+++ b/common/gl_canvas.c
@@ -71,8 +71,8 @@ static inline uint8_t *copy_opposite_image(GLCanvas *canvas, void *data, int str
return (uint8_t *)canvas->private_data;
}
-static cairo_surface_t *canvas_surf_to_trans_surf(GLCImage *image,
- uint32_t trans_color)
+static pixman_image_t *canvas_surf_to_trans_surf(GLCImage *image,
+ uint32_t trans_color)
{
int width = image->width;
int height = image->height;
@@ -81,21 +81,20 @@ static cairo_surface_t *canvas_surf_to_trans_surf(GLCImage *image,
int src_stride;
uint8_t *dest_line;
int dest_stride;
- cairo_surface_t *ret;
+ pixman_image_t *ret;
int i;
- ret = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
- if (cairo_surface_status(ret) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(ret)));
+ ret = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0);
+ if (ret == NULL) {
+ CANVAS_ERROR("create surface failed");
}
src_line = image->pixels;
src_stride = image->stride;
end_src_line = src_line + src_stride * height;
- dest_line = cairo_image_surface_get_data(ret);
- dest_stride = cairo_image_surface_get_stride(ret);
+ dest_line = (uint8_t *)pixman_image_get_data(ret);
+ dest_stride = pixman_image_get_stride(ret);
for (; src_line < end_src_line; src_line += src_stride, dest_line += dest_stride) {
for (i = 0; i < width; i++) {
@@ -209,32 +208,32 @@ static void set_clip(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip)
static void set_mask(GLCanvas *canvas, SpiceQMask *mask, int x, int y)
{
- cairo_surface_t *surface;
+ pixman_image_t *image;
- if (!(surface = canvas_get_mask(&canvas->base, mask))) {
+ if (!(image = canvas_get_mask(&canvas->base, mask))) {
glc_clear_mask(canvas->glc, GLC_MASK_A);
return;
}
glc_set_mask(canvas->glc, x - mask->pos.x, y - mask->pos.y,
- cairo_image_surface_get_width(surface),
- cairo_image_surface_get_height(surface),
- cairo_image_surface_get_stride(surface),
- cairo_image_surface_get_data(surface), GLC_MASK_A);
+ pixman_image_get_width(image),
+ pixman_image_get_height(image),
+ pixman_image_get_stride(image),
+ (uint8_t *)pixman_image_get_data(image), GLC_MASK_A);
}
-static inline void surface_to_image(GLCanvas *canvas, cairo_surface_t *surface, GLCImage *image,
+static inline void surface_to_image(GLCanvas *canvas, pixman_image_t *surface, GLCImage *image,
int ignore_stride)
{
- cairo_format_t format = cairo_image_surface_get_format(surface);
+ int depth = pixman_image_get_depth(surface);
- ASSERT(format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24);
- image->format = (format == CAIRO_FORMAT_RGB24) ? GLC_IMAGE_RGB32 : GLC_IMAGE_ARGB32;
- image->width = cairo_image_surface_get_width(surface);
- image->height = cairo_image_surface_get_height(surface);
- image->stride = cairo_image_surface_get_stride(surface);
- image->pixels = cairo_image_surface_get_data(surface);
+ ASSERT(depth == 32 || depth == 24);
+ image->format = (depth == 24) ? GLC_IMAGE_RGB32 : GLC_IMAGE_ARGB32;
+ image->width = pixman_image_get_width(surface);
+ image->height = pixman_image_get_height(surface);
+ image->stride = pixman_image_get_stride(surface);
+ image->pixels = (uint8_t *)pixman_image_get_data(surface);
image->pallet = NULL;
if (ignore_stride) {
return;
@@ -265,7 +264,7 @@ static void set_brush(GLCanvas *canvas, SpiceBrush *brush)
case SPICE_BRUSH_TYPE_PATTERN: {
GLCImage image;
GLCPattern pattern;
- cairo_surface_t *surface;
+ pixman_image_t *surface;
surface = canvas_get_image(&canvas->base, brush->u.pattern.pat);
surface_to_image(canvas, surface, &image, 0);
@@ -275,6 +274,7 @@ static void set_brush(GLCanvas *canvas, SpiceBrush *brush)
glc_set_pattern(canvas->glc, pattern);
glc_pattern_destroy(pattern);
+ pixman_image_unref (surface);
}
case SPICE_BRUSH_TYPE_NONE:
return;
@@ -358,7 +358,7 @@ void gl_canvas_draw_fill(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
void gl_canvas_draw_copy(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GLCRecti src;
GLCRecti dest;
GLCImage image;
@@ -374,13 +374,13 @@ void gl_canvas_draw_copy(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
SET_GLC_RECT(&src, &copy->src_area);
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
glc_flush(canvas->glc);
}
void gl_canvas_draw_opaque(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GLCRecti src;
GLCRecti dest;
GLCRect fill_rect;
@@ -396,7 +396,7 @@ void gl_canvas_draw_opaque(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
SET_GLC_RECT(&dest, bbox);
SET_GLC_RECT(&src, &opaque->src_area);
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
set_brush(canvas, &opaque->brush);
set_op(canvas, opaque->rop_decriptor & ~SPICE_ROPD_INVERS_SRC);
@@ -408,7 +408,7 @@ void gl_canvas_draw_opaque(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
void gl_canvas_draw_alpha_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd *alpha_blend)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GLCRecti src;
GLCRecti dest;
GLCImage image;
@@ -423,13 +423,13 @@ void gl_canvas_draw_alpha_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
SET_GLC_RECT(&src, &alpha_blend->src_area);
glc_draw_image(canvas->glc, &dest, &src, &image, 0, (double)alpha_blend->alpha / 0xff);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
glc_flush(canvas->glc);
}
void gl_canvas_draw_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
{
- cairo_surface_t *surface;
+ pixman_image_t *surface;
GLCRecti src;
GLCRecti dest;
GLCImage image;
@@ -444,14 +444,14 @@ void gl_canvas_draw_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Sp
surface_to_image(canvas, surface, &image, 0);
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
glc_flush(canvas->glc);
}
void gl_canvas_draw_transparent(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent *transparent)
{
- cairo_surface_t *surface;
- cairo_surface_t *trans_surf;
+ pixman_image_t *surface;
+ pixman_image_t *trans_surf;
GLCImage image;
GLCRecti src;
GLCRecti dest;
@@ -464,14 +464,14 @@ void gl_canvas_draw_transparent(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
surface_to_image(canvas, surface, &image, 0);
trans_surf = canvas_surf_to_trans_surf(&image, transparent->true_color);
- cairo_surface_destroy(surface);
+ pixman_image_unref(surface);
surface_to_image(canvas, trans_surf, &image, 1);
SET_GLC_RECT(&dest, bbox);
SET_GLC_RECT(&src, &transparent->src_area);
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
- cairo_surface_destroy(trans_surf);
+ pixman_image_unref(trans_surf);
glc_flush(canvas->glc);
}
@@ -503,8 +503,8 @@ void gl_canvas_draw_invers(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
void gl_canvas_draw_rop3(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
{
- cairo_surface_t *d;
- cairo_surface_t *s;
+ pixman_image_t *d;
+ pixman_image_t *s;
GLCImage image;
SpicePoint src_pos;
uint8_t *data_opp;
@@ -521,34 +521,33 @@ void gl_canvas_draw_rop3(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
image.pallet = NULL;
- d = cairo_image_surface_create(CAIRO_FORMAT_RGB24, image.width, image.height);
- if (cairo_surface_status(d) != CAIRO_STATUS_SUCCESS) {
- CANVAS_ERROR("create surface failed, %s",
- cairo_status_to_string(cairo_surface_status(d)));
+ d = pixman_image_create_bits(PIXMAN_x8r8g8b8, image.width, image.height, NULL, 0);
+ if (d == NULL) {
+ CANVAS_ERROR("create surface failed");
}
- image.pixels = cairo_image_surface_get_data(d);
- image.stride = cairo_image_surface_get_stride(d);
+ image.pixels = (uint8_t *)pixman_image_get_data(d);
+ image.stride = pixman_image_get_stride(d);
glc_read_pixels(canvas->glc, bbox->left, bbox->top, &image);
data_opp = copy_opposite_image(canvas, image.pixels,
- cairo_image_surface_get_stride(d),
- cairo_image_surface_get_height(d));
+ image.stride,
+ pixman_image_get_height(d));
memcpy(image.pixels, data_opp,
- cairo_image_surface_get_stride(d) * cairo_image_surface_get_height(d));
+ image.stride * pixman_image_get_height(d));
s = canvas_get_image(&canvas->base, rop3->src_bitmap);
- src_stride = cairo_image_surface_get_stride(s);
+ src_stride = pixman_image_get_stride(s);
if (src_stride > 0) {
- data_opp = copy_opposite_image(canvas, cairo_image_surface_get_data(s),
- src_stride, cairo_image_surface_get_height(s));
- memcpy(cairo_image_surface_get_data(s), data_opp,
- src_stride * cairo_image_surface_get_height(s));
+ data_opp = copy_opposite_image(canvas, (uint8_t *)pixman_image_get_data(s),
+ src_stride, pixman_image_get_height(s));
+ memcpy((uint8_t *)pixman_image_get_data(s), data_opp,
+ src_stride * pixman_image_get_height(s));
}
if (!rect_is_same_size(bbox, &rop3->src_area)) {
- cairo_surface_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, image.width,
- image.height, rop3->scale_mode);
- cairo_surface_destroy(s);
+ pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, image.width,
+ image.height, rop3->scale_mode);
+ pixman_image_unref(s);
s = scaled_s;
src_pos.x = 0;
src_pos.y = 0;
@@ -557,49 +556,49 @@ void gl_canvas_draw_rop3(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
src_pos.y = rop3->src_area.top;
}
- if (cairo_image_surface_get_width(s) - src_pos.x < image.width ||
- cairo_image_surface_get_height(s) - src_pos.y < image.height) {
+ if (pixman_image_get_width(s) - src_pos.x < image.width ||
+ pixman_image_get_height(s) - src_pos.y < image.height) {
CANVAS_ERROR("bad src bitmap size");
}
if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
- cairo_surface_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat);
+ pixman_image_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat);
SpicePoint pat_pos;
- pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % cairo_image_surface_get_width(p);
+ pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
- pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % cairo_image_surface_get_height(p);
+ pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
//for now (bottom-top)
if (pat_pos.y < 0) {
- pat_pos.y = cairo_image_surface_get_height(p) + pat_pos.y;
+ pat_pos.y = pixman_image_get_height(p) + pat_pos.y;
}
- pat_pos.y = (image.height + pat_pos.y) % cairo_image_surface_get_height(p);
- pat_pos.y = cairo_image_surface_get_height(p) - pat_pos.y;
+ pat_pos.y = (image.height + pat_pos.y) % pixman_image_get_height(p);
+ pat_pos.y = pixman_image_get_height(p) - pat_pos.y;
do_rop3_with_pattern(rop3->rop3, d, s, &src_pos, p, &pat_pos);
- cairo_surface_destroy(p);
+ pixman_image_unref(p);
} else {
uint32_t color = (canvas->base.color_shift) == 8 ? rop3->brush.u.color :
canvas_16bpp_to_32bpp(rop3->brush.u.color);
do_rop3_with_color(rop3->rop3, d, s, &src_pos, color);
}
- cairo_surface_destroy(s);
+ pixman_image_unref(s);
GLCRecti dest;
GLCRecti src;
dest.x = bbox->left;
dest.y = bbox->top;
- image.pixels = copy_opposite_image(canvas, image.pixels, cairo_image_surface_get_stride(d),
- cairo_image_surface_get_height(d));
+ image.pixels = copy_opposite_image(canvas, image.pixels, pixman_image_get_stride(d),
+ pixman_image_get_height(d));
src.x = src.y = 0;
dest.width = src.width = image.width;
dest.height = src.height = image.height;
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
- cairo_surface_destroy(d);
+ pixman_image_unref(d);
}
void gl_canvas_draw_stroke(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
@@ -641,34 +640,34 @@ void gl_canvas_draw_text(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
set_op(canvas, text->fore_mode);
if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) {
SpicePoint pos;
- cairo_surface_t *mask = canvas_get_str_mask(&canvas->base, str, 1, &pos);
+ pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 1, &pos);
_glc_fill_mask(canvas->glc, pos.x, pos.y,
- cairo_image_surface_get_width(mask),
- cairo_image_surface_get_height(mask),
- cairo_image_surface_get_stride(mask),
- cairo_image_surface_get_data(mask));
- cairo_surface_destroy(mask);
+ pixman_image_get_width(mask),
+ pixman_image_get_height(mask),
+ pixman_image_get_stride(mask),
+ (uint8_t *)pixman_image_get_data(mask));
+ pixman_image_unref(mask);
} else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) {
SpicePoint pos;
- cairo_surface_t *mask = canvas_get_str_mask(&canvas->base, str, 4, &pos);
+ pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 4, &pos);
glc_fill_alpha(canvas->glc, pos.x, pos.y,
- cairo_image_surface_get_width(mask),
- cairo_image_surface_get_height(mask),
- cairo_image_surface_get_stride(mask),
- cairo_image_surface_get_data(mask));
+ pixman_image_get_width(mask),
+ pixman_image_get_height(mask),
+ pixman_image_get_stride(mask),
+ (uint8_t *)pixman_image_get_data(mask));
- cairo_surface_destroy(mask);
+ pixman_image_unref(mask);
} else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) {
WARN("untested path A8 glyphs, doing nothing");
if (0) {
SpicePoint pos;
- cairo_surface_t *mask = canvas_get_str_mask(&canvas->base, str, 8, &pos);
+ pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 8, &pos);
glc_fill_alpha(canvas->glc, pos.x, pos.y,
- cairo_image_surface_get_width(mask),
- cairo_image_surface_get_height(mask),
- cairo_image_surface_get_stride(mask),
- cairo_image_surface_get_data(mask));
- cairo_surface_destroy(mask);
+ pixman_image_get_width(mask),
+ pixman_image_get_height(mask),
+ pixman_image_get_stride(mask),
+ (uint8_t *)pixman_image_get_data(mask));
+ pixman_image_unref(mask);
}
} else {
WARN("untested path vector glyphs, doing nothing");
diff --git a/common/rop3.c b/common/rop3.c
index 64baba80..014109f4 100644
--- a/common/rop3.c
+++ b/common/rop3.c
@@ -24,11 +24,11 @@
#define WARN(x) printf("warning: %s\n", x)
#endif
-typedef void (*rop3_with_pattern_handler_t)(cairo_surface_t *d, cairo_surface_t *s,
- SpicePoint *src_pos, cairo_surface_t *p,
+typedef void (*rop3_with_pattern_handler_t)(pixman_image_t *d, pixman_image_t *s,
+ SpicePoint *src_pos, pixman_image_t *p,
SpicePoint *pat_pos);
-typedef void (*rop3_with_color_handler_t)(cairo_surface_t *d, cairo_surface_t *s,
+typedef void (*rop3_with_color_handler_t)(pixman_image_t *d, pixman_image_t *s,
SpicePoint *src_pos, uint32_t rgb);
typedef void (*rop3_test_handler_t)();
@@ -40,14 +40,14 @@ static rop3_with_color_handler_t rop3_with_color_handlers[ROP3_NUM_OPS];
static rop3_test_handler_t rop3_test_handlers[ROP3_NUM_OPS];
-static void default_rop3_with_pattern_handler(cairo_surface_t *d, cairo_surface_t *s,
- SpicePoint *src_pos, cairo_surface_t *p,
+static void default_rop3_with_pattern_handler(pixman_image_t *d, pixman_image_t *s,
+ SpicePoint *src_pos, pixman_image_t *p,
SpicePoint *pat_pos)
{
WARN("not implemented 0x%x");
}
-static void default_rop3_withe_color_handler(cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
+static void default_rop3_withe_color_handler(pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
uint32_t rgb)
{
WARN("not implemented 0x%x");
@@ -58,24 +58,24 @@ static void default_rop3_test_handler()
}
#define ROP3_HANDLERS(name, formula, index) \
-static void rop3_handle_p_##name(cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos, \
- cairo_surface_t *p, SpicePoint *pat_pos) \
+static void rop3_handle_p_##name(pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos, \
+ pixman_image_t *p, SpicePoint *pat_pos) \
{ \
- int width = cairo_image_surface_get_width(d); \
- int height = cairo_image_surface_get_height(d); \
- uint8_t *dest_line = cairo_image_surface_get_data(d); \
- int dest_stride = cairo_image_surface_get_stride(d); \
+ int width = pixman_image_get_width(d); \
+ int height = pixman_image_get_height(d); \
+ uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d); \
+ int dest_stride = pixman_image_get_stride(d); \
uint8_t *end_line = dest_line + height * dest_stride; \
\
- int pat_width = cairo_image_surface_get_width(p); \
- int pat_height = cairo_image_surface_get_height(p); \
- uint8_t *pat_base = cairo_image_surface_get_data(p); \
- int pat_stride = cairo_image_surface_get_stride(p); \
+ int pat_width = pixman_image_get_width(p); \
+ int pat_height = pixman_image_get_height(p); \
+ uint8_t *pat_base = (uint8_t *)pixman_image_get_data(p); \
+ int pat_stride = pixman_image_get_stride(p); \
int pat_v_offset = pat_pos->y; \
\
- int src_stride = cairo_image_surface_get_stride(s); \
+ int src_stride = pixman_image_get_stride(s); \
uint8_t *src_line; \
- src_line = cairo_image_surface_get_data(s) + src_pos->y * src_stride + (src_pos->x << 2); \
+ src_line = (uint8_t *)pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x << 2); \
\
for (; dest_line < end_line; dest_line += dest_stride, src_line += src_stride) { \
uint32_t *dest = (uint32_t *)dest_line; \
@@ -95,19 +95,19 @@ static void rop3_handle_p_##name(cairo_surface_t *d, cairo_surface_t *s, SpicePo
} \
} \
\
-static void rop3_handle_c_##name(cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos, \
+static void rop3_handle_c_##name(pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos, \
uint32_t rgb) \
{ \
- int width = cairo_image_surface_get_width(d); \
- int height = cairo_image_surface_get_height(d); \
- uint8_t *dest_line = cairo_image_surface_get_data(d); \
- int dest_stride = cairo_image_surface_get_stride(d); \
+ int width = pixman_image_get_width(d); \
+ int height = pixman_image_get_height(d); \
+ uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d); \
+ int dest_stride = pixman_image_get_stride(d); \
uint8_t *end_line = dest_line + height * dest_stride; \
uint32_t *pat = &rgb; \
\
- int src_stride = cairo_image_surface_get_stride(s); \
+ int src_stride = pixman_image_get_stride(s); \
uint8_t *src_line; \
- src_line = cairo_image_surface_get_data(s) + src_pos->y * src_stride + (src_pos->x << 2); \
+ src_line = (uint8_t *)pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x << 2); \
\
for (; dest_line < end_line; dest_line += dest_stride, src_line += src_stride) { \
uint32_t *dest = (uint32_t *)dest_line; \
@@ -600,13 +600,13 @@ void rop3_init()
}
}
-void do_rop3_with_pattern(uint8_t rop3, cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
- cairo_surface_t *p, SpicePoint *pat_pos)
+void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
+ pixman_image_t *p, SpicePoint *pat_pos)
{
rop3_with_pattern_handlers[rop3](d, s, src_pos, p, pat_pos);
}
-void do_rop3_with_color(uint8_t rop3, cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
+void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
uint32_t rgb)
{
rop3_with_color_handlers[rop3](d, s, src_pos, rgb);
diff --git a/common/rop3.h b/common/rop3.h
index 32a62033..832ac511 100644
--- a/common/rop3.h
+++ b/common/rop3.h
@@ -22,11 +22,11 @@
#include <stdint.h>
#include <spice/draw.h>
-#include "cairo.h"
+#include "pixman_utils.h"
-void do_rop3_with_pattern(uint8_t rop3, cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
- cairo_surface_t *p, SpicePoint *pat_pos);
-void do_rop3_with_color(uint8_t rop3, cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
+void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
+ pixman_image_t *p, SpicePoint *pat_pos);
+void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
uint32_t rgb);
void rop3_init();
diff --git a/server/red_worker.c b/server/red_worker.c
index 85964cee..b2cb1f6e 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -722,7 +722,7 @@ typedef struct ImageCacheItem {
uint32_t age;
#endif
struct ImageCacheItem *next;
- cairo_surface_t *surf;
+ pixman_image_t *image;
} ImageCacheItem;
#define IMAGE_CACHE_HASH_SIZE 1024
@@ -3890,7 +3890,7 @@ static void image_cache_remove(ImageCache *cache, ImageCacheItem *item)
now = &(*now)->next;
}
ring_remove(&item->lru_link);
- cairo_surface_destroy(item->surf);
+ pixman_image_unref(item->image);
free(item);
#ifndef IMAGE_CACHE_AGE
cache->num_items--;
@@ -3899,7 +3899,7 @@ static void image_cache_remove(ImageCache *cache, ImageCacheItem *item)
#define IMAGE_CACHE_MAX_ITEMS 2
-static void image_cache_put(SpiceImageCache *spice_cache, uint64_t id, cairo_surface_t *surface)
+static void image_cache_put(SpiceImageCache *spice_cache, uint64_t id, pixman_image_t *image)
{
ImageCache *cache = (ImageCache *)spice_cache;
ImageCacheItem *item;
@@ -3921,7 +3921,7 @@ static void image_cache_put(SpiceImageCache *spice_cache, uint64_t id, cairo_sur
#else
cache->num_items++;
#endif
- item->surf = cairo_surface_reference(surface);
+ item->image = pixman_image_ref(image);
ring_item_init(&item->lru_link);
item->next = cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE];
@@ -3930,7 +3930,7 @@ static void image_cache_put(SpiceImageCache *spice_cache, uint64_t id, cairo_sur
ring_add(&cache->lru, &item->lru_link);
}
-static cairo_surface_t *image_cache_get(SpiceImageCache *spice_cache, uint64_t id)
+static pixman_image_t *image_cache_get(SpiceImageCache *spice_cache, uint64_t id)
{
ImageCache *cache = (ImageCache *)spice_cache;
@@ -3938,7 +3938,7 @@ static cairo_surface_t *image_cache_get(SpiceImageCache *spice_cache, uint64_t i
if (!item) {
red_error("not found");
}
- return cairo_surface_reference(item->surf);
+ return pixman_image_ref(item->image);
}
static void image_cache_init(ImageCache *cache)