diff options
author | Alon Levy <alevy@redhat.com> | 2011-07-07 17:25:19 +0200 |
---|---|---|
committer | Alon Levy <alevy@redhat.com> | 2011-07-20 16:00:19 +0300 |
commit | 2a4d97fb780cf3ce2d9060751d0bec2fdc9800a9 (patch) | |
tree | 72885e849ea35eb95a7e10d2ada5aa49952bebe5 | |
parent | b26f0532c170068e91e4946592eab2fd9d6cbae5 (diff) | |
download | spice-2a4d97fb780cf3ce2d9060751d0bec2fdc9800a9.tar.gz spice-2a4d97fb780cf3ce2d9060751d0bec2fdc9800a9.tar.xz spice-2a4d97fb780cf3ce2d9060751d0bec2fdc9800a9.zip |
server: add QXLWorker.flush_surfaces_async for S3/S4 support
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.
-rw-r--r-- | server/red_dispatcher.c | 20 | ||||
-rw-r--r-- | server/red_worker.c | 25 | ||||
-rw-r--r-- | server/red_worker.h | 2 | ||||
-rw-r--r-- | server/spice-server.syms | 1 | ||||
-rw-r--r-- | server/spice.h | 2 |
5 files changed, 46 insertions, 4 deletions
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c index 7f3efe87..7792d90a 100644 --- a/server/red_dispatcher.c +++ b/server/red_dispatcher.c @@ -541,6 +541,18 @@ static void qxl_worker_start(QXLWorker *qxl_worker) red_dispatcher_start((RedDispatcher*)qxl_worker); } +static void red_dispatcher_flush_surfaces_async(RedDispatcher *dispatcher, uint64_t cookie) +{ + 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 red_dispatcher_stop(RedDispatcher *dispatcher) { RedWorkerMessage message = RED_WORKER_MESSAGE_STOP; @@ -788,6 +800,12 @@ void spice_qxl_destroy_surface_async(QXLInstance *instance, uint32_t surface_id, red_dispatcher_destroy_surface_wait(instance->st->dispatcher, surface_id, 1, cookie); } +SPICE_GNUC_VISIBLE +void spice_qxl_flush_surfaces_async(QXLInstance *instance, uint64_t cookie) +{ + red_dispatcher_flush_surfaces_async(instance->st->dispatcher, cookie); +} + void red_dispatcher_async_complete(struct RedDispatcher *dispatcher, uint64_t cookie) { pthread_mutex_lock(&dispatcher->async_lock); @@ -806,6 +824,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"); } diff --git a/server/red_worker.c b/server/red_worker.c index 9b5d9cd5..834c1c55 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -9675,18 +9675,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); } @@ -9727,6 +9740,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; @@ -9936,6 +9950,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 604437bf..15d5f82c 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-server.syms b/server/spice-server.syms index 28e6025b..b908d854 100644 --- a/server/spice-server.syms +++ b/server/spice-server.syms @@ -79,6 +79,7 @@ global: spice_qxl_destroy_primary_surface_async; spice_qxl_create_primary_surface_async; spice_qxl_destroy_surface_async; + spice_qxl_flush_surfaces_async; } SPICE_SERVER_0.8.1; SPICE_SERVER_0.10.0 { diff --git a/server/spice.h b/server/spice.h index 89872ea6..549dd0c5 100644 --- a/server/spice.h +++ b/server/spice.h @@ -153,6 +153,8 @@ void spice_qxl_destroy_primary_surface_async(QXLInstance *instance, uint32_t sur void spice_qxl_create_primary_surface_async(QXLInstance *instance, uint32_t surface_id, QXLDevSurfaceCreate *surface, uint64_t cookie); void spice_qxl_destroy_surface_async(QXLInstance *instance, uint32_t surface_id, uint64_t cookie); +/* suspend and resolution change on windows drivers */ +void spice_qxl_flush_surfaces_async(QXLInstance *instance, uint64_t cookie); typedef struct QXLDrawArea { uint8_t *buf; |