diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/x11/pixels_source.cpp | 23 | ||||
-rw-r--r-- | client/x11/pixels_source_p.h | 9 | ||||
-rw-r--r-- | client/x11/red_drawable.cpp | 199 | ||||
-rw-r--r-- | client/x11/red_pixmap_cairo.cpp | 36 |
4 files changed, 149 insertions, 118 deletions
diff --git a/client/x11/pixels_source.cpp b/client/x11/pixels_source.cpp index 7b9ed05f..144c296f 100644 --- a/client/x11/pixels_source.cpp +++ b/client/x11/pixels_source.cpp @@ -25,9 +25,9 @@ static void create_image(const PixmapHeader* pixmap, PixelsSource_p& pixels_source, - cairo_format_t cairo_format) + pixman_format_code_t format) { - cairo_surface_t* cairo_surf; + pixman_image_t *pixman_image; XImage *image = new XImage; memset(image, 0, sizeof(*image)); @@ -53,10 +53,11 @@ static void create_image(const PixmapHeader* pixmap, PixelsSource_p& pixels_sour THROW("init image failed"); } - cairo_surf = cairo_image_surface_create_for_data(pixmap->data, cairo_format, - pixmap->width, pixmap->height, - pixmap->stride); - if (cairo_surface_status(cairo_surf) != CAIRO_STATUS_SUCCESS) { + pixman_image = pixman_image_create_bits(format, + pixmap->width, pixmap->height, + (uint32_t *)pixmap->data, + pixmap->stride); + if (pixman_image == NULL) { THROW("surf create failed"); } } catch (...) { @@ -66,7 +67,7 @@ static void create_image(const PixmapHeader* pixmap, PixelsSource_p& pixels_sour pixels_source.type = PIXELS_SOURCE_TYPE_PIXMAP; pixels_source.pixmap.x_image = image; - pixels_source.pixmap.cairo_surf = cairo_surf; + pixels_source.pixmap.pixman_image = pixman_image; } PixelsSource::PixelsSource() @@ -85,12 +86,12 @@ ImageFromRes::ImageFromRes(int res_id) if (!pixmap) { THROW("no image %d", res_id); } - create_image(pixmap, *(PixelsSource_p*)get_opaque(), CAIRO_FORMAT_RGB24); + create_image(pixmap, *(PixelsSource_p*)get_opaque(), PIXMAN_x8r8g8b8); } ImageFromRes::~ImageFromRes() { - cairo_surface_destroy(((PixelsSource_p*)get_opaque())->pixmap.cairo_surf); + pixman_image_unref(((PixelsSource_p*)get_opaque())->pixmap.pixman_image); delete ((PixelsSource_p*)get_opaque())->pixmap.x_image; } @@ -109,12 +110,12 @@ AlphaImageFromRes::AlphaImageFromRes(int res_id) if (!pixmap) { THROW("no image %d", res_id); } - create_image(pixmap, *(PixelsSource_p*)get_opaque(), CAIRO_FORMAT_ARGB32); + create_image(pixmap, *(PixelsSource_p*)get_opaque(), PIXMAN_a8r8g8b8); } AlphaImageFromRes::~AlphaImageFromRes() { - cairo_surface_destroy(((PixelsSource_p*)get_opaque())->pixmap.cairo_surf); + pixman_image_unref(((PixelsSource_p*)get_opaque())->pixmap.pixman_image); delete ((PixelsSource_p*)get_opaque())->pixmap.x_image; } diff --git a/client/x11/pixels_source_p.h b/client/x11/pixels_source_p.h index 69d6998b..9605ae43 100644 --- a/client/x11/pixels_source_p.h +++ b/client/x11/pixels_source_p.h @@ -24,7 +24,7 @@ #include <X11/extensions/XShm.h> #include "red_window.h" #include "red_pixmap_gl.h" -#include "cairo.h" +#include "pixman_utils.h" enum { PIXELS_SOURCE_TYPE_INVALID, @@ -53,12 +53,12 @@ struct PixelsSource_p { struct { XImage* x_image; XShmSegmentInfo *shminfo; - cairo_surface_t* cairo_surf; + pixman_image_t* pixman_image; } x_shm_drawable; struct { XImage* x_image; - cairo_surface_t* cairo_surf; + pixman_image_t* pixman_image; } pixmap; struct { @@ -79,9 +79,6 @@ struct PixelsSource_p { struct RedDrawable_p { PixelsSource_p source; - union { - cairo_t* cairo; - }; }; #endif diff --git a/client/x11/red_drawable.cpp b/client/x11/red_drawable.cpp index 7485c94d..e020b845 100644 --- a/client/x11/red_drawable.cpp +++ b/client/x11/red_drawable.cpp @@ -237,18 +237,18 @@ static inline void copy_to_pixmap_from_shmdrawable(const RedDrawable_p* dest, const PixelsSource_p* source, int src_x, int src_y) { - cairo_t* cairo = dest->cairo; - cairo_surface_t* surf = source->x_shm_drawable.cairo_surf; - - ASSERT(cairo); - ASSERT(surf); - - cairo_set_source_surface(cairo, surf, area.left + offset.x - src_x, - area.top + offset.y - src_y); - cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY); - cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left, - area.bottom - area.top); - cairo_fill(cairo); + pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; + pixman_image_t *src_surface = source->x_shm_drawable.pixman_image; + + pixman_image_composite32(PIXMAN_OP_SRC, + src_surface, NULL, dest_surface, + src_x + offset.x, + src_y + offset.y, + 0, 0, + area.left + offset.x, + area.top + offset.y, + area.right - area.left, + area.bottom - area.top); } static inline void copy_to_pixmap_from_pixmap(const RedDrawable_p* dest, @@ -257,18 +257,18 @@ static inline void copy_to_pixmap_from_pixmap(const RedDrawable_p* dest, const PixelsSource_p* source, int src_x, int src_y) { - cairo_t* cairo = dest->cairo; - cairo_surface_t* surf = source->pixmap.cairo_surf; - - ASSERT(cairo); - ASSERT(surf); - - cairo_set_source_surface(cairo, surf, area.left + offset.x - src_x, - area.top + offset.y - src_y); - cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY); - cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left, - area.bottom - area.top); - cairo_fill(cairo); + pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; + pixman_image_t *src_surface = source->pixmap.pixman_image; + + pixman_image_composite32(PIXMAN_OP_SRC, + src_surface, NULL, dest_surface, + src_x + offset.x, + src_y + offset.y, + 0, 0, + area.left + offset.x, + area.top + offset.y, + area.right - area.left, + area.bottom - area.top); } static inline void copy_to_pixmap_from_gltexture(const RedDrawable_p* dest, @@ -384,18 +384,18 @@ static inline void blend_to_pixmap_from_pixmap(const RedDrawable_p* dest, const PixelsSource_p* source, int src_x, int src_y) { - cairo_t* cairo = dest->cairo; - cairo_surface_t* surf = source->pixmap.cairo_surf; - - ASSERT(cairo); - ASSERT(surf); - - cairo_set_source_surface(cairo, surf, (area.left + offset.x - src_x), - (area.top + offset.y - src_y)); - cairo_set_operator(cairo, CAIRO_OPERATOR_ATOP); - cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left, - area.bottom - area.top); - cairo_fill(cairo); + pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; + pixman_image_t *src_surface = source->pixmap.pixman_image; + + pixman_image_composite32 (PIXMAN_OP_ATOP, + src_surface, NULL, dest_surface, + src_x + offset.x, + src_y + offset.y, + 0, 0, + area.left + offset.x, + area.top + offset.y, + area.right - area.left, + area.bottom - area.top); } static inline void blend_to_pixmap(const RedDrawable_p* dest, @@ -460,41 +460,74 @@ static inline void combine_to_pixmap_from_pixmap(const RedDrawable_p* dest, int src_x, int src_y, RedDrawable::CombineOP op) { - cairo_t* cairo = dest->cairo; - cairo_surface_t* surf = source->pixmap.cairo_surf; + pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; + pixman_image_t *src_surface = source->pixmap.pixman_image; - ASSERT(cairo); - ASSERT(surf); - cairo_operator_t cairo_op; + SpiceROP rop; switch (op) { case RedDrawable::OP_COPY: - cairo_op = CAIRO_OPERATOR_RASTER_COPY; + rop = SPICE_ROP_COPY; break; case RedDrawable::OP_AND: - cairo_op = CAIRO_OPERATOR_RASTER_AND; + rop = SPICE_ROP_AND; break; case RedDrawable::OP_XOR: - cairo_op = CAIRO_OPERATOR_RASTER_XOR; + rop = SPICE_ROP_XOR; break; default: THROW("invalid op %d", op); } - cairo_set_operator(cairo, cairo_op); - if (cairo_image_surface_get_format(surf) == CAIRO_FORMAT_A1) { - cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left, - area.bottom - area.top); - cairo_clip(cairo); - cairo_set_source_rgb(cairo, 1, 1, 1); - cairo_mask_surface(cairo, surf, area.left + offset.x - src_x, area.top + offset.y - src_y); - cairo_reset_clip(cairo); + if (pixman_image_get_depth (src_surface) == 1) { + pixman_image_t *temp; + + temp = pixman_image_create_bits(pixman_image_get_depth(dest_surface) == 24 ? + PIXMAN_x8r8g8b8 : PIXMAN_a8r8g8b8, + area.right - area.left, + area.bottom - area.top, NULL, 0); + + /* Copy from dest to temp */ + pixman_image_composite32(PIXMAN_OP_SRC, + dest_surface, NULL, temp, + area.left + offset.x, + area.top + offset.y, + 0, 0, + 0, 0, + area.right - area.left, + area.bottom - area.top); + + /* rop white over temp */ + spice_pixman_fill_rect_rop(temp, + 0, 0, + area.right - area.left, + area.bottom - area.top, + 0xffffff, + rop); + + /* copy back using a1 mask */ + pixman_image_composite32(PIXMAN_OP_SRC, + temp, src_surface, dest_surface, + 0, 0, + src_x + offset.x, + src_y + offset.y, + area.left + offset.x, + area.top + offset.y, + area.right - area.left, + area.bottom - area.top); + + pixman_image_unref(temp); + } else { - cairo_set_source_surface(cairo, surf, area.left + offset.x - src_x, - area.top + offset.y - src_y); - cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left, - area.bottom - area.top); - cairo_fill(cairo); + spice_pixman_blit_rop(dest_surface, + src_surface, + src_x + offset.x, + src_y + offset.y, + area.left + offset.x, + area.top + offset.y, + area.right - area.left, + area.bottom - area.top, + rop); } } @@ -606,17 +639,13 @@ static inline void fill_gl_drawable(RedDrawable_p* dest, const SpiceRect& area, static inline void fill_pixmap(RedDrawable_p* dest, const SpiceRect& area, rgb32_t color, const SpicePoint& offset) { - cairo_t* cairo = dest->cairo; - - ASSERT(cairo); - cairo_set_source_rgb(cairo, - (double)rgb32_get_red(color) / 0xff, - (double)rgb32_get_green(color) / 0xff, - (double)rgb32_get_blue(color) / 0xff); - cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left, - area.bottom - area.top); - cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY); - cairo_fill(cairo); + pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; + + spice_pixman_fill_rect(dest_surface, + area.left + offset.x, area.top + offset.y, + area.right - area.left, + area.bottom - area.top, + color); } void RedDrawable::fill_rect(const SpiceRect& area, rgb32_t color) @@ -668,18 +697,28 @@ static inline void frame_drawable(RedDrawable_p* dest, const SpiceRect& area, rg static inline void frame_pixmap(RedDrawable_p* dest, const SpiceRect& area, rgb32_t color, const SpicePoint& offset) { - cairo_t* cairo = dest->cairo; - - ASSERT(cairo); - cairo_set_source_rgb(cairo, - (double)rgb32_get_red(color) / 0xff, - (double)rgb32_get_green(color) / 0xff, - (double)rgb32_get_blue(color) / 0xff); - cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left, - area.bottom - area.top); - cairo_set_line_width(cairo, 1); - cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY); - cairo_stroke(cairo); + pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; + + spice_pixman_fill_rect(dest_surface, + area.left + offset.x, area.top + offset.y, + area.right - area.left, + 1, + color); + spice_pixman_fill_rect(dest_surface, + area.left + offset.x, area.bottom + offset.y, + area.right - area.left, + 1, + color); + spice_pixman_fill_rect(dest_surface, + area.left + offset.x, area.top + offset.y, + 1, + area.bottom - area.top, + color); + spice_pixman_fill_rect(dest_surface, + area.right + offset.x, area.top + offset.y, + 1, + area.bottom - area.top, + color); } void RedDrawable::frame_rect(const SpiceRect& area, rgb32_t color) diff --git a/client/x11/red_pixmap_cairo.cpp b/client/x11/red_pixmap_cairo.cpp index 7ca9315f..7b8f0742 100644 --- a/client/x11/red_pixmap_cairo.cpp +++ b/client/x11/red_pixmap_cairo.cpp @@ -28,10 +28,9 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, bool top_bottom, rgb32_t* pallet, RedWindow *win) : RedPixmap(width, height, format, top_bottom, pallet) { - cairo_surface_t* cairo_surf = NULL; - cairo_t* cairo = NULL; ASSERT(format == RedPixmap::ARGB32 || format == RedPixmap::RGB32 || format == RedPixmap::A1); ASSERT(sizeof(RedDrawable_p) <= PIXELES_SOURCE_OPAQUE_SIZE); + pixman_image_t *pixman_image; XImage *image = NULL; XShmSegmentInfo *shminfo = NULL; _data = NULL; @@ -40,7 +39,7 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, try { - cairo_format_t cairo_format; + pixman_format_code_t pixman_format; if (win) { vinfo = XPlatform::get_vinfo()[win->get_screen_num()]; @@ -55,12 +54,12 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, case RedPixmap::ARGB32: case RedPixmap::RGB32: depth = XPlatform::get_vinfo()[0]->depth; - cairo_format = format == RedPixmap::ARGB32 ? CAIRO_FORMAT_ARGB32 : - CAIRO_FORMAT_RGB24; + pixman_format = format == RedPixmap::ARGB32 ? PIXMAN_a8r8g8b8 : + PIXMAN_x8r8g8b8; break; case RedPixmap::A1: depth = 1; - cairo_format = CAIRO_FORMAT_A1; + pixman_format = PIXMAN_a1; break; default: THROW("unsupported format %d", format); @@ -122,13 +121,13 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, image->red_mask = 0x00ff0000; image->green_mask = 0x0000ff00; image->blue_mask = 0x000000ff; - cairo_format = format == RedPixmap::ARGB32 ? CAIRO_FORMAT_ARGB32 : - CAIRO_FORMAT_RGB24; + pixman_format = format == RedPixmap::ARGB32 ? PIXMAN_a8r8g8b8 : + PIXMAN_x8r8g8b8; break; case RedPixmap::A1: image->depth = 1; image->format = XYBitmap; - cairo_format = CAIRO_FORMAT_A1; + pixman_format = PIXMAN_a1; break; default: THROW("unsupported format %d", format); @@ -138,23 +137,17 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, THROW("init image failed"); } } - cairo_surf = cairo_image_surface_create_for_data(_data, cairo_format, _width, _height, - _stride); - if (cairo_surface_status(cairo_surf) != CAIRO_STATUS_SUCCESS) { + pixman_image = pixman_image_create_bits(pixman_format, _width, _height, + (uint32_t *)_data, _stride); + if (pixman_image == NULL) { THROW("surf create failed"); } - cairo = cairo_create(cairo_surf); - cairo_surface_destroy(cairo_surf); - if (cairo_status(cairo) != CAIRO_STATUS_SUCCESS) { - THROW("cairo create failed failed"); - } if (!using_shm) { - ((PixelsSource_p*)get_opaque())->pixmap.cairo_surf = cairo_surf; + ((PixelsSource_p*)get_opaque())->pixmap.pixman_image = pixman_image; } else { - ((PixelsSource_p*)get_opaque())->x_shm_drawable.cairo_surf = cairo_surf; + ((PixelsSource_p*)get_opaque())->x_shm_drawable.pixman_image = pixman_image; } - ((RedDrawable_p*)get_opaque())->cairo = cairo; } catch (...) { if (using_shm) { if (image) { @@ -178,11 +171,12 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, RedPixmapCairo::~RedPixmapCairo() { - cairo_destroy(((RedDrawable_p*)get_opaque())->cairo); if (((PixelsSource_p*)get_opaque())->type == PIXELS_SOURCE_TYPE_PIXMAP) { + pixman_image_unref(((PixelsSource_p*)get_opaque())->pixmap.pixman_image); delete ((PixelsSource_p*)get_opaque())->pixmap.x_image; delete[] _data; } else { + pixman_image_unref(((PixelsSource_p*)get_opaque())->x_shm_drawable.pixman_image); XShmSegmentInfo *shminfo = ((PixelsSource_p*)get_opaque())->x_shm_drawable.shminfo; XShmDetach(XPlatform::get_display(), shminfo); XDestroyImage(((PixelsSource_p*)get_opaque())->x_shm_drawable.x_image); |