handle_dev_destroy_surface_wait: all clients render state handle_dev_destroy_surfaces: clear all surfaces handle_dev_destroy_primary_surface: clear all primary copies handle_dev_input RED_WORKER_MESSAGE_STOP: all clients red_worker_main: call red_handle_streams_timeout for all clients --- server/red_worker.c | 119 +++++++++++++++++++++++++++++++++++--------------- 1 files changed, 83 insertions(+), 36 deletions(-)
diff --git a/server/red_worker.c b/server/red_worker.c index 5295af5..aa77538 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -3629,7 +3629,12 @@ static inline void red_process_drawable_surfaces(RedRender *render, RedDrawable static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable, uint32_t group_id) { - red_process_drawable_surfaces(&worker->render, drawable, group_id); + RingItem *link; + RedRender *render; + + RENDER_FOREACH(link, render, worker) { + red_process_drawable_surfaces(render, drawable, group_id); + } } static inline void red_create_surface(RedRender *render, uint32_t surface_id, uint32_t width, @@ -4353,7 +4358,12 @@ static void red_render_update_area(RedRender *render, const SpiceRect *area, int static void red_update_area(RedWorker *worker, const SpiceRect *area, int surface_id) { - red_render_update_area(&worker->render, area, surface_id); + RedRender *render; + RingItem *link; + + RENDER_FOREACH(link, render, worker) { + red_render_update_area(render, area, surface_id); + } } #endif @@ -4632,25 +4642,41 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int * #define RED_RELEASE_BUNCH_SIZE 64 -static void red_free_some(RedWorker *worker) +static void red_free_some_helper(RedWorker *worker, int *n) { - int n = 0; - DisplayChannelClient *dcc = worker->render.dcc; - GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL; + RingItem *link; + RedRender *render; - if (glz_dict) { - // encoding using the dictionary is prevented since the following operations might - // change the dictionary - pthread_rwlock_wrlock(&glz_dict->encode_lock); - n = red_display_free_some_independent_glz_drawables(dcc); + RENDER_FOREACH(link, render, worker) { + while (!ring_is_empty(&render->current_list) && *n++ < RED_RELEASE_BUNCH_SIZE) { + free_one_drawable(render, TRUE); + } } +} - while (!ring_is_empty(&worker->render.current_list) && n++ < RED_RELEASE_BUNCH_SIZE) { - free_one_drawable(&worker->render, TRUE); - } +static void red_free_some(RedWorker *worker) +{ + int n = 0; + RingItem *link; + DisplayChannelClient *dcc; + GlzSharedDictionary *glz_dict; - if (glz_dict) { - pthread_rwlock_unlock(&glz_dict->encode_lock); + if (!worker->display_channel) { + red_free_some_helper(worker, &n); + return; + } + DCC_FOREACH(link, dcc, &worker->display_channel->common.base) { + glz_dict = dcc->glz_dict; + if (glz_dict) { + // encoding using the dictionary is prevented since the following operations might + // change the dictionary + pthread_rwlock_wrlock(&glz_dict->encode_lock); + n += red_display_free_some_independent_glz_drawables(dcc); + } + red_free_some_helper(worker, &n); + if (glz_dict) { + pthread_rwlock_unlock(&glz_dict->encode_lock); + } } } @@ -10101,15 +10127,19 @@ static inline void handle_dev_destroy_surface_wait(RedWorker *worker) { RedWorkerMessage message; uint32_t surface_id; + RingItem *link; + RedRender *render; receive_data(worker->channel, &surface_id, sizeof(uint32_t)); ASSERT(surface_id == 0); - + flush_all_qxl_commands(worker); - if (worker->render.surfaces[0].context.canvas) { - destroy_surface_wait(&worker->render, 0); + RENDER_FOREACH(link, render, worker) { + if (render->surfaces[0].context.canvas) { + destroy_surface_wait(render, 0); + } } message = RED_WORKER_MESSAGE_READY; @@ -10117,16 +10147,10 @@ static inline void handle_dev_destroy_surface_wait(RedWorker *worker) } /* called upon device reset */ - -/* TODO: split me*/ -static inline void handle_dev_destroy_surfaces(RedWorker *worker) +static inline void red_render_handle_dev_destroy_surfaces(RedRender *render) { - RedRender *render = &worker->render; int i; - RedWorkerMessage message; - red_printf(""); - flush_all_qxl_commands(worker); //to handle better for (i = 0; i < NUM_SURFACES; ++i) { if (render->surfaces[i].context.canvas) { @@ -10138,7 +10162,19 @@ static inline void handle_dev_destroy_surfaces(RedWorker *worker) } } ASSERT(ring_is_empty(&render->streams)); +} + +static inline void handle_dev_destroy_surfaces(RedWorker *worker) +{ + RedWorkerMessage message; + RingItem *link; + RedRender *render; + red_printf(""); + flush_all_qxl_commands(worker); + RENDER_FOREACH(link, render, worker) { + red_render_handle_dev_destroy_surfaces(render); + } if (cursor_is_connected(worker)) { red_wait_outgoing_items(&worker->cursor_channel->common.base); red_channel_pipes_add_type(&worker->cursor_channel->common.base, @@ -10212,7 +10248,8 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker) { RedWorkerMessage message; uint32_t surface_id; - RedRender *render = &worker->render; + RedRender *render; + RingItem *link; RedChannel *cursor_red_channel = &worker->cursor_channel->common.base; receive_data(worker->channel, &surface_id, sizeof(uint32_t)); @@ -10235,11 +10272,13 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker) } flush_all_qxl_commands(worker); - destroy_surface_wait(render, 0); - red_destroy_surface(render, 0); - ASSERT(ring_is_empty(&render->streams)); + RENDER_FOREACH(link, render, worker) { + destroy_surface_wait(render, 0); + red_destroy_surface(render, 0); + ASSERT(ring_is_empty(&render->streams)); + } - ASSERT(!render->surfaces[surface_id].context.canvas); + ASSERT(!worker->render.surfaces[surface_id].context.canvas); worker->cursor_visible = TRUE; worker->cursor_position.x = worker->cursor_position.y = 0; @@ -10256,6 +10295,8 @@ static void handle_dev_input(EventListener *listener, uint32_t events) RedChannel *cursor_red_channel = &worker->cursor_channel->common.base; RedChannel *display_red_channel = &worker->display_channel->common.base; int ring_is_empty; + RingItem *link; + RedRender *render; read_message(worker->channel, &message); @@ -10352,10 +10393,12 @@ static void handle_dev_input(EventListener *listener, uint32_t events) red_printf("stop"); ASSERT(worker->running); worker->running = FALSE; - red_display_client_clear_glz_drawables(worker->render.dcc); - for (x = 0; x < NUM_SURFACES; ++x) { - if (worker->render.surfaces[x].context.canvas) { - red_current_flush(&worker->render, x); + red_display_clear_glz_drawables(worker->display_channel); + RENDER_FOREACH(link, render, worker) { + for (x = 0; x < NUM_SURFACES; ++x) { + if (render->surfaces[x].context.canvas) { + red_current_flush(render, x); + } } } red_cursor_flush(worker); @@ -10597,6 +10640,8 @@ static void red_display_cc_free_glz_drawables(RedChannelClient *rcc) void *red_worker_main(void *arg) { RedWorker worker; + RedRender *render; + RingItem *link; red_printf("begin"); ASSERT(MAX_PIPE_SIZE > WIDE_CLIENT_ACK_WINDOW && @@ -10622,7 +10667,9 @@ void *red_worker_main(void *arg) worker.epoll_timeout = MIN(red_get_streams_timout(&worker.render), worker.epoll_timeout); num_events = epoll_wait(worker.epoll, events, MAX_EPOLL_SOURCES, worker.epoll_timeout); - red_handle_streams_timout(&worker.render); + RENDER_FOREACH(link, render, &worker) { + red_handle_streams_timout(render); + } if (worker.display_channel) { /* during migration, in the dest, the display channel can be initialized -- 1.7.5.1 _______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel