[Spice-devel] [PATCH 3/8] Make virt mapping an interface

alexl at redhat.com alexl at redhat.com
Mon Mar 8 09:33:54 PST 2010


From: Alexander Larsson <alexl at redhat.com>

---
 common/cairo_canvas.c |    9 ++-------
 common/cairo_canvas.h |    3 +--
 common/canvas_base.c  |   21 +++++++--------------
 common/canvas_base.h  |   15 ++++++++++-----
 common/gl_canvas.c    |    9 ++-------
 common/gl_canvas.h    |    3 +--
 server/red_worker.c   |   29 ++++++++++++++++++-----------
 7 files changed, 41 insertions(+), 48 deletions(-)

diff --git a/common/cairo_canvas.c b/common/cairo_canvas.c
index a3211de..8dcb12d 100644
--- a/common/cairo_canvas.c
+++ b/common/cairo_canvas.c
@@ -2157,8 +2157,7 @@ CairoCanvas *canvas_create(pixman_image_t *image, int bits
 #endif
                             , SpiceGlzDecoder *glz_decoder
 #ifndef CAIRO_CANVAS_NO_CHUNKS
-                           , void *get_virt_opaque, get_virt_fn_t get_virt,
-                           void *validate_virt_opaque, validate_virt_fn_t validate_virt
+                           , SpiceVirtMapping *virt_mapping
 #endif
                            )
 {
@@ -2181,11 +2180,7 @@ CairoCanvas *canvas_create(pixman_image_t *image, int bits
 #endif
                                , glz_decoder
 #ifndef CAIRO_CANVAS_NO_CHUNKS
-                               ,
-                               get_virt_opaque,
-                               get_virt,
-                               validate_virt_opaque,
-                               validate_virt
+                               , virt_mapping
 #endif
                                );
     canvas->private_data = NULL;
diff --git a/common/cairo_canvas.h b/common/cairo_canvas.h
index 3800903..c0102ae 100644
--- a/common/cairo_canvas.h
+++ b/common/cairo_canvas.h
@@ -71,8 +71,7 @@ CairoCanvas *canvas_create(pixman_image_t *image, int bits
 #endif
                            , SpiceGlzDecoder *glz_decoder
 #ifndef CAIRO_CANVAS_NO_CHUNKS
-                           , void *get_virt_opaque, get_virt_fn_t get_virt,
-                           void *validate_virt_opaque, validate_virt_fn_t validate_virt
+                           , SpiceVirtMapping *virt_mapping
 #endif
                            );
 void canvas_destroy(CairoCanvas *canvas);
diff --git a/common/canvas_base.c b/common/canvas_base.c
index aeb1cb5..01945ec 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -164,10 +164,7 @@ typedef struct QuicData {
     jmp_buf jmp_env;
 #ifndef CAIRO_CANVAS_NO_CHUNKS
     SPICE_ADDRESS next;
-    get_virt_fn_t get_virt;
-    void *get_virt_opaque;
-    validate_virt_fn_t validate_virt;
-    void *validate_virt_opaque;
+    SpiceVirtMapping *virt_mapping;
 #endif
     char message_buf[512];
 } QuicData;
@@ -1506,11 +1503,11 @@ static int quic_usr_more_space(QuicUsrContext *usr, uint32_t **io_ptr, int rows_
     if (!quic_data->next) {
         return 0;
     }
-    chunk = (DataChunk *)quic_data->get_virt(quic_data->get_virt_opaque, quic_data->next,
-                                             sizeof(DataChunk));
+    chunk = (DataChunk *)quic_data->virt_mapping->ops->get_virt(quic_data->virt_mapping, quic_data->next,
+                                                                sizeof(DataChunk));
     size = chunk->size;
-    quic_data->validate_virt(quic_data->validate_virt_opaque, (unsigned long)chunk->data,
-                             quic_data->next, size);
+    quic_data->virt_mapping->ops->validate_virt(quic_data->virt_mapping, (unsigned long)chunk->data,
+                                                quic_data->next, size);
 
     quic_data->next = chunk->next;
     *io_ptr = (uint32_t *)chunk->data;
@@ -1555,8 +1552,7 @@ static int canvas_base_init(CanvasBase *canvas, int depth
 #endif
                             , SpiceGlzDecoder *glz_decoder
 #ifndef CAIRO_CANVAS_NO_CHUNKS
-                           , void *get_virt_opaque, get_virt_fn_t get_virt,
-                           void *validate_virt_opaque, validate_virt_fn_t validate_virt
+                            , SpiceVirtMapping *virt_mapping
 #endif
                             )
 {
@@ -1568,10 +1564,7 @@ static int canvas_base_init(CanvasBase *canvas, int depth
     canvas->quic_data.usr.more_space = quic_usr_more_space;
     canvas->quic_data.usr.more_lines = quic_usr_more_lines;
 #ifndef CAIRO_CANVAS_NO_CHUNKS
-    canvas->quic_data.get_virt_opaque = get_virt_opaque;
-    canvas->quic_data.get_virt = get_virt;
-    canvas->quic_data.validate_virt_opaque = validate_virt_opaque;
-    canvas->quic_data.validate_virt = validate_virt;
+    canvas->quic_data.virt_mapping = virt_mapping;
 #endif
     if (!(canvas->quic_data.quic = quic_create(&canvas->quic_data.usr))) {
             return 0;
diff --git a/common/canvas_base.h b/common/canvas_base.h
index 7796245..4c28654 100644
--- a/common/canvas_base.h
+++ b/common/canvas_base.h
@@ -27,6 +27,7 @@
 typedef struct _SpiceImageCache SpiceImageCache;
 typedef struct _SpicePaletteCache SpicePaletteCache;
 typedef struct _SpiceGlzDecoder SpiceGlzDecoder;
+typedef struct _SpiceVirtMapping SpiceVirtMapping;
 
 typedef struct {
     void (*put)(SpiceImageCache *cache,
@@ -64,11 +65,15 @@ struct _SpiceGlzDecoder {
   SpiceGlzDecoderOps *ops;
 };
 
-#ifndef CAIRO_CANVAS_NO_CHUNKS
-typedef void *(*get_virt_fn_t)(void *get_virt_opaque, unsigned long addr, uint32_t add_size);
-typedef void (*validate_virt_fn_t)(void *validate_virt_opaque, unsigned long virt,
-                                   unsigned long from_addr, uint32_t add_size);
-#endif
+typedef struct {
+    void *(*get_virt)(SpiceVirtMapping *mapping, unsigned long addr, uint32_t add_size);
+    void (*validate_virt)(SpiceVirtMapping *mapping, unsigned long virt,
+                          unsigned long from_addr, uint32_t add_size);
+} SpiceVirtMappingOps;
+
+struct _SpiceVirtMapping {
+  SpiceVirtMappingOps *ops;
+};
 
 #endif
 
diff --git a/common/gl_canvas.c b/common/gl_canvas.c
index f173194..e7a7bff 100644
--- a/common/gl_canvas.c
+++ b/common/gl_canvas.c
@@ -813,8 +813,7 @@ GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
 #endif
                            , SpiceGlzDecoder *glz_decoder
 #ifndef CAIRO_CANVAS_NO_CHUNKS
-                           , void *get_virt_opaque, get_virt_fn_t get_virt,
-                           void *validate_virt_opaque, validate_virt_fn_t validate_virt
+                           , SpiceVirtMapping *virt_mapping
 #endif
                            )
 {
@@ -843,11 +842,7 @@ GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
 #endif
                                , glz_decoder
 #ifndef CAIRO_CANVAS_NO_CHUNKS
-                               ,
-                               get_virt_opaque,
-                               get_virt,
-                               validate_virt_opaque,
-                               validate_virt
+                               , virt_mapping
 #endif
                                );
     if (!init_ok) {
diff --git a/common/gl_canvas.h b/common/gl_canvas.h
index ec0cbdb..ee272a8 100644
--- a/common/gl_canvas.h
+++ b/common/gl_canvas.h
@@ -66,8 +66,7 @@ GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
 #endif
                            , SpiceGlzDecoder *glz_decoder
 #ifndef CAIRO_CANVAS_NO_CHUNKS
-                           , void *get_virt_opaque, get_virt_fn_t get_virt,
-                           void *validate_virt_opaque, validate_virt_fn_t validate_virt
+                            , SpiceVirtMapping *virt_mapping
 #endif
                            );
 void gl_canvas_destroy(GLCanvas *, int);
diff --git a/server/red_worker.c b/server/red_worker.c
index 52d8451..6eaf391 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1007,6 +1007,7 @@ typedef struct RedWorker {
     uint64_t *wakeup_counter;
     uint64_t *command_counter;
 #endif
+    SpiceVirtMapping preload_group_virt_mapping;
 } RedWorker;
 
 pthread_mutex_t avcodec_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -1217,18 +1218,20 @@ static void cb_validate_virt(void *opaque, unsigned long virt, unsigned long fro
     validate_virt((RedWorker *)opaque, virt, slot_id, add_size, group_id);
 }
 
-static void *cb_get_virt_preload_group(void *opaque, unsigned long addr, uint32_t add_size)
+static void *op_get_virt_preload_group(SpiceVirtMapping *mapping, unsigned long addr, uint32_t add_size)
 {
-    return (void *)get_virt((RedWorker *)opaque, addr, add_size,
-                            ((RedWorker *)opaque)->preload_group_id);
+    RedWorker *worker = CONTAINEROF(mapping, RedWorker, preload_group_virt_mapping);
+    return (void *)get_virt(worker, addr, add_size,
+                            worker->preload_group_id);
 }
 
-static void cb_validate_virt_preload_group(void *opaque, unsigned long virt,
+static void op_validate_virt_preload_group(SpiceVirtMapping *mapping, unsigned long virt,
                                            unsigned long from_addr, uint32_t add_size)
 {
-    int slot_id = get_memslot_id((RedWorker *)opaque, from_addr);
-    validate_virt((RedWorker *)opaque, virt, slot_id, add_size,
-                  ((RedWorker *)opaque)->preload_group_id);
+    RedWorker *worker = CONTAINEROF(mapping, RedWorker, preload_group_virt_mapping);
+    int slot_id = get_memslot_id(worker, from_addr);
+    validate_virt(worker, virt, slot_id, add_size,
+                  worker->preload_group_id);
 }
 
 char *draw_type_to_str(uint8_t type)
@@ -7491,8 +7494,7 @@ static CairoCanvas *create_cairo_context(RedWorker *worker, uint32_t width, uint
         red_error("create cairo surface failed");
     }
     canvas = canvas_create(surface, depth, &worker->image_cache.base, NULL,
-                           worker, cb_get_virt_preload_group, worker,
-                           cb_validate_virt_preload_group);
+                           &worker->preload_group_virt_mapping);
     pixman_image_unref (surface);
     return canvas;
 }
@@ -7555,8 +7557,7 @@ static GLCanvas *create_ogl_context_common(RedWorker *worker, OGLCtx *ctx, uint3
 
     oglctx_make_current(ctx);
     if (!(canvas = gl_canvas_create(ctx, width, height, depth, &worker->image_cache.base, NULL,
-                                    worker, cb_get_virt_preload_group,
-                                    worker, cb_validate_virt_preload_group))) {
+                                    &worker->preload_group_virt_mapping))) {
         return NULL;
     }
 
@@ -9028,6 +9029,10 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
     struct epoll_event event;
     RedWorkeMessage message;
     int epoll;
+    static SpiceVirtMappingOps preload_group_virt_mapping_ops = {
+        op_get_virt_preload_group,
+        op_validate_virt_preload_group
+    };
 
     ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
 
@@ -9081,6 +9086,8 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
     worker->internal_groupslot_id = init_data->internal_groupslot_id;
     red_create_mem_slots(worker);
 
+    worker->preload_group_virt_mapping.ops = &preload_group_virt_mapping_ops;
+
     message = RED_WORKER_MESSAGE_READY;
     write_message(worker->channel, &message);
 }
-- 
1.6.6



More information about the Spice-devel mailing list