diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2013-10-11 14:11:23 -0400 |
---|---|---|
committer | Yonit Halperin <yhalperi@redhat.com> | 2013-10-23 15:44:11 -0400 |
commit | 0272dc65a73a14c7c9a9640a3e003dc75f6a4e19 (patch) | |
tree | 22525ff8f8926486641025773696920e647e29f0 | |
parent | a5100670f4f1af0fa384425c4df8822679d6fccb (diff) |
red_parse_qxl: track qxl resources size
-rw-r--r-- | server/red_parse_qxl.c | 214 | ||||
-rw-r--r-- | server/red_parse_qxl.h | 20 | ||||
-rw-r--r-- | server/red_worker.c | 2 |
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); |