summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2013-10-11 14:11:23 -0400
committerYonit Halperin <yhalperi@redhat.com>2013-10-23 15:44:11 -0400
commit0272dc65a73a14c7c9a9640a3e003dc75f6a4e19 (patch)
tree22525ff8f8926486641025773696920e647e29f0
parenta5100670f4f1af0fa384425c4df8822679d6fccb (diff)
red_parse_qxl: track qxl resources size
-rw-r--r--server/red_parse_qxl.c214
-rw-r--r--server/red_parse_qxl.h20
-rw-r--r--server/red_worker.c2
3 files changed, 161 insertions, 75 deletions
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
index 008705f..f094fbd 100644
--- a/server/red_parse_qxl.c
+++ b/server/red_parse_qxl.c
@@ -60,6 +60,21 @@ static inline uint32_t color_16_to_32(uint32_t color)
return ret;
}
+static void red_qxl_resources_add_image(RedQXLResources *qxl,
+ SpiceImage *image,
+ uint32_t size)
+{
+ spice_assert(qxl->num_images < QXL_COMMAND_MAX_IMAGE_NUM);
+ qxl->images[qxl->num_images] = image;
+ qxl->images_size[qxl->num_images++] = size;
+}
+
+static void red_qxl_resources_add_res(RedQXLResources *qxl,
+ uint32_t size)
+{
+ qxl->other_res_size += size;
+}
+
static uint8_t *red_linearize_chunk(RedDataChunk *head, size_t size, bool *free_chunk)
{
uint8_t *data, *ptr;
@@ -170,7 +185,8 @@ void red_get_rect_ptr(SpiceRect *red, const QXLRect *qxl)
}
static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
- QXLPHYSICAL addr)
+ QXLPHYSICAL addr,
+ RedQXLResources *qxl_res)
{
RedDataChunk chunks;
QXLPathSeg *start, *end;
@@ -208,6 +224,8 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
start = (QXLPathSeg*)(&start->points[count]);
}
+ red_qxl_resources_add_res(qxl_res, size);
+
red = spice_malloc(mem_size);
red->num_segments = n_segments;
@@ -367,7 +385,8 @@ static int bitmap_consistent(SpiceBitmap *bitmap)
static const int BITMAP_FMT_IS_RGB[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
- QXLPHYSICAL addr, uint32_t flags, int is_mask)
+ QXLPHYSICAL addr, uint32_t flags, int is_mask,
+ RedQXLResources *qxl_res)
{
RedDataChunk chunks;
QXLImage *qxl;
@@ -380,6 +399,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
if (addr == 0) {
return NULL;
}
+ spice_assert(qxl_res);
qxl = (QXLImage *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
if (error) {
@@ -448,6 +468,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
}
red->u.bitmap.palette = rp;
red->u.bitmap.palette_id = rp->unique;
+ red_qxl_resources_add_res(qxl_res, num_ents * sizeof(qp->ents[0]));
}
bitmap_size = red->u.bitmap.y * abs(red->u.bitmap.stride);
if (qxl_flags & QXL_BITMAP_DIRECT) {
@@ -468,6 +489,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
if (qxl_flags & QXL_BITMAP_UNSTABLE) {
red->u.bitmap.data->flags |= SPICE_CHUNKS_FLAGS_UNSTABLE;
}
+ red_qxl_resources_add_image(qxl_res, red, bitmap_size);
break;
case SPICE_IMAGE_TYPE_SURFACE:
red->u.surface.surface_id = qxl->surface_image.surface_id;
@@ -484,6 +506,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
red->u.quic.data = red_get_image_data_chunked(slots, group_id,
&chunks);
red_put_data_chunks(&chunks);
+ red_qxl_resources_add_image(qxl_res, red, red->u.quic.data_size);
break;
default:
spice_warning("unknown type %d", red->descriptor.type);
@@ -514,7 +537,7 @@ void red_put_image(SpiceImage *red)
}
static void red_get_brush_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceBrush *red, QXLBrush *qxl, uint32_t flags)
+ SpiceBrush *red, QXLBrush *qxl, uint32_t flags, RedQXLResources *qxl_res)
{
red->type = qxl->type;
switch (red->type) {
@@ -526,7 +549,7 @@ static void red_get_brush_ptr(RedMemSlotInfo *slots, int group_id,
}
break;
case SPICE_BRUSH_TYPE_PATTERN:
- red->u.pattern.pat = red_get_image(slots, group_id, qxl->u.pattern.pat, flags, FALSE);
+ red->u.pattern.pat = red_get_image(slots, group_id, qxl->u.pattern.pat, flags, FALSE, qxl_res);
break;
}
}
@@ -541,11 +564,11 @@ static void red_put_brush(SpiceBrush *red)
}
static void red_get_qmask_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceQMask *red, QXLQMask *qxl, uint32_t flags)
+ SpiceQMask *red, QXLQMask *qxl, uint32_t flags, RedQXLResources *qxl_res)
{
red->flags = qxl->flags;
red_get_point_ptr(&red->pos, &qxl->pos);
- red->bitmap = red_get_image(slots, group_id, qxl->bitmap, flags, TRUE);
+ red->bitmap = red_get_image(slots, group_id, qxl->bitmap, flags, TRUE, qxl_res);
}
static void red_put_qmask(SpiceQMask *red)
@@ -554,11 +577,12 @@ static void red_put_qmask(SpiceQMask *red)
}
static void red_get_fill_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceFill *red, QXLFill *qxl, uint32_t flags)
+ SpiceFill *red, QXLFill *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red_get_brush_ptr(slots, group_id, &red->brush, &qxl->brush, flags);
+ red_get_brush_ptr(slots, group_id, &red->brush, &qxl->brush, flags, qxl_res);
red->rop_descriptor = qxl->rop_descriptor;
- red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags);
+ red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags, qxl_res);
}
static void red_put_fill(SpiceFill *red)
@@ -568,14 +592,15 @@ static void red_put_fill(SpiceFill *red)
}
static void red_get_opaque_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceOpaque *red, QXLOpaque *qxl, uint32_t flags)
+ SpiceOpaque *red, QXLOpaque *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE);
+ red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE, qxl_res);
red_get_rect_ptr(&red->src_area, &qxl->src_area);
- red_get_brush_ptr(slots, group_id, &red->brush, &qxl->brush, flags);
+ red_get_brush_ptr(slots, group_id, &red->brush, &qxl->brush, flags, qxl_res);
red->rop_descriptor = qxl->rop_descriptor;
red->scale_mode = qxl->scale_mode;
- red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags);
+ red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags, qxl_res);
}
static void red_put_opaque(SpiceOpaque *red)
@@ -586,16 +611,17 @@ static void red_put_opaque(SpiceOpaque *red)
}
static int red_get_copy_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceCopy *red, QXLCopy *qxl, uint32_t flags)
+ SpiceCopy *red, QXLCopy *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE);
+ red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE, qxl_res);
if (!red->src_bitmap) {
return 1;
}
red_get_rect_ptr(&red->src_area, &qxl->src_area);
red->rop_descriptor = qxl->rop_descriptor;
red->scale_mode = qxl->scale_mode;
- red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags);
+ red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags, qxl_res);
return 0;
}
@@ -606,13 +632,14 @@ static void red_put_copy(SpiceCopy *red)
}
static void red_get_blend_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceBlend *red, QXLBlend *qxl, uint32_t flags)
+ SpiceBlend *red, QXLBlend *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE);
+ red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE, qxl_res);
red_get_rect_ptr(&red->src_area, &qxl->src_area);
red->rop_descriptor = qxl->rop_descriptor;
red->scale_mode = qxl->scale_mode;
- red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags);
+ red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags, qxl_res);
}
static void red_put_blend(SpiceBlend *red)
@@ -623,9 +650,10 @@ static void red_put_blend(SpiceBlend *red)
static void red_get_transparent_ptr(RedMemSlotInfo *slots, int group_id,
SpiceTransparent *red, QXLTransparent *qxl,
- uint32_t flags)
+ uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE);
+ red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE, qxl_res);
red_get_rect_ptr(&red->src_area, &qxl->src_area);
red->src_color = qxl->src_color;
red->true_color = qxl->true_color;
@@ -638,20 +666,21 @@ static void red_put_transparent(SpiceTransparent *red)
static void red_get_alpha_blend_ptr(RedMemSlotInfo *slots, int group_id,
SpiceAlphaBlend *red, QXLAlphaBlend *qxl,
- uint32_t flags)
+ uint32_t flags, RedQXLResources *qxl_res)
{
red->alpha_flags = qxl->alpha_flags;
red->alpha = qxl->alpha;
- red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE);
+ red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE, qxl_res);
red_get_rect_ptr(&red->src_area, &qxl->src_area);
}
static void red_get_alpha_blend_ptr_compat(RedMemSlotInfo *slots, int group_id,
SpiceAlphaBlend *red, QXLCompatAlphaBlend *qxl,
- uint32_t flags)
+ uint32_t flags,
+ RedQXLResources *qxl_res)
{
red->alpha = qxl->alpha;
- red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE);
+ red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE, qxl_res);
red_get_rect_ptr(&red->src_area, &qxl->src_area);
}
@@ -681,16 +710,17 @@ static bool get_transform(RedMemSlotInfo *slots,
}
static void red_get_composite_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceComposite *red, QXLComposite *qxl, uint32_t flags)
+ SpiceComposite *red, QXLComposite *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
red->flags = qxl->flags;
- red->src_bitmap = red_get_image(slots, group_id, qxl->src, flags, FALSE);
+ red->src_bitmap = red_get_image(slots, group_id, qxl->src, flags, FALSE, qxl_res);
if (get_transform(slots, group_id, qxl->src_transform, &red->src_transform))
red->flags |= SPICE_COMPOSITE_HAS_SRC_TRANSFORM;
if (qxl->mask) {
- red->mask_bitmap = red_get_image(slots, group_id, qxl->mask, flags, FALSE);
+ red->mask_bitmap = red_get_image(slots, group_id, qxl->mask, flags, FALSE, qxl_res);
red->flags |= SPICE_COMPOSITE_HAS_MASK;
if (get_transform(slots, group_id, qxl->mask_transform, &red->mask_transform))
red->flags |= SPICE_COMPOSITE_HAS_MASK_TRANSFORM;
@@ -711,14 +741,15 @@ static void red_put_composite(SpiceComposite *red)
}
static void red_get_rop3_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceRop3 *red, QXLRop3 *qxl, uint32_t flags)
+ SpiceRop3 *red, QXLRop3 *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE);
+ red->src_bitmap = red_get_image(slots, group_id, qxl->src_bitmap, flags, FALSE, qxl_res);
red_get_rect_ptr(&red->src_area, &qxl->src_area);
- red_get_brush_ptr(slots, group_id, &red->brush, &qxl->brush, flags);
+ red_get_brush_ptr(slots, group_id, &red->brush, &qxl->brush, flags, qxl_res);
red->rop3 = qxl->rop3;
red->scale_mode = qxl->scale_mode;
- red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags);
+ red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags, qxl_res);
}
static void red_put_rop3(SpiceRop3 *red)
@@ -729,11 +760,12 @@ static void red_put_rop3(SpiceRop3 *red)
}
static int red_get_stroke_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceStroke *red, QXLStroke *qxl, uint32_t flags)
+ SpiceStroke *red, QXLStroke *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
int error;
- red->path = red_get_path(slots, group_id, qxl->path);
+ red->path = red_get_path(slots, group_id, qxl->path, qxl_res);
if (!red->path) {
return 1;
}
@@ -752,11 +784,12 @@ static int red_get_stroke_ptr(RedMemSlotInfo *slots, int group_id,
return error;
}
memcpy(red->attr.style, buf, style_nseg * sizeof(QXLFIXED));
+ red_qxl_resources_add_res(qxl_res, style_nseg * sizeof(QXLFIXED));
} else {
red->attr.style_nseg = 0;
red->attr.style = NULL;
}
- red_get_brush_ptr(slots, group_id, &red->brush, &qxl->brush, flags);
+ red_get_brush_ptr(slots, group_id, &red->brush, &qxl->brush, flags, qxl_res);
red->fore_mode = qxl->fore_mode;
red->back_mode = qxl->back_mode;
return 0;
@@ -772,7 +805,8 @@ static void red_put_stroke(SpiceStroke *red)
}
static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
- QXLPHYSICAL addr)
+ QXLPHYSICAL addr,
+ RedQXLResources *qxl_res)
{
RedDataChunk chunks;
QXLString *qxl;
@@ -811,6 +845,8 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
}
spice_assert(bpp != 0);
+ red_qxl_resources_add_res(qxl_res, chunk_size);
+
start = (QXLRasterGlyph*)data;
end = (QXLRasterGlyph*)(data + chunk_size);
red_size = sizeof(SpiceString);
@@ -855,12 +891,13 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
}
static void red_get_text_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceText *red, QXLText *qxl, uint32_t flags)
+ SpiceText *red, QXLText *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red->str = red_get_string(slots, group_id, qxl->str);
+ red->str = red_get_string(slots, group_id, qxl->str, qxl_res);
red_get_rect_ptr(&red->back_area, &qxl->back_area);
- red_get_brush_ptr(slots, group_id, &red->fore_brush, &qxl->fore_brush, flags);
- red_get_brush_ptr(slots, group_id, &red->back_brush, &qxl->back_brush, flags);
+ red_get_brush_ptr(slots, group_id, &red->fore_brush, &qxl->fore_brush, flags, qxl_res);
+ red_get_brush_ptr(slots, group_id, &red->back_brush, &qxl->back_brush, flags, qxl_res);
red->fore_mode = qxl->fore_mode;
red->back_mode = qxl->back_mode;
}
@@ -873,9 +910,10 @@ static void red_put_text_ptr(SpiceText *red)
}
static void red_get_whiteness_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceWhiteness *red, QXLWhiteness *qxl, uint32_t flags)
+ SpiceWhiteness *red, QXLWhiteness *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags);
+ red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags, qxl_res);
}
static void red_put_whiteness(SpiceWhiteness *red)
@@ -884,9 +922,10 @@ static void red_put_whiteness(SpiceWhiteness *red)
}
static void red_get_blackness_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceBlackness *red, QXLBlackness *qxl, uint32_t flags)
+ SpiceBlackness *red, QXLBlackness *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags);
+ red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags, qxl_res);
}
static void red_put_blackness(SpiceWhiteness *red)
@@ -895,9 +934,10 @@ static void red_put_blackness(SpiceWhiteness *red)
}
static void red_get_invers_ptr(RedMemSlotInfo *slots, int group_id,
- SpiceInvers *red, QXLInvers *qxl, uint32_t flags)
+ SpiceInvers *red, QXLInvers *qxl, uint32_t flags,
+ RedQXLResources *qxl_res)
{
- red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags);
+ red_get_qmask_ptr(slots, group_id, &red->mask, &qxl->mask, flags, qxl_res);
}
static void red_put_invers(SpiceWhiteness *red)
@@ -936,7 +976,9 @@ static int red_get_native_drawable(RedMemSlotInfo *slots, int group_id,
if (error) {
return error;
}
- red->release_info = &qxl->release_info;
+ red->qxl_res.release_info = &qxl->release_info;
+ red->qxl_res.num_images = 0;
+ red->qxl_res.other_res_size = 0;
red_get_rect_ptr(&red->bbox, &qxl->bbox);
red_get_clip_ptr(slots, group_id, &red->clip, &qxl->clip);
@@ -955,51 +997,64 @@ static int red_get_native_drawable(RedMemSlotInfo *slots, int group_id,
switch (red->type) {
case QXL_DRAW_ALPHA_BLEND:
red_get_alpha_blend_ptr(slots, group_id,
- &red->u.alpha_blend, &qxl->u.alpha_blend, flags);
+ &red->u.alpha_blend, &qxl->u.alpha_blend, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_BLACKNESS:
red_get_blackness_ptr(slots, group_id,
- &red->u.blackness, &qxl->u.blackness, flags);
+ &red->u.blackness, &qxl->u.blackness, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_BLEND:
- red_get_blend_ptr(slots, group_id, &red->u.blend, &qxl->u.blend, flags);
+ red_get_blend_ptr(slots, group_id, &red->u.blend, &qxl->u.blend, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_COPY:
- error = red_get_copy_ptr(slots, group_id, &red->u.copy, &qxl->u.copy, flags);
+ error = red_get_copy_ptr(slots, group_id, &red->u.copy, &qxl->u.copy, flags,
+ &red->qxl_res);
break;
case QXL_COPY_BITS:
red_get_point_ptr(&red->u.copy_bits.src_pos, &qxl->u.copy_bits.src_pos);
break;
case QXL_DRAW_FILL:
- red_get_fill_ptr(slots, group_id, &red->u.fill, &qxl->u.fill, flags);
+ red_get_fill_ptr(slots, group_id, &red->u.fill, &qxl->u.fill, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_OPAQUE:
- red_get_opaque_ptr(slots, group_id, &red->u.opaque, &qxl->u.opaque, flags);
+ red_get_opaque_ptr(slots, group_id, &red->u.opaque, &qxl->u.opaque, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_INVERS:
- red_get_invers_ptr(slots, group_id, &red->u.invers, &qxl->u.invers, flags);
+ red_get_invers_ptr(slots, group_id, &red->u.invers, &qxl->u.invers, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_NOP:
break;
case QXL_DRAW_ROP3:
- red_get_rop3_ptr(slots, group_id, &red->u.rop3, &qxl->u.rop3, flags);
+ red_get_rop3_ptr(slots, group_id, &red->u.rop3, &qxl->u.rop3, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_COMPOSITE:
- red_get_composite_ptr(slots, group_id, &red->u.composite, &qxl->u.composite, flags);
+ red_get_composite_ptr(slots, group_id, &red->u.composite, &qxl->u.composite, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_STROKE:
- error = red_get_stroke_ptr(slots, group_id, &red->u.stroke, &qxl->u.stroke, flags);
+ error = red_get_stroke_ptr(slots, group_id, &red->u.stroke, &qxl->u.stroke, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_TEXT:
- red_get_text_ptr(slots, group_id, &red->u.text, &qxl->u.text, flags);
+ red_get_text_ptr(slots, group_id, &red->u.text, &qxl->u.text, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_TRANSPARENT:
red_get_transparent_ptr(slots, group_id,
- &red->u.transparent, &qxl->u.transparent, flags);
+ &red->u.transparent, &qxl->u.transparent, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_WHITENESS:
red_get_whiteness_ptr(slots, group_id,
- &red->u.whiteness, &qxl->u.whiteness, flags);
+ &red->u.whiteness, &qxl->u.whiteness, flags,
+ &red->qxl_res);
break;
default:
spice_warning("unknown type %d", red->type);
@@ -1019,7 +1074,8 @@ static int red_get_compat_drawable(RedMemSlotInfo *slots, int group_id,
if (error) {
return error;
}
- red->release_info = &qxl->release_info;
+ red->qxl_res.release_info = &qxl->release_info;
+ red->qxl_res.num_images = 0;
red_get_rect_ptr(&red->bbox, &qxl->bbox);
red_get_clip_ptr(slots, group_id, &red->clip, &qxl->clip);
@@ -1037,17 +1093,21 @@ static int red_get_compat_drawable(RedMemSlotInfo *slots, int group_id,
switch (red->type) {
case QXL_DRAW_ALPHA_BLEND:
red_get_alpha_blend_ptr_compat(slots, group_id,
- &red->u.alpha_blend, &qxl->u.alpha_blend, flags);
+ &red->u.alpha_blend, &qxl->u.alpha_blend, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_BLACKNESS:
red_get_blackness_ptr(slots, group_id,
- &red->u.blackness, &qxl->u.blackness, flags);
+ &red->u.blackness, &qxl->u.blackness, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_BLEND:
- red_get_blend_ptr(slots, group_id, &red->u.blend, &qxl->u.blend, flags);
+ red_get_blend_ptr(slots, group_id, &red->u.blend, &qxl->u.blend, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_COPY:
- error = red_get_copy_ptr(slots, group_id, &red->u.copy, &qxl->u.copy, flags);
+ error = red_get_copy_ptr(slots, group_id, &red->u.copy, &qxl->u.copy, flags,
+ &red->qxl_res);
break;
case QXL_COPY_BITS:
red_get_point_ptr(&red->u.copy_bits.src_pos, &qxl->u.copy_bits.src_pos);
@@ -1060,32 +1120,40 @@ static int red_get_compat_drawable(RedMemSlotInfo *slots, int group_id,
(red->bbox.bottom - red->bbox.top);
break;
case QXL_DRAW_FILL:
- red_get_fill_ptr(slots, group_id, &red->u.fill, &qxl->u.fill, flags);
+ red_get_fill_ptr(slots, group_id, &red->u.fill, &qxl->u.fill, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_OPAQUE:
- red_get_opaque_ptr(slots, group_id, &red->u.opaque, &qxl->u.opaque, flags);
+ red_get_opaque_ptr(slots, group_id, &red->u.opaque, &qxl->u.opaque, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_INVERS:
- red_get_invers_ptr(slots, group_id, &red->u.invers, &qxl->u.invers, flags);
+ red_get_invers_ptr(slots, group_id, &red->u.invers, &qxl->u.invers, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_NOP:
break;
case QXL_DRAW_ROP3:
- red_get_rop3_ptr(slots, group_id, &red->u.rop3, &qxl->u.rop3, flags);
+ red_get_rop3_ptr(slots, group_id, &red->u.rop3, &qxl->u.rop3, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_STROKE:
- error = red_get_stroke_ptr(slots, group_id, &red->u.stroke, &qxl->u.stroke, flags);
+ error = red_get_stroke_ptr(slots, group_id, &red->u.stroke, &qxl->u.stroke, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_TEXT:
- red_get_text_ptr(slots, group_id, &red->u.text, &qxl->u.text, flags);
+ red_get_text_ptr(slots, group_id, &red->u.text, &qxl->u.text, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_TRANSPARENT:
red_get_transparent_ptr(slots, group_id,
- &red->u.transparent, &qxl->u.transparent, flags);
+ &red->u.transparent, &qxl->u.transparent, flags,
+ &red->qxl_res);
break;
case QXL_DRAW_WHITENESS:
red_get_whiteness_ptr(slots, group_id,
- &red->u.whiteness, &qxl->u.whiteness, flags);
+ &red->u.whiteness, &qxl->u.whiteness, flags,
+ &red->qxl_res);
break;
default:
spice_warning("unknown type %d", red->type);
diff --git a/server/red_parse_qxl.h b/server/red_parse_qxl.h
index 3adc9fa..3dcd4bb 100644
--- a/server/red_parse_qxl.h
+++ b/server/red_parse_qxl.h
@@ -23,9 +23,27 @@
#include "red_common.h"
#include "red_memslots.h"
+#define QXL_COMMAND_MAX_IMAGE_NUM 3
+typedef struct RedQXLResources {
+ /* pointers to images of type SPICE_IMAGE_TYPE_(BITMAP|QUIC) that are containd by
+ * the RedDrawable that holds RedQXLResources. BITMAP & QUIC are the only image types
+ * that may occupy a substantial part of qxl's ram */
+ SpiceImage *images[QXL_COMMAND_MAX_IMAGE_NUM];
+ uint32_t images_size[QXL_COMMAND_MAX_IMAGE_NUM];
+ uint32_t num_images;
+
+ /* the size of reosurces, other than bitmaps, that the RedDrawable refers
+ * to (e.g., QXLPathSeg) */
+ uint32_t other_res_size;
+ /* only images of type BITMAP|QUIC point to the device memeory. Data of other resources
+ * is copied. Thus, the resources can be released after there is no reference
+ * to a bitmap (or quic) data */
+ QXLReleaseInfo *release_info;
+} RedQXLResources;
+
typedef struct RedDrawable {
int refs;
- QXLReleaseInfo *release_info;
+ RedQXLResources qxl_res;
uint32_t surface_id;
uint8_t effect;
uint8_t type;
diff --git a/server/red_worker.c b/server/red_worker.c
index a099434..78cfdd7 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1754,7 +1754,7 @@ static inline void put_red_drawable(RedWorker *worker, RedDrawable *red_drawable
}
worker->red_drawable_count--;
release_info_ext.group_id = group_id;
- release_info_ext.info = red_drawable->release_info;
+ release_info_ext.info = red_drawable->qxl_res.release_info;
worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
red_put_drawable(red_drawable);
free(red_drawable);