This does the following, all to remove any referenced memory on the pci bars: flush_all_qxl_commands(worker); flush_all_surfaces(worker); red_wait_outgoing_item((RedChannel *)worker->display_channel); red_wait_outgoing_item((RedChannel *)worker->cursor_channel);
The added api is specifically async, i.e. it calls async_complete when done. --- server/red_dispatcher.c | 17 +++++++++++++++++ server/red_worker.c | 25 +++++++++++++++++++++---- server/red_worker.h | 2 ++ server/spice.h | 2 ++ 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c index f0af364..fcdc4f7 100644 --- a/server/red_dispatcher.c +++ b/server/red_dispatcher.c @@ -512,6 +512,19 @@ static void qxl_worker_oom(QXLWorker *qxl_worker) } } +static void qxl_worker_flush_surfaces_async(QXLWorker *qxl_worker, uint64_t cookie) +{ + RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker; + RedWorkerMessage message = red_dispatcher_async_start(dispatcher, + RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC); + + if (message == RED_WORKER_MESSAGE_NOP) { + return; + } + write_message(dispatcher->channel, &message); + send_data(dispatcher->channel, &cookie, sizeof(cookie)); +} + static void qxl_worker_start(QXLWorker *qxl_worker) { RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker; @@ -642,6 +655,8 @@ void red_dispatcher_async_complete(struct RedDispatcher *dispatcher, uint64_t co break; case RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC: break; + case RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC: + break; default: red_printf("unexpected message"); } @@ -716,6 +731,8 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl) dispatcher->base.create_primary_surface_async = qxl_worker_create_primary_surface_async; dispatcher->base.destroy_surface_wait_async = qxl_worker_destroy_surface_wait_async; + dispatcher->base.flush_surfaces_async = qxl_worker_flush_surfaces_async; + qxl->st->qif->get_init_info(qxl, &init_info); init_data.memslot_id_bits = init_info.memslot_id_bits; diff --git a/server/red_worker.c b/server/red_worker.c index e072994..ccd7de1 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -9673,18 +9673,31 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker) red_cursor_reset(worker); } -static void handle_dev_stop(RedWorker *worker) +static void flush_all_surfaces(RedWorker *worker) { int x; - ASSERT(worker->running); - worker->running = FALSE; - red_display_clear_glz_drawables(worker->display_channel); for (x = 0; x < NUM_SURFACES; ++x) { if (worker->surfaces[x].context.canvas) { red_current_flush(worker, x); } } +} + +static void handle_dev_flush_surfaces(RedWorker *worker) +{ + flush_all_qxl_commands(worker); + flush_all_surfaces(worker); + red_wait_outgoing_item((RedChannel *)worker->display_channel); + red_wait_outgoing_item((RedChannel *)worker->cursor_channel); +} + +static void handle_dev_stop(RedWorker *worker) +{ + ASSERT(worker->running); + worker->running = FALSE; + red_display_clear_glz_drawables(worker->display_channel); + flush_all_surfaces(worker); red_wait_outgoing_item((RedChannel *)worker->display_channel); red_wait_outgoing_item((RedChannel *)worker->cursor_channel); } @@ -9725,6 +9738,7 @@ static void handle_dev_input(EventListener *listener, uint32_t events) case RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC: case RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC: case RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC: + case RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC: call_async_complete = 1; receive_data(worker->channel, &cookie, sizeof(cookie)); break; @@ -9934,6 +9948,9 @@ static void handle_dev_input(EventListener *listener, uint32_t events) } break; } + case RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC: + handle_dev_flush_surfaces(worker); + break; default: red_error("message error"); } diff --git a/server/red_worker.h b/server/red_worker.h index 604437b..15d5f82 100644 --- a/server/red_worker.h +++ b/server/red_worker.h @@ -77,6 +77,8 @@ enum { RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC, RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC, RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC, + /* suspend/windows resolution change command */ + RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC, }; typedef uint32_t RedWorkerMessage; diff --git a/server/spice.h b/server/spice.h index 727507c..da147cd 100644 --- a/server/spice.h +++ b/server/spice.h @@ -132,6 +132,8 @@ struct QXLWorker { void (*create_primary_surface_async)(QXLWorker *worker, uint32_t surface_id, QXLDevSurfaceCreate *surface, uint64_t cookie); void (*destroy_surface_wait_async)(QXLWorker *worker, uint32_t surface_id, uint64_t cookie); + /* suspend and resolution change on windows drivers */ + void (*flush_surfaces_async)(QXLWorker *worker, uint64_t cookie); }; typedef struct QXLDrawArea { -- 1.7.6 _______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel