[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