worker: move display_channel_create_surface

Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
Marc-André Lureau 2013-09-27 19:10:03 +02:00 committed by Frediano Ziglio
parent fd9c97a833
commit 4e35645fb0
3 changed files with 103 additions and 118 deletions

View File

@ -1525,6 +1525,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;

View File

@ -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);

View File

@ -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;
}
@ -3416,114 +3413,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);
@ -4043,8 +3932,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) {