[Spice-devel] [RFCv5 26/47] server/red_worker: remove more direct access to RedChannelClient.rcc

Alon Levy alevy at redhat.com
Sun May 8 06:11:22 PDT 2011


---
 server/red_worker.c |   99 +++++++++++++++++++++++++++++---------------------
 1 files changed, 57 insertions(+), 42 deletions(-)

diff --git a/server/red_worker.c b/server/red_worker.c
index 3fbc7d1..c2e1623 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1194,7 +1194,7 @@ static void red_pipe_add_verb(RedChannelClient* rcc, uint16_t verb)
 }
 
 static inline void red_create_surface_item(DisplayChannelClient *dcc, int surface_id);
-static void red_add_surface_image(RedWorker *worker, int surface_id);
+static void red_push_surface_image(DisplayChannelClient *dcc, int surface_id);
 static void red_pipes_add_verb(RedChannel *channel, uint16_t verb)
 {
     RedChannelClient *rcc = channel->rcc;
@@ -1230,7 +1230,7 @@ static inline void red_handle_drawable_surfaces_client_synced(
             }
             red_create_surface_item(dcc, surface_id);
             red_current_flush(&worker->render, surface_id);
-            red_add_surface_image(worker, surface_id);
+            red_push_surface_image(dcc, surface_id);
         }
     }
 
@@ -1240,7 +1240,7 @@ static inline void red_handle_drawable_surfaces_client_synced(
 
     red_create_surface_item(dcc, drawable->surface_id);
     red_current_flush(&worker->render, drawable->surface_id);
-    red_add_surface_image(worker, drawable->surface_id);
+    red_push_surface_image(dcc, drawable->surface_id);
 }
 
 static int display_is_connected(RedWorker *worker)
@@ -1310,23 +1310,23 @@ static inline void red_pipe_remove_drawable(DisplayChannelClient *dcc, Drawable
     }
 }
 
-static inline void red_pipe_add_image_item(RedWorker *worker, ImageItem *item)
+static inline void red_pipe_add_image_item(DisplayChannelClient *dcc, ImageItem *item)
 {
-    if (!display_is_connected(worker)) {
+    if (!dcc) {
         return;
     }
     item->refs++;
-    red_channel_client_pipe_add(worker->display_channel->common.base.rcc, &item->link);
+    red_channel_client_pipe_add(&dcc->common.base, &item->link);
 }
 
-static inline void red_pipe_add_image_item_after(RedWorker *worker, ImageItem *item,
+static inline void red_pipe_add_image_item_after(DisplayChannelClient *dcc, ImageItem *item,
                                                  PipeItem *pos)
 {
-    if (!display_is_connected(worker)) {
+    if (!dcc) {
         return;
     }
     item->refs++;
-    red_channel_client_pipe_add_after(worker->display_channel->common.base.rcc, &item->link, pos);
+    red_channel_client_pipe_add_after(&dcc->common.base, &item->link, pos);
 }
 
 static void release_image_item(ImageItem *item)
@@ -2655,27 +2655,23 @@ static void reset_rate(DisplayChannelClient *dcc, StreamAgent *stream_agent)
     /* MJpeg has no rate limiting anyway, so do nothing */
 }
 
-static int display_channel_is_low_bandwidth(DisplayChannel *display_channel)
+static int display_channel_is_low_bandwidth(DisplayChannelClient *dcc)
 {
-    if (display_channel->common.base.rcc) {
-        if (main_channel_client_is_low_bandwidth(
-                red_client_get_main(display_channel->common.base.rcc->client))) {
-            return TRUE;
-        }
-    }
-    return FALSE;
+    RedChannelClient *rcc = &dcc->common.base;
+
+    return dcc && main_channel_client_is_low_bandwidth(
+                red_client_get_main(red_channel_client_get_client(rcc)));
 }
 
 static inline void pre_stream_item_swap(RedRender *render, Stream *stream)
 {
-    RedWorker *worker = render->worker;
     DisplayChannelClient *dcc = render->dcc;
     int index;
     StreamAgent *agent;
 
     ASSERT(stream->current);
 
-    if (!dcc || !display_channel_is_low_bandwidth(worker->display_channel)) {
+    if (!dcc || !display_channel_is_low_bandwidth(dcc)) {
         return;
     }
 
@@ -4286,6 +4282,14 @@ static CursorItem *get_cursor_item(RedWorker *worker, RedCursorCmd *cmd, uint32_
     return cursor_item;
 }
 
+static PipeItem *ref_cursor_pipe_item(RedChannelClient *rcc, void *data, int num)
+{
+    CursorItem *cursor_item = data;
+
+    cursor_item->refs += (num != 0); /* we already reference the first use */
+    return &cursor_item->pipe_data;
+}
+
 static void qxl_process_cursor(RedWorker *worker, RedCursorCmd *cursor_cmd, uint32_t group_id)
 {
     CursorItem *item;
@@ -4320,9 +4324,10 @@ static void qxl_process_cursor(RedWorker *worker, RedCursorCmd *cursor_cmd, uint
         red_error("invalid cursor command %u", cursor_cmd->type);
     }
 
-    if (worker->cursor_channel && (worker->mouse_mode == SPICE_MOUSE_MODE_SERVER ||
+    if (cursor_is_connected(worker) && (worker->mouse_mode == SPICE_MOUSE_MODE_SERVER ||
                                    cursor_cmd->type != QXL_CURSOR_MOVE || cursor_show)) {
-        red_channel_client_pipe_add(worker->cursor_channel->common.base.rcc, &item->pipe_data);
+        red_channel_pipes_new_add(&worker->cursor_channel->common.base, ref_cursor_pipe_item,
+                                  (void*)item);
     } else {
         red_release_cursor(worker, item);
     }
@@ -4497,29 +4502,35 @@ static void red_current_flush(RedRender *render, int surface_id)
 }
 
 // adding the pipe item after pos. If pos == NULL, adding to head.
-static ImageItem *red_add_surface_area_image(RedWorker *worker, int surface_id, SpiceRect *area,
+static ImageItem *red_add_surface_area_image(RedRender *render, int surface_id, SpiceRect *area,
                                              PipeItem *pos, int can_lossy)
 {
+    DisplayChannelClient *dcc = render->dcc;
+    RedWorker *worker = dcc ? DCC_TO_WORKER(dcc) : NULL;
+    DisplayChannel *display_channel = worker ? worker->display_channel : NULL;
+    RedChannel *channel = &display_channel->common.base;
+    RedSurface *surface = &render->surfaces[surface_id];
+    SpiceCanvas *canvas = surface->context.canvas;
     ImageItem *item;
     int stride;
     int width;
     int height;
-    RedSurface *surface = &worker->render.surfaces[surface_id];
-    SpiceCanvas *canvas = surface->context.canvas;
     int bpp;
     int all_set;
 
     ASSERT(area);
 
+    if (!dcc) {
+        return NULL;
+    }
     width = area->right - area->left;
     height = area->bottom - area->top;
     bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
-    stride = SPICE_ALIGN(width * bpp, 4); 
-                                      
+    stride = SPICE_ALIGN(width * bpp, 4);
+
     item = (ImageItem *)spice_malloc_n_m(height, stride, sizeof(ImageItem));
 
-    red_channel_pipe_item_init(&worker->display_channel->common.base,
-                               &item->link, PIPE_ITEM_TYPE_IMAGE);
+    red_channel_pipe_item_init(channel, &item->link, PIPE_ITEM_TYPE_IMAGE);
 
     item->refs = 1;
     item->surface_id = surface_id;
@@ -4549,9 +4560,9 @@ static ImageItem *red_add_surface_area_image(RedWorker *worker, int surface_id,
     }
 
     if (!pos) {
-        red_pipe_add_image_item(worker, item);
+        red_pipe_add_image_item(dcc, item);
     } else {
-        red_pipe_add_image_item_after(worker, item, pos);
+        red_pipe_add_image_item_after(dcc, item, pos);
     }
 
     release_image_item(item);
@@ -4559,25 +4570,28 @@ static ImageItem *red_add_surface_area_image(RedWorker *worker, int surface_id,
     return item;
 }
 
-static void red_add_surface_image(RedWorker *worker, int surface_id)
+static void red_push_surface_image(DisplayChannelClient *dcc, int surface_id)
 {
     SpiceRect area;
     RedSurface *surface;
+    RedRender *render;
 
-    surface = &worker->render.surfaces[surface_id];
-
-    if (!display_is_connected(worker) || !surface->context.canvas) {
+    if (!dcc) {
+        return;
+    }
+    render = dcc->common.render;
+    surface = &render->surfaces[surface_id];
+    if (!surface->context.canvas) {
         return;
     }
-
     area.top = area.left = 0;
     area.right = surface->context.width;
     area.bottom = surface->context.height;
 
     /* not allowing lossy compression because probably, especially if it is a primary surface,
        it combines both "picture-like" areas with areas that are more "artificial"*/
-    red_add_surface_area_image(worker, surface_id, &area, NULL, FALSE);
-    red_channel_push(&worker->display_channel->common.base);
+    red_add_surface_area_image(render, surface_id, &area, NULL, FALSE);
+    red_channel_client_push(&dcc->common.base);
 }
 
 typedef struct {
@@ -6376,8 +6390,10 @@ static void red_pipe_replace_rendered_drawables_with_images(RedWorker *worker,
                                                             int first_surface_id,
                                                             SpiceRect *first_area)
 {
+    /* TODO: can't have those statics with multiple clients */
     static int resent_surface_ids[MAX_PIPE_SIZE];
     static SpiceRect resent_areas[MAX_PIPE_SIZE]; // not pointers since drawbales may be released
+    RedRender *render = dcc->common.render;
     int num_resent;
     PipeItem *pipe_item;
     Ring *pipe;
@@ -6411,7 +6427,7 @@ static void red_pipe_replace_rendered_drawables_with_images(RedWorker *worker,
             continue;
         }
 
-        image = red_add_surface_area_image(worker, drawable->red_drawable->surface_id,
+        image = red_add_surface_area_image(render, drawable->red_drawable->surface_id,
                                            &drawable->red_drawable->bbox, pipe_item, TRUE);
         resent_surface_ids[num_resent] = drawable->red_drawable->surface_id;
         resent_areas[num_resent] = drawable->red_drawable->bbox;
@@ -6468,7 +6484,7 @@ static void red_add_lossless_drawable_dependencies(RedWorker *worker,
         // the surfaces areas will be sent as DRAW_COPY commands, that
         // will be executed before the current drawable
         for (i = 0; i < num_deps; i++) {
-            red_add_surface_area_image(worker, deps_surfaces_ids[i], deps_areas[i],
+            red_add_surface_area_image(render, deps_surfaces_ids[i], deps_areas[i],
                                        red_pipe_get_tail(dcc), FALSE);
 
         }
@@ -6489,7 +6505,7 @@ static void red_add_lossless_drawable_dependencies(RedWorker *worker,
                                                             &drawable->bbox);
         }
 
-        red_add_surface_area_image(worker, drawable->surface_id, &drawable->bbox,
+        red_add_surface_area_image(render, drawable->surface_id, &drawable->bbox,
                                    red_pipe_get_tail(dcc), TRUE);
     }
 }
@@ -8824,7 +8840,6 @@ static int display_channel_wait_for_init(DisplayChannelClient *dcc)
 static void on_new_display_channel_client(DisplayChannelClient *dcc)
 {
     DisplayChannel *display_channel = DCC_TO_DC(dcc);
-    RedWorker *worker = display_channel->common.worker;
     RedRender *render = dcc->common.render;
     RedChannelClient *rcc = &dcc->common.base;
 
@@ -8842,7 +8857,7 @@ static void on_new_display_channel_client(DisplayChannelClient *dcc)
     if (render->surfaces[0].context.canvas) {
         red_current_flush(render, 0);
         push_new_primary_surface(dcc);
-        red_add_surface_image(worker, 0);
+        red_push_surface_image(dcc, 0);
         if (red_channel_is_connected(&display_channel->common.base)) {
             red_pipe_add_verb(rcc, SPICE_MSG_DISPLAY_MARK);
             red_disply_start_streams(dcc);
-- 
1.7.5.1



More information about the Spice-devel mailing list