From 25bb38f643af6f0015df369a22176275b6ebfae0 Mon Sep 17 00:00:00 2001 From: Yonit Halperin Date: Sun, 20 Jun 2010 15:24:49 +0300 Subject: applying zlib compression over glz on WAN connection --- common/canvas_base.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- common/canvas_base.h | 13 +++++++++++++ common/gdi_canvas.c | 4 +++- common/gdi_canvas.h | 3 ++- common/gl_canvas.c | 2 ++ common/gl_canvas.h | 1 + common/sw_canvas.c | 6 ++++++ common/sw_canvas.h | 2 ++ 8 files changed, 71 insertions(+), 11 deletions(-) (limited to 'common') diff --git a/common/canvas_base.c b/common/canvas_base.c index 26bc52c6..0148270f 100644 --- a/common/canvas_base.c +++ b/common/canvas_base.c @@ -186,6 +186,7 @@ typedef struct CanvasBase { LzData lz_data; GlzData glz_data; SpiceJpegDecoder* jpeg; + SpiceZlibDecoder* zlib; void *usr_data; spice_destroy_fn_t usr_data_destroy; @@ -817,6 +818,21 @@ static pixman_image_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int inv return lz_data->decode_data.out_surface; } +static pixman_image_t *canvas_get_glz_rgb_common(CanvasBase *canvas, uint8_t *data, + int want_original) +{ + if (canvas->glz_data.decoder == NULL) { + CANVAS_ERROR("glz not supported"); + } + + canvas->glz_data.decoder->ops->decode(canvas->glz_data.decoder, + data, NULL, + &canvas->glz_data.decode_data); + + /* global_decode calls alloc_lz_image, which sets canvas->glz_data.surface */ + return (canvas->glz_data.decode_data.out_surface); +} + // don't handle plts since bitmaps with plt can be decoded globally to RGB32 (because // same byte sequence can be transformed to different RGB pixels by different plts) static pixman_image_t *canvas_get_glz(CanvasBase *canvas, LZImage *image, @@ -827,15 +843,25 @@ static pixman_image_t *canvas_get_glz(CanvasBase *canvas, LZImage *image, canvas->glz_data.decode_data.dc = canvas->dc; #endif - if (canvas->glz_data.decoder == NULL) { - CANVAS_ERROR("glz not supported"); + return canvas_get_glz_rgb_common(canvas, image->lz_rgb.data, want_original); +} + +static pixman_image_t *canvas_get_zlib_glz_rgb(CanvasBase *canvas, SpiceZlibGlzRGBImage *image, + int want_original) +{ + uint8_t *glz_data; + pixman_image_t *surface; + + if (canvas->zlib == NULL) { + CANVAS_ERROR("zlib not supported"); } - canvas->glz_data.decoder->ops->decode(canvas->glz_data.decoder, - image->lz_rgb.data, NULL, - &canvas->glz_data.decode_data); - /* global_decode calls alloc_lz_image, which sets canvas->glz_data.surface */ - return (canvas->glz_data.decode_data.out_surface); + glz_data = (uint8_t*)spice_malloc(image->zlib_glz.glz_data_size); + canvas->zlib->ops->decode(canvas->zlib, image->zlib_glz.data, image->zlib_glz.data_size, + glz_data, image->zlib_glz.glz_data_size); + surface = canvas_get_glz_rgb_common(canvas, glz_data, want_original); + free(glz_data); + return surface; } //#define DEBUG_DUMP_BITMAP @@ -1025,7 +1051,8 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE #ifdef SW_CANVAS_CACHE !(descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME) && #endif - (descriptor->type != SPICE_IMAGE_TYPE_GLZ_RGB)) { + (descriptor->type != SPICE_IMAGE_TYPE_GLZ_RGB) && + (descriptor->type != SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB)) { return NULL; } @@ -1067,8 +1094,12 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE surface = canvas_get_glz(canvas, image, want_original); break; } + case SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB: { + SpiceZlibGlzRGBImage *image = (SpiceZlibGlzRGBImage *)descriptor; + surface = canvas_get_zlib_glz_rgb(canvas, image, want_original); + break; + } #endif - case SPICE_IMAGE_TYPE_FROM_CACHE: surface = canvas->bits_cache->ops->get(canvas->bits_cache, descriptor->id); break; @@ -3305,6 +3336,7 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops, , SpiceImageSurfaces *surfaces , SpiceGlzDecoder *glz_decoder , SpiceJpegDecoder *jpeg_decoder + , SpiceZlibDecoder *zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , SpiceVirtMapping *virt_mapping #endif @@ -3339,6 +3371,7 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops, canvas->surfaces = surfaces; canvas->glz_data.decoder = glz_decoder; canvas->jpeg = jpeg_decoder; + canvas->zlib = zlib_decoder; canvas->format = format; diff --git a/common/canvas_base.h b/common/canvas_base.h index b54fce57..9dfbe854 100644 --- a/common/canvas_base.h +++ b/common/canvas_base.h @@ -32,6 +32,7 @@ typedef struct _SpiceImageSurfaces SpiceImageSurfaces; typedef struct _SpicePaletteCache SpicePaletteCache; typedef struct _SpiceGlzDecoder SpiceGlzDecoder; typedef struct _SpiceJpegDecoder SpiceJpegDecoder; +typedef struct _SpiceZlibDecoder SpiceZlibDecoder; typedef struct _SpiceVirtMapping SpiceVirtMapping; typedef struct _SpiceCanvas SpiceCanvas; @@ -107,6 +108,18 @@ struct _SpiceJpegDecoder { SpiceJpegDecoderOps *ops; }; +typedef struct { + void (*decode)(SpiceZlibDecoder *decoder, + uint8_t *data, + int data_size, + uint8_t *dest, + int dest_size); +} SpiceZlibDecoderOps; + +struct _SpiceZlibDecoder { + SpiceZlibDecoderOps *ops; +}; + typedef struct { void *(*get_virt)(SpiceVirtMapping *mapping, unsigned long addr, uint32_t add_size); void (*validate_virt)(SpiceVirtMapping *mapping, unsigned long virt, diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c index fea23906..76a76740 100644 --- a/common/gdi_canvas.c +++ b/common/gdi_canvas.c @@ -1851,6 +1851,7 @@ SpiceCanvas *gdi_canvas_create(int width, int height, , SpiceImageSurfaces *surfaces , SpiceGlzDecoder *glz_decoder , SpiceJpegDecoder *jpeg_decoder + , SpiceZlibDecoder *zlib_decoder ) { GdiCanvas *canvas; @@ -1870,7 +1871,8 @@ SpiceCanvas *gdi_canvas_create(int width, int height, #endif , surfaces , glz_decoder - , jpeg_decoder); + , jpeg_decoder + , zlib_decoder); canvas->dc = dc; canvas->lock = lock; return (SpiceCanvas *)canvas; diff --git a/common/gdi_canvas.h b/common/gdi_canvas.h index 02e053d2..3fdf07e9 100644 --- a/common/gdi_canvas.h +++ b/common/gdi_canvas.h @@ -32,7 +32,8 @@ SpiceCanvas *gdi_canvas_create(int width, int height, SpicePaletteCache *palette_cache, SpiceImageSurfaces *surfaces, SpiceGlzDecoder *glz_decoder, - SpiceJpegDecoder *jpeg_decoder); + SpiceJpegDecoder *jpeg_decoder, + SpiceZlibDecoder *zlib_decoder); void gdi_canvas_init(); diff --git a/common/gl_canvas.c b/common/gl_canvas.c index 444fa4bb..688b635e 100644 --- a/common/gl_canvas.c +++ b/common/gl_canvas.c @@ -817,6 +817,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format , SpiceImageSurfaces *surfaces , SpiceGlzDecoder *glz_decoder , SpiceJpegDecoder *jpeg_decoder + , SpiceZlibDecoder *zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , SpiceVirtMapping *virt_mapping #endif @@ -845,6 +846,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format , surfaces , glz_decoder , jpeg_decoder + , zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , virt_mapping #endif diff --git a/common/gl_canvas.h b/common/gl_canvas.h index cd76f8d9..d3f707a8 100644 --- a/common/gl_canvas.h +++ b/common/gl_canvas.h @@ -31,6 +31,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format , SpiceImageSurfaces *surfaces , SpiceGlzDecoder *glz_decoder , SpiceJpegDecoder *jpeg_decoder + , SpiceZlibDecoder *zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , SpiceVirtMapping *virt_mapping #endif diff --git a/common/sw_canvas.c b/common/sw_canvas.c index c1a7392a..56865c31 100644 --- a/common/sw_canvas.c +++ b/common/sw_canvas.c @@ -1172,6 +1172,7 @@ static SpiceCanvas *canvas_create_common(pixman_image_t *image, , SpiceImageSurfaces *surfaces , SpiceGlzDecoder *glz_decoder , SpiceJpegDecoder *jpeg_decoder + , SpiceZlibDecoder *zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , SpiceVirtMapping *virt_mapping #endif @@ -1200,6 +1201,7 @@ static SpiceCanvas *canvas_create_common(pixman_image_t *image, , surfaces , glz_decoder , jpeg_decoder + , zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , virt_mapping #endif @@ -1222,6 +1224,7 @@ SpiceCanvas *canvas_create(int width, int height, uint32_t format , SpiceImageSurfaces *surfaces , SpiceGlzDecoder *glz_decoder , SpiceJpegDecoder *jpeg_decoder + , SpiceZlibDecoder *zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , SpiceVirtMapping *virt_mapping #endif @@ -1242,6 +1245,7 @@ SpiceCanvas *canvas_create(int width, int height, uint32_t format , surfaces , glz_decoder , jpeg_decoder + , zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , virt_mapping #endif @@ -1259,6 +1263,7 @@ SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, , SpiceImageSurfaces *surfaces , SpiceGlzDecoder *glz_decoder , SpiceJpegDecoder *jpeg_decoder + , SpiceZlibDecoder *zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , SpiceVirtMapping *virt_mapping #endif @@ -1279,6 +1284,7 @@ SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, , surfaces , glz_decoder , jpeg_decoder + , zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , virt_mapping #endif diff --git a/common/sw_canvas.h b/common/sw_canvas.h index 63a78630..05e4071f 100644 --- a/common/sw_canvas.h +++ b/common/sw_canvas.h @@ -36,6 +36,7 @@ SpiceCanvas *canvas_create(int width, int height, uint32_t format , SpiceImageSurfaces *surfaces , SpiceGlzDecoder *glz_decoder , SpiceJpegDecoder *jpeg_decoder + , SpiceZlibDecoder *zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , SpiceVirtMapping *virt_mapping #endif @@ -51,6 +52,7 @@ SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, uint , SpiceImageSurfaces *surfaces , SpiceGlzDecoder *glz_decoder , SpiceJpegDecoder *jpeg_decoder + , SpiceZlibDecoder *zlib_decoder #ifndef SW_CANVAS_NO_CHUNKS , SpiceVirtMapping *virt_mapping #endif -- cgit