> > 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) { Acked-by: Frediano Ziglio <fziglio@xxxxxxxxxx> Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel