mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 14:41:25 +00:00
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.
This commit is contained in:
parent
b26f0532c1
commit
2a4d97fb78
@ -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");
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user