From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> --- server/display-channel.c | 59 +++++++++++++++++++++++++++++++++++++++++++ server/display-channel.h | 4 +++ server/red_worker.c | 66 +++--------------------------------------------- 3 files changed, 67 insertions(+), 62 deletions(-) diff --git a/server/display-channel.c b/server/display-channel.c index 1eb2fa1..28fd565 100644 --- a/server/display-channel.c +++ b/server/display-channel.c @@ -2029,3 +2029,62 @@ DisplayChannel* display_channel_new(RedWorker *worker, int migrate, int stream_v return display; } + +static inline void set_surface_release_info(QXLReleaseInfoExt *release_info_ext, + QXLReleaseInfo *release_info, uint32_t group_id) +{ + release_info_ext->info = release_info; + release_info_ext->group_id = group_id; +} + +void display_channel_process_surface_cmd(DisplayChannel *display, RedSurfaceCmd *surface, + uint32_t group_id, int loadvm) +{ + uint32_t surface_id; + RedSurface *red_surface; + uint8_t *data; + + surface_id = surface->surface_id; + if SPICE_UNLIKELY(surface_id >= display->n_surfaces) { + goto exit; + } + + red_surface = &display->surfaces[surface_id]; + + switch (surface->type) { + case QXL_SURFACE_CMD_CREATE: { + uint32_t height = surface->u.surface_create.height; + int32_t stride = surface->u.surface_create.stride; + int reloaded_surface = loadvm || (surface->flags & QXL_SURF_FLAG_KEEP_DATA); + + if (red_surface->refs) { + spice_warning("avoiding creating a surface twice"); + break; + } + data = surface->u.surface_create.data; + if (stride < 0) { + data -= (int32_t)(stride * (height - 1)); + } + display_channel_create_surface(display, surface_id, surface->u.surface_create.width, + height, stride, surface->u.surface_create.format, data, + reloaded_surface, + // reloaded surfaces will be sent on demand + !reloaded_surface); + set_surface_release_info(&red_surface->create, surface->release_info, group_id); + break; + } + case QXL_SURFACE_CMD_DESTROY: + if (!red_surface->refs) { + spice_warning("avoiding destroying a surface twice"); + break; + } + set_surface_release_info(&red_surface->destroy, surface->release_info, group_id); + display_channel_destroy_surface(display, surface_id); + break; + default: + spice_warn_if_reached(); + }; +exit: + red_put_surface_cmd(surface); + free(surface); +} diff --git a/server/display-channel.h b/server/display-channel.h index e17381c..5fa17e6 100644 --- a/server/display-channel.h +++ b/server/display-channel.h @@ -301,6 +301,10 @@ void display_channel_destroy_surfaces (DisplayCha void display_channel_destroy_surface (DisplayChannel *display, uint32_t surface_id); uint32_t display_channel_generate_uid (DisplayChannel *display); +void display_channel_process_surface_cmd (DisplayChannel *display, + RedSurfaceCmd *surface, + uint32_t group_id, + int loadvm); static inline int validate_surface(DisplayChannel *display, uint32_t surface_id) { diff --git a/server/red_worker.c b/server/red_worker.c index 77ad06b..cf9e41f 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -149,13 +149,6 @@ static void common_release_recv_buf(RedChannelClient *rcc, uint16_t type, uint32 } } -static inline void set_surface_release_info(QXLReleaseInfoExt *release_info_ext, - QXLReleaseInfo *release_info, uint32_t group_id) -{ - release_info_ext->info = release_info; - release_info_ext->group_id = group_id; -} - void red_drawable_unref(RedWorker *worker, RedDrawable *red_drawable, uint32_t group_id) { @@ -192,59 +185,6 @@ static void red_process_draw(RedWorker *worker, RedDrawable *red_drawable, } -static void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface, - uint32_t group_id, int loadvm) -{ - DisplayChannel *display = worker->display_channel; - uint32_t surface_id; - RedSurface *red_surface; - uint8_t *data; - - surface_id = surface->surface_id; - if SPICE_UNLIKELY(surface_id >= display->n_surfaces) { - goto exit; - } - - red_surface = &display->surfaces[surface_id]; - - switch (surface->type) { - case QXL_SURFACE_CMD_CREATE: { - uint32_t height = surface->u.surface_create.height; - int32_t stride = surface->u.surface_create.stride; - int reloaded_surface = loadvm || (surface->flags & QXL_SURF_FLAG_KEEP_DATA); - - if (red_surface->refs) { - spice_warning("avoiding creating a surface twice"); - break; - } - data = surface->u.surface_create.data; - if (stride < 0) { - data -= (int32_t)(stride * (height - 1)); - } - display_channel_create_surface(worker->display_channel, surface_id, surface->u.surface_create.width, - height, stride, surface->u.surface_create.format, data, - reloaded_surface, - // reloaded surfaces will be sent on demand - !reloaded_surface); - set_surface_release_info(&red_surface->create, surface->release_info, group_id); - break; - } - case QXL_SURFACE_CMD_DESTROY: - if (!red_surface->refs) { - spice_warning("avoiding destroying a surface twice"); - break; - } - set_surface_release_info(&red_surface->destroy, surface->release_info, group_id); - display_channel_destroy_surface(display, surface_id); - break; - default: - spice_warn_if_reached(); - }; -exit: - red_put_surface_cmd(surface); - free(surface); -} - static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size, int *ring_is_empty) { QXLCommandExt ext_cmd; @@ -399,7 +339,8 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int * free(surface); break; } - red_process_surface(worker, surface, ext_cmd.group_id, FALSE); + display_channel_process_surface_cmd(worker->display_channel, surface, + ext_cmd.group_id, FALSE); break; } default: @@ -1414,7 +1355,8 @@ static int loadvm_command(RedWorker *worker, QXLCommandExt *ext) free(surface_cmd); return FALSE; } - red_process_surface(worker, surface_cmd, ext->group_id, TRUE); + display_channel_process_surface_cmd(worker->display_channel, surface_cmd, + ext->group_id, TRUE); break; default: spice_warning("unhandled loadvm command type (%d)", ext->cmd.type); -- 2.4.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel