With this patch applied the spice server will not release surface create commands for the whole lifecycle of the surface. When the surface is destroyed both create and destroy commands are released.
This has the effect that the surface metadata (size, depth, ...) is kept in qxl device memory. This in turn makes it alot easier for qemu to handle savevm/loadvm. It just needs to do some minimal command parsing and maintain pointers to the create commands for the active surfaces. Signed-off-by: Gerd Hoffmann <kra...@redhat.com> --- server/red_worker.c | 35 ++++++++++++++++++----------------- 1 files changed, 18 insertions(+), 17 deletions(-) diff --git a/server/red_worker.c b/server/red_worker.c index 54cb780..208b685 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -890,8 +890,7 @@ typedef struct RedSurface { QRegion draw_dirty_region; //fix me - better handling here - QXLReleaseInfo *release_info; - uint32_t release_group_id; + QXLReleaseInfoExt create, destroy; } RedSurface; #ifdef STREAM_TRACE @@ -1500,12 +1499,11 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id) #endif if (surface->context.canvas) { surface->context.canvas->ops->destroy(surface->context.canvas); - if (surface->release_info) { - QXLReleaseInfoExt release_info_ext; - - release_info_ext.group_id = surface->release_group_id; - release_info_ext.info = surface->release_info; - worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext); + if (surface->create.info) { + worker->qxl->st->qif->release_resource(worker->qxl, surface->create); + } + if (surface->destroy.info) { + worker->qxl->st->qif->release_resource(worker->qxl, surface->destroy); } region_destroy(&surface->draw_dirty_region); @@ -1517,15 +1515,20 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id) } } -static inline void set_surface_release_info(RedWorker *worker, uint32_t surface_id, +static inline void set_surface_release_info(RedWorker *worker, uint32_t surface_id, int is_create, QXLReleaseInfo *release_info, uint32_t group_id) { RedSurface *surface; surface = &worker->surfaces[surface_id]; - surface->release_info = release_info; - surface->release_group_id = group_id; + if (is_create) { + surface->create.info = release_info; + surface->create.group_id = group_id; + } else { + surface->destroy.info = release_info; + surface->destroy.group_id = group_id; + } } static inline void free_qxl_drawable(RedWorker *worker, QXLDrawable *drawable, uint32_t group_id, @@ -3881,7 +3884,6 @@ static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface unsigned long saved_data = (unsigned long)surface->u.surface_create.data; uint32_t height = surface->u.surface_create.height; int32_t stride = surface->u.surface_create.stride; - QXLReleaseInfoExt release_info_ext; data = (uint8_t *)get_virt(&worker->mem_slots, saved_data, height * abs(stride), group_id); if (stride < 0) { @@ -3889,14 +3891,12 @@ static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface } red_create_surface(worker, surface_id, surface->u.surface_create.width, height, stride, surface->u.surface_create.format, data); - release_info_ext.group_id = group_id; - release_info_ext.info = &surface->release_info; - worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext); + set_surface_release_info(worker, surface_id, 1, &surface->release_info, group_id); break; } case QXL_SURFACE_CMD_DESTROY: PANIC_ON(!red_surface->context.canvas); - set_surface_release_info(worker, surface_id, &surface->release_info, group_id); + set_surface_release_info(worker, surface_id, 0, &surface->release_info, group_id); red_handle_depends_on_target_surface(worker, surface_id); red_current_clear(worker, surface_id); red_clear_surface_glz_drawables(worker, surface_id); @@ -8040,7 +8040,8 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui surface->context.stride = stride; surface->context.line_0 = line_0; memset(line_0 + (int32_t)(stride * (height - 1)), 0, height*abs(stride)); - surface->release_info = NULL; + surface->create.info = NULL; + surface->destroy.info = NULL; ring_init(&surface->current); ring_init(&surface->current_list); ring_init(&surface->depend_on_me); -- 1.6.6.1 _______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel