diff options
-rw-r--r-- | server/red_dispatcher.c | 29 | ||||
-rw-r--r-- | server/red_worker.c | 123 | ||||
-rw-r--r-- | server/red_worker.h | 3 | ||||
-rw-r--r-- | server/vd_interface.h | 5 |
4 files changed, 59 insertions, 101 deletions
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c index 3d1d6f98..2d23cbe1 100644 --- a/server/red_dispatcher.c +++ b/server/red_dispatcher.c @@ -345,40 +345,34 @@ static void qxl_worker_oom(QXLWorker *qxl_worker) } } -static void qxl_worker_save(QXLWorker *qxl_worker) +static void qxl_worker_start(QXLWorker *qxl_worker) { RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker; - RedWorkeMessage message = RED_WORKER_MESSAGE_SAVE; + RedWorkeMessage message = RED_WORKER_MESSAGE_START; write_message(dispatcher->channel, &message); - read_message(dispatcher->channel, &message); - ASSERT(message == RED_WORKER_MESSAGE_READY); } -static void qxl_worker_load(QXLWorker *qxl_worker) +static void qxl_worker_stop(QXLWorker *qxl_worker) { RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker; - RedWorkeMessage message = RED_WORKER_MESSAGE_LOAD; + RedWorkeMessage message = RED_WORKER_MESSAGE_STOP; write_message(dispatcher->channel, &message); read_message(dispatcher->channel, &message); ASSERT(message == RED_WORKER_MESSAGE_READY); } -static void qxl_worker_start(QXLWorker *qxl_worker) +void qxl_worker_loadvm_commands(QXLWorker *qxl_worker, + struct QXLCommandExt *ext, uint32_t count) { RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker; - RedWorkeMessage message = RED_WORKER_MESSAGE_START; - - write_message(dispatcher->channel, &message); -} - -static void qxl_worker_stop(QXLWorker *qxl_worker) -{ - RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker; - RedWorkeMessage message = RED_WORKER_MESSAGE_STOP; + RedWorkeMessage message = RED_WORKER_MESSAGE_LOADVM_COMMANDS; + red_printf(""); write_message(dispatcher->channel, &message); + send_data(dispatcher->channel, &count, sizeof(uint32_t)); + send_data(dispatcher->channel, ext, sizeof(QXLCommandExt) * count); read_message(dispatcher->channel, &message); ASSERT(message == RED_WORKER_MESSAGE_READY); } @@ -506,8 +500,6 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl) dispatcher->base.minor_version = SPICE_INTERFACE_QXL_MINOR; dispatcher->base.wakeup = qxl_worker_wakeup; dispatcher->base.oom = qxl_worker_oom; - dispatcher->base.save = qxl_worker_save; - dispatcher->base.load = qxl_worker_load; dispatcher->base.start = qxl_worker_start; dispatcher->base.stop = qxl_worker_stop; dispatcher->base.update_area = qxl_worker_update_area; @@ -521,6 +513,7 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl) dispatcher->base.reset_image_cache = qxl_worker_reset_image_cache; dispatcher->base.reset_cursor = qxl_worker_reset_cursor; dispatcher->base.destroy_surface_wait = qxl_worker_destroy_surface_wait; + dispatcher->base.loadvm_commands = qxl_worker_loadvm_commands; qxl->st->qif->get_init_info(qxl, &init_info); diff --git a/server/red_worker.c b/server/red_worker.c index 680bca1f..6dbbc221 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -3878,9 +3878,9 @@ static inline void red_process_drawable(RedWorker *worker, QXLDrawable *drawable static inline void red_create_surface(RedWorker *worker, uint32_t surface_id,uint32_t width, uint32_t height, int32_t stride, uint32_t format, - void *line_0); + void *line_0, int data_is_valid); -static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface, uint32_t group_id) +static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface, uint32_t group_id, int data_is_valid) { int surface_id; RedSurface *red_surface; @@ -3902,7 +3902,8 @@ static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface data -= (int32_t)(stride * (height - 1)); } red_create_surface(worker, surface_id, surface->u.surface_create.width, - height, stride, surface->u.surface_create.format, data); + height, stride, surface->u.surface_create.format, data, + data_is_valid); set_surface_release_info(worker, surface_id, 1, &surface->release_info, group_id); break; } @@ -4923,7 +4924,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size) case QXL_CMD_SURFACE: { QXLSurfaceCmd *surface = (QXLSurfaceCmd *)get_virt(&worker->mem_slots, ext_cmd.cmd.data, sizeof(QXLSurfaceCmd), ext_cmd.group_id); - red_process_surface(worker, surface, ext_cmd.group_id); + red_process_surface(worker, surface, ext_cmd.group_id, 0); break; } default: @@ -8041,7 +8042,7 @@ static inline void red_create_surface_item(RedWorker *worker, int surface_id) static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, uint32_t width, uint32_t height, int32_t stride, uint32_t format, - void *line_0) + void *line_0, int data_is_valid) { uint32_t i; RedSurface *surface = &worker->surfaces[surface_id]; @@ -8056,7 +8057,9 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui surface->context.format = format; surface->context.stride = stride; surface->context.line_0 = line_0; - memset(line_0 + (int32_t)(stride * (height - 1)), 0, height*abs(stride)); + if (!data_is_valid) { + memset(line_0 + (int32_t)(stride * (height - 1)), 0, height*abs(stride)); + } surface->create.info = NULL; surface->destroy.info = NULL; ring_init(&surface->current); @@ -8850,29 +8853,6 @@ typedef struct __attribute__ ((__packed__)) CursorData { SpiceCursor _cursor; } CursorData; -static void red_save_cursor(RedWorker *worker) -{ - CursorData *cursor_data; - LocalCursor *local; - int size; - - ASSERT(worker->cursor); - ASSERT(worker->cursor->type == CURSOR_TYPE_LOCAL); - - local = (LocalCursor *)worker->cursor; - size = sizeof(CursorData) + sizeof(SpiceCursor) + local->data_size; - cursor_data = spice_malloc(size); - - cursor_data->position = worker->cursor_position; - cursor_data->visible = worker->cursor_visible; - cursor_data->trail_frequency = worker->cursor_trail_frequency; - cursor_data->trail_length = worker->cursor_trail_length; - cursor_data->data_size = local->data_size; - cursor_data->_cursor.header = local->red_cursor.header; - memcpy(cursor_data->_cursor.data, local->red_cursor.data, local->data_size); - worker->qxl->st->qif->set_save_data(worker->qxl, cursor_data, size); -} - static LocalCursor *_new_local_cursor(SpiceCursorHeader *header, int data_size, SpicePoint16 position) { LocalCursor *local; @@ -8932,37 +8912,6 @@ static void red_cursor_flush(RedWorker *worker) red_release_cursor(worker, &local->base); } -static void red_save(RedWorker *worker) -{ - if (!worker->cursor) { - worker->qxl->st->qif->set_save_data(worker->qxl, NULL, 0); - return; - } - red_save_cursor(worker); -} - -static void red_cursor_load(RedWorker *worker) -{ - CursorData *cursor_data = worker->qxl->st->qif->get_save_data(worker->qxl); - LocalCursor *local; - - if (!cursor_data) { - return; - } - - worker->cursor_position = cursor_data->position; - worker->cursor_visible = cursor_data->visible; - worker->cursor_trail_frequency = cursor_data->trail_frequency; - worker->cursor_trail_length = cursor_data->trail_length; - - local = _new_local_cursor(&cursor_data->_cursor.header, cursor_data->data_size, - cursor_data->position); - ASSERT(local); - memcpy(local->red_cursor.data, cursor_data->_cursor.data, cursor_data->data_size); - red_set_cursor(worker, &local->base); - red_release_cursor(worker, &local->base); -} - static void red_wait_outgoiong_item(RedChannel *channel) { uint64_t end_time; @@ -9155,7 +9104,7 @@ static inline void handle_dev_create_primary_surface(RedWorker *worker) } red_create_surface(worker, 0, surface.width, surface.height, surface.stride, surface.format, - line_0); + line_0, surface.flags & QXL_SURF_FLAG_KEEP_DATA); if (worker->display_channel) { red_pipe_add_verb(&worker->display_channel->base, SPICE_MSG_DISPLAY_MARK); @@ -9289,22 +9238,7 @@ static void handle_dev_input(EventListener *listener, uint32_t events) red_printf("disconnect"); red_disconnect_display((RedChannel *)worker->display_channel); break; - case RED_WORKER_MESSAGE_SAVE: - red_printf("save"); - ASSERT(!worker->running); - red_save(worker); - message = RED_WORKER_MESSAGE_READY; - write_message(worker->channel, &message); - break; - case RED_WORKER_MESSAGE_LOAD: - red_printf("load"); - ASSERT(!worker->running); - red_add_surface_image(worker, 0); - red_cursor_load(worker); - message = RED_WORKER_MESSAGE_READY; - write_message(worker->channel, &message); - break; - case RED_WORKER_MESSAGE_STOP: { + case RED_WORKER_MESSAGE_STOP: { int x; red_printf("stop"); @@ -9420,6 +9354,41 @@ static void handle_dev_input(EventListener *listener, uint32_t events) case RED_WORKER_MESSAGE_RESET_MEMSLOTS: red_memslot_info_reset(&worker->mem_slots); break; + case RED_WORKER_MESSAGE_LOADVM_COMMANDS: { + uint32_t count; + QXLCommandExt ext; + QXLCursorCmd *cursor_cmd; + QXLSurfaceCmd *surface_cmd; + + red_printf("loadvm_commands"); + receive_data(worker->channel, &count, sizeof(uint32_t)); + while (count > 0) { + receive_data(worker->channel, &ext, sizeof(QXLCommandExt)); + switch (ext.cmd.type) { + case QXL_CMD_CURSOR: + cursor_cmd = (QXLCursorCmd *)get_virt(&worker->mem_slots, + ext.cmd.data, + sizeof(QXLCursorCmd), + ext.group_id); + qxl_process_cursor(worker, cursor_cmd, ext.group_id); + break; + case QXL_CMD_SURFACE: + surface_cmd = (QXLSurfaceCmd *)get_virt(&worker->mem_slots, + ext.cmd.data, + sizeof(QXLSurfaceCmd), + ext.group_id); + red_process_surface(worker, surface_cmd, ext.group_id, 1); + break; + default: + red_printf("unhandled loadvm command type (%d)", ext.cmd.type); + break; + } + count--; + } + message = RED_WORKER_MESSAGE_READY; + write_message(worker->channel, &message); + break; + } default: red_error("message error"); } diff --git a/server/red_worker.h b/server/red_worker.h index e53d5182..88c1e90c 100644 --- a/server/red_worker.h +++ b/server/red_worker.h @@ -50,8 +50,6 @@ enum { RED_WORKER_MESSAGE_DISPLAY_CONNECT, RED_WORKER_MESSAGE_DISPLAY_DISCONNECT, RED_WORKER_MESSAGE_DISPLAY_MIGRATE, - RED_WORKER_MESSAGE_SAVE, - RED_WORKER_MESSAGE_LOAD, RED_WORKER_MESSAGE_START, RED_WORKER_MESSAGE_STOP, RED_WORKER_MESSAGE_CURSOR_CONNECT, @@ -69,6 +67,7 @@ enum { RED_WORKER_MESSAGE_RESET_CURSOR, RED_WORKER_MESSAGE_RESET_IMAGE_CACHE, RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT, + RED_WORKER_MESSAGE_LOADVM_COMMANDS, }; typedef uint32_t RedWorkeMessage; diff --git a/server/vd_interface.h b/server/vd_interface.h index 0f26822d..d3cf5cbe 100644 --- a/server/vd_interface.h +++ b/server/vd_interface.h @@ -103,8 +103,6 @@ struct QXLWorker { uint32_t major_version; void (*wakeup)(QXLWorker *worker); void (*oom)(QXLWorker *worker); - void (*save)(QXLWorker *worker); - void (*load)(QXLWorker *worker); void (*start)(QXLWorker *worker); void (*stop)(QXLWorker *worker); void (*update_area)(QXLWorker *qxl_worker, uint32_t surface_id, @@ -120,6 +118,7 @@ struct QXLWorker { void (*reset_image_cache)(QXLWorker *worker); void (*reset_cursor)(QXLWorker *worker); void (*destroy_surface_wait)(QXLWorker *worker, uint32_t surface_id); + void (*loadvm_commands)(QXLWorker *worker, struct QXLCommandExt *ext, uint32_t count); }; typedef struct DrawArea { @@ -196,8 +195,6 @@ struct QXLInterface { int (*get_cursor_command)(QXLInstance *qin, struct QXLCommandExt *cmd); int (*req_cursor_notification)(QXLInstance *qin); void (*notify_update)(QXLInstance *qin, uint32_t update_id); - void (*set_save_data)(QXLInstance *qin, void *data, int size); - void *(*get_save_data)(QXLInstance *qin); int (*flush_resources)(QXLInstance *qin); }; |