[Spice-devel] [PATCH 24/35] QXL: redesign.

Gerd Hoffmann kraxel at redhat.com
Wed May 12 04:32:18 PDT 2010


---
 server/red_dispatcher.c |   36 ++++++++++++++++++------------------
 server/red_dispatcher.h |    2 +-
 server/red_worker.c     |   38 +++++++++++++++++++-------------------
 server/red_worker.h     |    2 +-
 server/reds.c           |   20 +++++++++++---------
 server/reds.h           |    5 +++++
 server/spice.h          |    3 +--
 server/vd_interface.h   |   45 ++++++++++++++++++++++++++-------------------
 8 files changed, 82 insertions(+), 69 deletions(-)

diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index f7c6646..3d1d6f9 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -40,7 +40,7 @@ static int num_active_workers = 0;
 typedef struct RedDispatcher RedDispatcher;
 struct RedDispatcher {
     QXLWorker base;
-    QXLInterface *qxl_interface;
+    QXLInstance *qxl;
     int channel;
     pthread_t worker_thread;
     uint32_t pending;
@@ -387,7 +387,7 @@ void red_dispatcher_set_mm_time(uint32_t mm_time)
 {
     RedDispatcher *now = dispatchers;
     while (now) {
-        now->qxl_interface->set_mm_time(now->qxl_interface, mm_time);
+        now->qxl->st->qif->set_mm_time(now->qxl, mm_time);
         now = now->next;
     }
 }
@@ -409,7 +409,7 @@ void red_dispatcher_on_ic_change()
     RedDispatcher *now = dispatchers;
     while (now) {
         RedWorkeMessage message = RED_WORKER_MESSAGE_SET_COMPRESSION;
-        now->qxl_interface->set_compression_level(now->qxl_interface, compression_level);
+        now->qxl->st->qif->set_compression_level(now->qxl, compression_level);
         write_message(now->channel, &message);
         send_data(now->channel, &image_compression, sizeof(spice_image_compression_t));
         now = now->next;
@@ -422,7 +422,7 @@ void red_dispatcher_on_sv_change()
     RedDispatcher *now = dispatchers;
     while (now) {
         RedWorkeMessage message = RED_WORKER_MESSAGE_SET_STREAMING_VIDEO;
-        now->qxl_interface->set_compression_level(now->qxl_interface, compression_level);
+        now->qxl->st->qif->set_compression_level(now->qxl, compression_level);
         write_message(now->channel, &message);
         send_data(now->channel, &streaming_video, sizeof(uint32_t));
         now = now->next;
@@ -458,11 +458,11 @@ uint32_t red_dispatcher_qxl_ram_size()
     if (!dispatchers) {
         return 0;
     }
-    dispatchers->qxl_interface->get_init_info(dispatchers->qxl_interface, &qxl_info);
+    dispatchers->qxl->st->qif->get_init_info(dispatchers->qxl, &qxl_info);
     return qxl_info.qxl_ram_size;
 }
 
-RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
+RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
 {
     RedDispatcher *dispatcher;
     int channels[2];
@@ -475,9 +475,9 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
     sigset_t thread_sig_mask;
     sigset_t curr_sig_mask;
 
-    if (qxl_interface->pci_vendor != REDHAT_PCI_VENDOR_ID ||
-        qxl_interface->pci_id != QXL_DEVICE_ID ||
-        qxl_interface->pci_revision != QXL_REVISION) {
+    if (qxl->st->qif->pci_vendor != REDHAT_PCI_VENDOR_ID ||
+        qxl->st->qif->pci_id != QXL_DEVICE_ID ||
+        qxl->st->qif->pci_revision != QXL_REVISION) {
         red_printf("pci mismatch");
         return NULL;
     }
@@ -492,8 +492,8 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
 
     dispatcher = spice_new0(RedDispatcher, 1);
     dispatcher->channel = channels[0];
-    init_data.qxl_interface = dispatcher->qxl_interface = qxl_interface;
-    init_data.id = id;
+    init_data.qxl = dispatcher->qxl = qxl;
+    init_data.id = qxl->id;
     init_data.channel = channels[1];
     init_data.pending = &dispatcher->pending;
     init_data.num_renderers = num_renderers;
@@ -502,8 +502,8 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
     init_data.image_compression = image_compression;
     init_data.streaming_video = streaming_video;
 
-    dispatcher->base.major_version = VD_INTERFACE_QXL_MAJOR;
-    dispatcher->base.major_version = VD_INTERFACE_QXL_MINOR;
+    dispatcher->base.major_version = SPICE_INTERFACE_QXL_MAJOR;
+    dispatcher->base.minor_version = SPICE_INTERFACE_QXL_MINOR;
     dispatcher->base.wakeup = qxl_worker_wakeup;
     dispatcher->base.oom = qxl_worker_oom;
     dispatcher->base.save = qxl_worker_save;
@@ -522,7 +522,7 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
     dispatcher->base.reset_cursor = qxl_worker_reset_cursor;
     dispatcher->base.destroy_surface_wait = qxl_worker_destroy_surface_wait;
 
-    qxl_interface->get_init_info(qxl_interface, &init_info);
+    qxl->st->qif->get_init_info(qxl, &init_info);
 
     init_data.memslot_id_bits = init_info.memslot_id_bits;
     init_data.memslot_gen_bits = init_info.memslot_gen_bits;
@@ -548,7 +548,7 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
 
     reds_channel = spice_new0(Channel, 1);
     reds_channel->type = SPICE_CHANNEL_DISPLAY;
-    reds_channel->id = id;
+    reds_channel->id = qxl->id;
     reds_channel->link = red_dispatcher_set_peer;
     reds_channel->shutdown = red_dispatcher_shutdown_peer;
     reds_channel->migrate = red_dispatcher_migrate;
@@ -557,14 +557,14 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
 
     cursor_channel = spice_new0(Channel, 1);
     cursor_channel->type = SPICE_CHANNEL_CURSOR;
-    cursor_channel->id = id;
+    cursor_channel->id = qxl->id;
     cursor_channel->link = red_dispatcher_set_cursor_peer;
     cursor_channel->shutdown = red_dispatcher_shutdown_cursor_peer;
     cursor_channel->migrate = red_dispatcher_cursor_migrate;
     cursor_channel->data = dispatcher;
     reds_register_channel(cursor_channel);
-    qxl_interface->attache_worker(qxl_interface, &dispatcher->base);
-    qxl_interface->set_compression_level(qxl_interface, calc_compression_level());
+    qxl->st->qif->attache_worker(qxl, &dispatcher->base);
+    qxl->st->qif->set_compression_level(qxl, calc_compression_level());
 
     dispatcher->next = dispatchers;
     dispatchers = dispatcher;
diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h
index b0bc040..7f8973a 100644
--- a/server/red_dispatcher.h
+++ b/server/red_dispatcher.h
@@ -19,7 +19,7 @@
 #define _H_RED_DISPATCHER
 
 
-struct RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id);
+struct RedDispatcher *red_dispatcher_init(QXLInstance *qxl);
 
 void red_dispatcher_set_mm_time(uint32_t);
 void red_dispatcher_on_ic_change();
diff --git a/server/red_worker.c b/server/red_worker.c
index 59cca3d..54cb780 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -918,7 +918,7 @@ typedef struct RedWorker {
     EventListener dev_listener;
     DisplayChannel *display_channel;
     CursorChannel *cursor_channel;
-    QXLInterface *qxl;
+    QXLInstance *qxl;
     int id;
     int channel;
     int running;
@@ -1505,7 +1505,7 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
 
                 release_info_ext.group_id = surface->release_group_id;
                 release_info_ext.info = surface->release_info;
-                worker->qxl->release_resource(worker->qxl, release_info_ext);
+                worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
             }
 
             region_destroy(&surface->draw_dirty_region);
@@ -1539,7 +1539,7 @@ static inline void free_qxl_drawable(RedWorker *worker, QXLDrawable *drawable, u
     }
     release_info_ext.group_id = group_id;
     release_info_ext.info = &drawable->release_info;
-    worker->qxl->release_resource(worker->qxl, release_info_ext);
+    worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
 }
 
 static void remove_depended_item(DependItem *item)
@@ -3891,7 +3891,7 @@ static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface
                            height, stride, surface->u.surface_create.format, data);
         release_info_ext.group_id = group_id;
         release_info_ext.info = &surface->release_info;
-        worker->qxl->release_resource(worker->qxl, release_info_ext);
+        worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
         break;
     }
     case QXL_SURFACE_CMD_DESTROY:
@@ -4713,7 +4713,7 @@ static void red_release_cursor(RedWorker *worker, CursorItem *cursor)
         cursor_cmd = cursor->qxl_cursor;
         release_info_ext.group_id = cursor->group_id;
         release_info_ext.info = &cursor_cmd->release_info;
-        worker->qxl->release_resource(worker->qxl, release_info_ext);
+        worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
         free_cursor_item(worker, cursor);
     }
 }
@@ -4819,14 +4819,14 @@ static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size)
     int n = 0;
 
     while (!worker->cursor_channel || worker->cursor_channel->base.pipe_size <= max_pipe_size) {
-        if (!worker->qxl->get_cursor_command(worker->qxl, &ext_cmd)) {
+        if (!worker->qxl->st->qif->get_cursor_command(worker->qxl, &ext_cmd)) {
             if (worker->repoll_cursor_ring < CMD_RING_POLL_RETRIES) {
                 worker->repoll_cursor_ring++;
                 worker->epoll_timeout = MIN(worker->epoll_timeout, CMD_RING_POLL_TIMEOUT);
                 break;
             }
             if (worker->repoll_cursor_ring > CMD_RING_POLL_RETRIES ||
-                worker->qxl->req_cursor_notification(worker->qxl)) {
+                worker->qxl->st->qif->req_cursor_notification(worker->qxl)) {
                 worker->repoll_cursor_ring++;
                 break;
             }
@@ -4856,14 +4856,14 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
     uint64_t start = red_now();
 
     while (!worker->display_channel || worker->display_channel->base.pipe_size <= max_pipe_size) {
-        if (!worker->qxl->get_command(worker->qxl, &ext_cmd)) {
+        if (!worker->qxl->st->qif->get_command(worker->qxl, &ext_cmd)) {
             if (worker->repoll_cmd_ring < CMD_RING_POLL_RETRIES) {
                 worker->repoll_cmd_ring++;
                 worker->epoll_timeout = MIN(worker->epoll_timeout, CMD_RING_POLL_TIMEOUT);
                 break;
             }
             if (worker->repoll_cmd_ring > CMD_RING_POLL_RETRIES ||
-                         worker->qxl->req_cmd_notification(worker->qxl)) {
+                         worker->qxl->st->qif->req_cmd_notification(worker->qxl)) {
                 worker->repoll_cmd_ring++;
                 break;
             }
@@ -4887,10 +4887,10 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
             surface_id = draw_cmd->surface_id;
             validate_surface(worker, surface_id);
             red_update_area(worker, &draw_cmd->area, draw_cmd->surface_id);
-            worker->qxl->notify_update(worker->qxl, draw_cmd->update_id);
+            worker->qxl->st->qif->notify_update(worker->qxl, draw_cmd->update_id);
             release_info_ext.group_id = ext_cmd.group_id;
             release_info_ext.info = &draw_cmd->release_info;
-            worker->qxl->release_resource(worker->qxl, release_info_ext);
+            worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
             break;
         }
         case QXL_CMD_MESSAGE: {
@@ -4900,7 +4900,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
             red_printf("MESSAGE: %s", message->data);
             release_info_ext.group_id = ext_cmd.group_id;
             release_info_ext.info = &message->release_info;
-            worker->qxl->release_resource(worker->qxl, release_info_ext);
+            worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
             break;
         }
         case QXL_CMD_SURFACE: {
@@ -8081,7 +8081,7 @@ static inline void flush_display_commands(RedWorker *worker)
         uint64_t end_time;
 
         red_process_commands(worker, MAX_PIPE_SIZE);
-        if (!worker->qxl->has_command(worker->qxl)) {
+        if (!worker->qxl->st->qif->has_command(worker->qxl)) {
             break;
         }
 
@@ -8089,7 +8089,7 @@ static inline void flush_display_commands(RedWorker *worker)
             display_channel_push(worker);
         }
 
-        if (!worker->qxl->has_command(worker->qxl)) {
+        if (!worker->qxl->st->qif->has_command(worker->qxl)) {
             break;
         }
         end_time = red_now() + DISPLAY_CLIENT_TIMEOUT * 10;
@@ -8852,7 +8852,7 @@ static void red_save_cursor(RedWorker *worker)
     cursor_data->data_size = local->data_size;
     cursor_data->_cursor.header = local->red_cursor.header;
     memcpy(cursor_data->_cursor.data, local->red_cursor.data, local->data_size);
-    worker->qxl->set_save_data(worker->qxl, cursor_data, size);
+    worker->qxl->st->qif->set_save_data(worker->qxl, cursor_data, size);
 }
 
 static LocalCursor *_new_local_cursor(SpiceCursorHeader *header, int data_size, SpicePoint16 position)
@@ -8917,7 +8917,7 @@ static void red_cursor_flush(RedWorker *worker)
 static void red_save(RedWorker *worker)
 {
     if (!worker->cursor) {
-        worker->qxl->set_save_data(worker->qxl, NULL, 0);
+        worker->qxl->st->qif->set_save_data(worker->qxl, NULL, 0);
         return;
     }
     red_save_cursor(worker);
@@ -8925,7 +8925,7 @@ static void red_save(RedWorker *worker)
 
 static void red_cursor_load(RedWorker *worker)
 {
-    CursorData *cursor_data = worker->qxl->get_save_data(worker->qxl);
+    CursorData *cursor_data = worker->qxl->st->qif->get_save_data(worker->qxl);
     LocalCursor *local;
 
     if (!cursor_data) {
@@ -9211,7 +9211,7 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
         while (red_process_commands(worker, MAX_PIPE_SIZE)) {
             display_channel_push(worker);
         }
-        if (worker->qxl->flush_resources(worker->qxl) == 0) {
+        if (worker->qxl->st->qif->flush_resources(worker->qxl) == 0) {
             red_printf("oom current %u pipe %u", worker->current_size, worker->display_channel ?
                        worker->display_channel->base.pipe_size : 0);
             red_free_some(worker);
@@ -9420,7 +9420,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
     ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
 
     memset(worker, 0, sizeof(RedWorker));
-    worker->qxl = init_data->qxl_interface;
+    worker->qxl = init_data->qxl;
     worker->id = init_data->id;
     worker->channel = init_data->channel;
     worker->pending = init_data->pending;
diff --git a/server/red_worker.h b/server/red_worker.h
index 5807237..e53d518 100644
--- a/server/red_worker.h
+++ b/server/red_worker.h
@@ -83,7 +83,7 @@ enum {
 };
 
 typedef struct WorkerInitData {
-    struct QXLInterface *qxl_interface;
+    struct QXLInstance *qxl;
     int id;
     int channel;
     uint32_t *pending;
diff --git a/server/reds.c b/server/reds.c
index 5c34df7..62a2cab 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -4029,8 +4029,7 @@ static void attach_to_red_agent(VDIPortInterface *interface)
 }
 
 __visible__ int spice_server_add_interface(SpiceServer *s,
-                                           SpiceBaseInstance *sin,
-                                           int id)
+                                           SpiceBaseInstance *sin)
 {
     SpiceBaseInterface *interface = sin->sif;
 
@@ -4083,17 +4082,20 @@ __visible__ int spice_server_add_interface(SpiceServer *s,
             red_error("migration register failed");
         }
 
-    } else if (strcmp(interface->type, VD_INTERFACE_QXL) == 0) {
-        QXLInterface *qxl_interface;
+    } else if (strcmp(interface->type, SPICE_INTERFACE_QXL) == 0) {
+        QXLInstance *qxl;
 
-        red_printf("VD_INTERFACE_QXL");
-        if (interface->major_version != VD_INTERFACE_QXL_MAJOR ||
-            interface->minor_version < VD_INTERFACE_QXL_MINOR) {
+        red_printf("SPICE_INTERFACE_QXL");
+        if (interface->major_version != SPICE_INTERFACE_QXL_MAJOR ||
+            interface->minor_version < SPICE_INTERFACE_QXL_MINOR) {
             red_printf("unsuported qxl interface");
             return -1;
         }
-        qxl_interface = (QXLInterface *)interface;
-        red_dispatcher_init(qxl_interface, id);
+
+        qxl = SPICE_CONTAINEROF(sin, QXLInstance, base);
+        qxl->st = spice_new0(QXLState, 1);
+        qxl->st->qif = SPICE_CONTAINEROF(interface, QXLInterface, base);
+        qxl->st->dispatcher = red_dispatcher_init(qxl);
 
     } else if (strcmp(interface->type, VD_INTERFACE_TABLET) == 0) {
         red_printf("VD_INTERFACE_TABLET");
diff --git a/server/reds.h b/server/reds.h
index 68359ae..b3dcd4b 100644
--- a/server/reds.h
+++ b/server/reds.h
@@ -66,6 +66,11 @@ struct SpiceMouseState {
     int dummy;
 };
 
+struct QXLState {
+    QXLInterface          *qif;
+    struct RedDispatcher  *dispatcher;
+};
+
 void reds_desable_mm_timer();
 void reds_enable_mm_timer();
 void reds_update_mm_timer(uint32_t mm_time);
diff --git a/server/spice.h b/server/spice.h
index 8a7764e..f1bc80d 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -41,8 +41,7 @@ int spice_server_set_tls(SpiceServer *s, int port,
                          const char *dh_key_file, const char *ciphersuite);
 
 int spice_server_add_interface(SpiceServer *s,
-                               SpiceBaseInstance *sin,
-                               int id);
+                               SpiceBaseInstance *sin);
 int spice_server_remove_interface(SpiceBaseInstance *sin);
 int spice_server_kbd_leds(SpiceKbdInstance *sin, int leds);
 
diff --git a/server/vd_interface.h b/server/vd_interface.h
index 1567b12..bbe8436 100644
--- a/server/vd_interface.h
+++ b/server/vd_interface.h
@@ -84,11 +84,12 @@ struct SpiceCoreInterface {
 
 };
 
-#define VD_INTERFACE_QXL "qxl"
-#define VD_INTERFACE_QXL_MAJOR 3
-#define VD_INTERFACE_QXL_MINOR 0
+#define SPICE_INTERFACE_QXL "qxl"
+#define SPICE_INTERFACE_QXL_MAJOR 3
+#define SPICE_INTERFACE_QXL_MINOR 0
 typedef struct QXLInterface QXLInterface;
-typedef void (*qxl_mode_change_notifier_t)(void *opaque);
+typedef struct QXLInstance QXLInstance;
+typedef struct QXLState QXLState;
 typedef struct QXLWorker QXLWorker;
 typedef struct QXLDevMemSlot QXLDevMemSlot;
 typedef struct QXLDevSurfaceCreate QXLDevSurfaceCreate;
@@ -183,21 +184,27 @@ struct QXLInterface {
     uint16_t pci_id;
     uint8_t pci_revision;
 
-    void (*attache_worker)(QXLInterface *qxl, QXLWorker *qxl_worker);
-    void (*set_compression_level)(QXLInterface *qxl, int level);
-    void (*set_mm_time)(QXLInterface *qxl, uint32_t mm_time);
-
-    void (*get_init_info)(QXLInterface *qxl, QXLDevInitInfo *info);
-    int (*get_command)(QXLInterface *qxl, struct QXLCommandExt *cmd);
-    int (*req_cmd_notification)(QXLInterface *qxl);
-    int (*has_command)(QXLInterface *qxl);
-    void (*release_resource)(QXLInterface *qxl, struct QXLReleaseInfoExt release_info);
-    int (*get_cursor_command)(QXLInterface *qxl, struct QXLCommandExt *cmd);
-    int (*req_cursor_notification)(QXLInterface *qxl);
-    void (*notify_update)(QXLInterface *qxl, uint32_t update_id);
-    void (*set_save_data)(QXLInterface *qxl, void *data, int size);
-    void *(*get_save_data)(QXLInterface *qxl);
-    int (*flush_resources)(QXLInterface *qxl);
+    void (*attache_worker)(QXLInstance *qin, QXLWorker *qxl_worker);
+    void (*set_compression_level)(QXLInstance *qin, int level);
+    void (*set_mm_time)(QXLInstance *qin, uint32_t mm_time);
+
+    void (*get_init_info)(QXLInstance *qin, QXLDevInitInfo *info);
+    int (*get_command)(QXLInstance *qin, struct QXLCommandExt *cmd);
+    int (*req_cmd_notification)(QXLInstance *qin);
+    int (*has_command)(QXLInstance *qin);
+    void (*release_resource)(QXLInstance *qin, struct QXLReleaseInfoExt release_info);
+    int (*get_cursor_command)(QXLInstance *qin, struct QXLCommandExt *cmd);
+    int (*req_cursor_notification)(QXLInstance *qin);
+    void (*notify_update)(QXLInstance *qin, uint32_t update_id);
+    void (*set_save_data)(QXLInstance *qin, void *data, int size);
+    void *(*get_save_data)(QXLInstance *qin);
+    int (*flush_resources)(QXLInstance *qin);
+};
+
+struct QXLInstance {
+    SpiceBaseInstance  base;
+    int                id;
+    QXLState           *st;
 };
 
 #define SPICE_INTERFACE_KEYBOARD "keyboard"
-- 
1.6.6.1



More information about the Spice-devel mailing list