From f4b7a9d00451455505f4fb8dc3516eb893ae41b0 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 9 Feb 2010 16:39:35 +0100 Subject: Use pixman_image_t instead of cairo_surface_t as the generic pixman container This allows us to use the simpler dependency of pixman outside of the cairo backend, and it later lets us move the cairo backend to using pixman only. --- common/cairo_canvas.c | 151 ++++++++++++----------- common/canvas_base.c | 323 +++++++++++++++++++++++++------------------------- common/canvas_base.h | 8 +- common/canvas_utils.c | 152 ++++++++++++------------ common/canvas_utils.h | 30 ++--- common/gdi_canvas.c | 156 ++++++++++++------------ common/gdi_canvas.h | 2 +- common/gl_canvas.c | 171 +++++++++++++------------- common/rop3.c | 56 ++++----- common/rop3.h | 8 +- 10 files changed, 534 insertions(+), 523 deletions(-) (limited to 'common') diff --git a/common/cairo_canvas.c b/common/cairo_canvas.c index 4b8c305..5ee7ccb 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 0ddbaf4..f5a6d33 100644 --- a/common/canvas_base.c +++ b/common/canvas_base.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #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 cc75087..78ece62 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 @@ -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 f6470ca..b70b17b 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 10f2d64..4fdbe6a 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 -#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 bc9f8b2..66f8a02 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, ©->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, ©->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, ©->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 18a4843..febd967 100644 --- a/common/gdi_canvas.h +++ b/common/gdi_canvas.h @@ -22,7 +22,7 @@ #include #include -#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 329d97b..b6d584f 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, ©->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 64baba8..014109f 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 32a6203..832ac51 100644 --- a/common/rop3.h +++ b/common/rop3.h @@ -22,11 +22,11 @@ #include #include -#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(); -- cgit v1.2.3