From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> --- server/display-channel.c | 92 ++++++++++++++++++++++++++++++++++ server/display-channel.h | 4 ++ server/red_worker.c | 125 +++-------------------------------------------- 3 files changed, 103 insertions(+), 118 deletions(-) diff --git a/server/display-channel.c b/server/display-channel.c index ec076ce..051d597 100644 --- a/server/display-channel.c +++ b/server/display-channel.c @@ -1470,6 +1470,98 @@ void display_channel_destroy_surfaces(DisplayChannel *display) display_channel_free_glz_drawables(display); } +static void send_create_surface(DisplayChannel *display, int surface_id, int image_ready) +{ + DisplayChannelClient *dcc; + RingItem *item, *next; + + FOREACH_DCC(display, item, next, dcc) { + dcc_create_surface(dcc, surface_id); + if (image_ready) + dcc_push_surface_image(dcc, surface_id); + } +} + +static SpiceCanvas* +create_canvas_for_surface(DisplayChannel *display, RedSurface *surface, + uint32_t renderer, uint32_t width, uint32_t height, + int32_t stride, uint32_t format, void *line_0) +{ + SpiceCanvas *canvas; + + switch (renderer) { + case RED_RENDERER_SW: + canvas = canvas_create_for_data(width, height, format, + line_0, stride, + &display->image_cache.base, + &display->image_surfaces, NULL, NULL, NULL); + surface->context.top_down = TRUE; + surface->context.canvas_draws_on_surface = TRUE; + return canvas; + default: + spice_warn_if_reached(); + }; + + return NULL; +} + +void display_channel_create_surface(DisplayChannel *display, uint32_t surface_id, uint32_t width, + uint32_t height, int32_t stride, uint32_t format, + void *line_0, int data_is_valid, int send_client) +{ + RedSurface *surface = &display->surfaces[surface_id]; + uint32_t i; + + spice_warn_if(surface->context.canvas); + + surface->context.canvas_draws_on_surface = FALSE; + surface->context.width = width; + surface->context.height = height; + surface->context.format = format; + surface->context.stride = stride; + surface->context.line_0 = line_0; + if (!data_is_valid) { + char *data = line_0; + if (stride < 0) { + data -= abs(stride) * (height - 1); + } + memset(data, 0, height*abs(stride)); + } + surface->create.info = NULL; + surface->destroy.info = NULL; + ring_init(&surface->current); + ring_init(&surface->current_list); + ring_init(&surface->depend_on_me); + region_init(&surface->draw_dirty_region); + surface->refs = 1; + if (display->renderer != RED_RENDERER_INVALID) { + surface->context.canvas = create_canvas_for_surface(display, surface, display->renderer, + width, height, stride, + surface->context.format, line_0); + if (!surface->context.canvas) { + spice_critical("drawing canvas creating failed - can`t create same type canvas"); + } + + if (send_client) + send_create_surface(display, surface_id, data_is_valid); + return; + } + + for (i = 0; i < display->num_renderers; i++) { + surface->context.canvas = create_canvas_for_surface(display, surface, display->renderers[i], + width, height, stride, + surface->context.format, line_0); + if (surface->context.canvas) { //no need canvas check + display->renderer = display->renderers[i]; + if (send_client) + send_create_surface(display, surface_id, data_is_valid); + return; + } + } + + spice_critical("unable to create drawing canvas"); +} + static void on_disconnect(RedChannelClient *rcc) { DisplayChannel *display; diff --git a/server/display-channel.h b/server/display-channel.h index 34caafe..750362b 100644 --- a/server/display-channel.h +++ b/server/display-channel.h @@ -255,6 +255,10 @@ DisplayChannel* display_channel_new (RedWorker int migrate, int stream_video, uint32_t n_surfaces); +void display_channel_create_surface (DisplayChannel *display, uint32_t surface_id, + uint32_t width, uint32_t height, + int32_t stride, uint32_t format, void *line_0, + int data_is_valid, int send_client); void display_channel_draw (DisplayChannel *display, const SpiceRect *area, int surface_id); diff --git a/server/red_worker.c b/server/red_worker.c index 7af9c9b..470f813 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -134,9 +134,6 @@ typedef struct BitmapData { } BitmapData; static inline void display_begin_send_message(RedChannelClient *rcc); -static void red_create_surface(DisplayChannel *display, uint32_t surface_id, uint32_t width, - uint32_t height, int32_t stride, uint32_t format, - void *line_0, int data_is_valid, int send_client); QXLInstance* red_worker_get_qxl(RedWorker *worker) { @@ -740,11 +737,11 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface if (stride < 0) { data -= (int32_t)(stride * (height - 1)); } - red_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); + 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; } @@ -3415,114 +3412,6 @@ static void red_migrate_display(DisplayChannel *display, RedChannelClient *rcc) } } -static inline void *create_canvas_for_surface(DisplayChannel *display, RedSurface *surface, - uint32_t renderer, uint32_t width, uint32_t height, - int32_t stride, uint32_t format, void *line_0) -{ - SpiceCanvas *canvas; - - switch (renderer) { - case RED_RENDERER_SW: - canvas = canvas_create_for_data(width, height, format, - line_0, stride, - &display->image_cache.base, - &display->image_surfaces, NULL, NULL, NULL); - surface->context.top_down = TRUE; - surface->context.canvas_draws_on_surface = TRUE; - return canvas; - default: - spice_error("invalid renderer type"); - }; - - return NULL; -} - -static void red_worker_create_surface_item(DisplayChannel *display, int surface_id) -{ - DisplayChannelClient *dcc; - RingItem *item, *next; - - FOREACH_DCC(display, item, next, dcc) { - dcc_create_surface(dcc, surface_id); - } -} - - -static void red_worker_push_surface_image(DisplayChannel *display, int surface_id) -{ - DisplayChannelClient *dcc; - RingItem *item, *next; - - FOREACH_DCC(display, item, next, dcc) { - dcc_push_surface_image(dcc, surface_id); - } -} - -static void red_create_surface(DisplayChannel *display, uint32_t surface_id, uint32_t width, - uint32_t height, int32_t stride, uint32_t format, - void *line_0, int data_is_valid, int send_client) -{ - RedSurface *surface = &display->surfaces[surface_id]; - uint32_t i; - - spice_warn_if(surface->context.canvas); - - surface->context.canvas_draws_on_surface = FALSE; - surface->context.width = width; - surface->context.height = height; - surface->context.format = format; - surface->context.stride = stride; - surface->context.line_0 = line_0; - if (!data_is_valid) { - char *data = line_0; - if (stride < 0) { - data -= abs(stride) * (height - 1); - } - memset(data, 0, height*abs(stride)); - } - surface->create.info = NULL; - surface->destroy.info = NULL; - ring_init(&surface->current); - ring_init(&surface->current_list); - ring_init(&surface->depend_on_me); - region_init(&surface->draw_dirty_region); - surface->refs = 1; - if (display->renderer != RED_RENDERER_INVALID) { - surface->context.canvas = create_canvas_for_surface(display, surface, display->renderer, - width, height, stride, - surface->context.format, line_0); - if (!surface->context.canvas) { - spice_critical("drawing canvas creating failed - can`t create same type canvas"); - } - - if (send_client) { - red_worker_create_surface_item(display, surface_id); - if (data_is_valid) { - red_worker_push_surface_image(display, surface_id); - } - } - return; - } - - for (i = 0; i < display->num_renderers; i++) { - surface->context.canvas = create_canvas_for_surface(display, surface, display->renderers[i], - width, height, stride, - surface->context.format, line_0); - if (surface->context.canvas) { //no need canvas check - display->renderer = display->renderers[i]; - if (send_client) { - red_worker_create_surface_item(display, surface_id); - if (data_is_valid) { - red_worker_push_surface_image(display, surface_id); - } - } - return; - } - } - - spice_critical("unable to create drawing canvas"); -} - static inline void flush_display_commands(RedWorker *worker) { RedChannel *display_red_channel = RED_CHANNEL(worker->display_channel); @@ -4081,8 +3970,8 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id, line_0 -= (int32_t)(surface.stride * (surface.height -1)); } - red_create_surface(display, 0, surface.width, surface.height, surface.stride, surface.format, - line_0, surface.flags & QXL_SURF_FLAG_KEEP_DATA, TRUE); + display_channel_create_surface(display, 0, surface.width, surface.height, surface.stride, surface.format, + line_0, surface.flags & QXL_SURF_FLAG_KEEP_DATA, TRUE); set_monitors_config_to_primary(display); if (display_is_connected(worker) && !worker->display_channel->common.during_target_migrate) { -- 2.4.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel