[Spice-devel] [PATCH 14/18] worker: move display_channel_create_surface
Frediano Ziglio
fziglio at redhat.com
Wed Nov 25 01:37:19 PST 2015
>
> From: Marc-André Lureau <marcandre.lureau at gmail.com>
>
> ---
> 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 at redhat.com>
Frediano
More information about the Spice-devel
mailing list