mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice-common
synced 2025-12-30 18:00:25 +00:00
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
This commit is contained in:
parent
93fdeaa7e1
commit
a23bf0c0d5
@ -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");
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user