diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2010-06-01 10:30:51 +0300 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-06-09 11:41:01 +0200 |
commit | 5d2ae66f5022187e0028a1d7ccf67fe48fdaa94b (patch) | |
tree | 0458ad257a08447d5edc21c6391225ac8b738717 /common | |
parent | 263646a1f7e705766f7d46017679812d4b1406b8 (diff) | |
download | spice-5d2ae66f5022187e0028a1d7ccf67fe48fdaa94b.tar.gz spice-5d2ae66f5022187e0028a1d7ccf67fe48fdaa94b.tar.xz spice-5d2ae66f5022187e0028a1d7ccf67fe48fdaa94b.zip |
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
Diffstat (limited to 'common')
-rw-r--r-- | common/canvas_base.c | 56 | ||||
-rw-r--r-- | common/canvas_base.h | 10 |
2 files changed, 61 insertions, 5 deletions
diff --git a/common/canvas_base.c b/common/canvas_base.c index 8180f09d..aac472c8 100644 --- a/common/canvas_base.c +++ b/common/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 +#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 - } else if (descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE) { +#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 } @@ -1438,6 +1478,12 @@ static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int 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/common/canvas_base.h b/common/canvas_base.h index 4eaafbbd..1bbe4653 100644 --- a/common/canvas_base.h +++ b/common/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 { |