From a23bf0c0d53d79f18a768f9322fc757ecbd693e5 Mon Sep 17 00:00:00 2001 From: Yonit Halperin Date: Tue, 1 Jun 2010 10:30:51 +0300 Subject: [PATCH] support for lossy images in the pixmap cache and fill bits 1) add an option to determine if a bitmap can be sent lossy to the client 2) when required, replacing lossy cache items with their correspending lossless bitmaps --- canvas_base.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++----- canvas_base.h | 10 +++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/canvas_base.c b/canvas_base.c index 8180f09..aac472c 100644 --- a/canvas_base.c +++ b/canvas_base.c @@ -567,7 +567,7 @@ static void dump_jpeg(uint8_t* data, int data_size) if (!f) { return; } - + fwrite(data, 1, data_size, f); fclose(f); } @@ -1044,12 +1044,19 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE * to happen which breaks if we don't. */ if (!real_get && !(descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME) && +#ifdef SW_CANVAS_CACHE + !(descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME) && +#endif (descriptor->type != SPICE_IMAGE_TYPE_GLZ_RGB)) { return NULL; } saved_want_original = want_original; - if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME) { + if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME +#ifdef SW_CANVAS_CACHE + || descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME +#endif + ) { want_original = TRUE; } @@ -1092,7 +1099,11 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE case SPICE_IMAGE_TYPE_FROM_CACHE: surface = canvas->bits_cache->ops->get(canvas->bits_cache, descriptor->id); break; - +#ifdef SW_CANVAS_CACHE + case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS: + surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, descriptor->id); + break; +#endif case SPICE_IMAGE_TYPE_BITMAP: { SpiceBitmapImage *bitmap = (SpiceBitmapImage *)descriptor; access_test(canvas, descriptor, sizeof(SpiceBitmapImage)); @@ -1107,6 +1118,9 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE if (descriptor->flags & SPICE_IMAGE_FLAGS_HIGH_BITS_SET && descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE && +#ifdef SW_CANVAS_CACHE + descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS && +#endif surface_format == PIXMAN_x8r8g8b8) { spice_pixman_fill_rect_rop(surface, 0, 0, @@ -1116,13 +1130,39 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE } if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME && - descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE) { +#ifdef SW_CANVAS_CACHE + descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS && +#endif + descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE ) { +#ifdef SW_CANVAS_CACHE + if (descriptor->type != SPICE_IMAGE_TYPE_JPEG) { + canvas->bits_cache->ops->put(canvas->bits_cache, descriptor->id, surface); + } else { + canvas->bits_cache->ops->put_lossy(canvas->bits_cache, descriptor->id, surface); + } +#else canvas->bits_cache->ops->put(canvas->bits_cache, descriptor->id, surface); +#endif #ifdef DEBUG_DUMP_SURFACE dump_surface(surface, 1); #endif - } else if (descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE) { +#ifdef SW_CANVAS_CACHE + } else if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME) { + if (descriptor->type == SPICE_IMAGE_TYPE_JPEG) { + CANVAS_ERROR("invalid cache replace request: the image is lossy"); + } + canvas->bits_cache->ops->replace_lossy(canvas->bits_cache, descriptor->id, surface); #ifdef DEBUG_DUMP_SURFACE + dump_surface(surface, 1); +#endif +#endif +#ifdef DEBUG_DUMP_SURFACE + } else if (descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE +#ifdef SW_CANVAS_CACHE + && descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS +#endif + ) { + dump_surface(surface, 0); #endif } @@ -1437,6 +1477,12 @@ static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int surface = canvas->bits_cache->ops->get(canvas->bits_cache, descriptor->id); is_invers = 0; break; +#endif +#ifdef SW_CANVAS_CACHE + case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS: + surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, descriptor->id); + is_invers = 0; + break; #endif default: CANVAS_ERROR("invalid image type"); diff --git a/canvas_base.h b/canvas_base.h index 4eaafbb..1bbe465 100644 --- a/canvas_base.h +++ b/canvas_base.h @@ -41,6 +41,16 @@ typedef struct { pixman_image_t *surface); pixman_image_t *(*get)(SpiceImageCache *cache, uint64_t id); +#ifdef SW_CANVAS_CACHE + void (*put_lossy)(SpiceImageCache *cache, + uint64_t id, + pixman_image_t *surface); + void (*replace_lossy)(SpiceImageCache *cache, + uint64_t id, + pixman_image_t *surface); + pixman_image_t *(*get_lossless)(SpiceImageCache *cache, + uint64_t id); +#endif } SpiceImageCacheOps; struct _SpiceImageCache {