diff options
-rw-r--r-- | common/cairo_canvas.c | 151 | ||||
-rw-r--r-- | common/canvas_base.c | 323 | ||||
-rw-r--r-- | common/canvas_base.h | 8 | ||||
-rw-r--r-- | common/canvas_utils.c | 152 | ||||
-rw-r--r-- | common/canvas_utils.h | 30 | ||||
-rw-r--r-- | common/gdi_canvas.c | 156 | ||||
-rw-r--r-- | common/gdi_canvas.h | 2 | ||||
-rw-r--r-- | common/gl_canvas.c | 171 | ||||
-rw-r--r-- | common/rop3.c | 56 | ||||
-rw-r--r-- | common/rop3.h | 8 |
10 files changed, 534 insertions, 523 deletions
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 <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 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 <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 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 <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 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 <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 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 <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(); |