[Spice-devel] [RFCv5 32/47] server/red_worker: start using RENDER_FOREACH
Alon Levy
alevy at redhat.com
Sun May 8 06:11:28 PDT 2011
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
More information about the Spice-devel
mailing list