[Spice-devel] [PATCH 4/5] make RedsState private in red-qxl.c

Frediano Ziglio fziglio at redhat.com
Mon Feb 29 11:26:21 UTC 2016


Considering that:
- RedsState is the state of QXLInstance implementation (RedQXL);
- qif (QXLInterface*) field can be computed really easy from QXLInstance;
- mostly of its state is private.
Make all structure private.

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 server/cursor-channel.c  |   2 +-
 server/dcc-send.c        |  17 +++---
 server/dcc.c             |   4 +-
 server/display-channel.c |   8 ++-
 server/red-qxl.c         | 135 +++++++++++++++++++++++++++++------------------
 server/red-qxl.h         |   5 +-
 server/red-worker.c      |  41 +++++++-------
 server/reds.c            |  12 ++---
 server/reds.h            |  11 ++--
 9 files changed, 130 insertions(+), 105 deletions(-)

diff --git a/server/cursor-channel.c b/server/cursor-channel.c
index 3e3c7a7..9dd93f6 100644
--- a/server/cursor-channel.c
+++ b/server/cursor-channel.c
@@ -115,7 +115,7 @@ static void cursor_item_unref(CursorItem *item)
         return;
 
     cursor_cmd = item->red_cursor;
-    item->qxl->st->qif->release_resource(item->qxl, cursor_cmd->release_info_ext);
+    qxl_if(item->qxl)->release_resource(item->qxl, cursor_cmd->release_info_ext);
     red_put_cursor_cmd(cursor_cmd);
     free(cursor_cmd);
 
diff --git a/server/dcc-send.c b/server/dcc-send.c
index 4180cc1..16c5098 100644
--- a/server/dcc-send.c
+++ b/server/dcc-send.c
@@ -2306,18 +2306,13 @@ static void marshall_gl_scanout(RedChannelClient *rcc,
     DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
     DisplayChannel *display_channel = DCC_TO_DC(dcc);
     QXLInstance* qxl = display_channel->common.qxl;
-    SpiceMsgDisplayGlScanoutUnix *so = &qxl->st->scanout;
 
-    pthread_mutex_lock(&qxl->st->scanout_mutex);
-
-    if (so->drm_dma_buf_fd == -1)
-        goto end;
-
-    red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_GL_SCANOUT_UNIX, NULL);
-    spice_marshall_msg_display_gl_scanout_unix(m, so);
-
-end:
-    pthread_mutex_unlock(&qxl->st->scanout_mutex);
+    SpiceMsgDisplayGlScanoutUnix *so = red_qxl_get_gl_scanout(qxl->st);
+    if (so != NULL) {
+        red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_GL_SCANOUT_UNIX, NULL);
+        spice_marshall_msg_display_gl_scanout_unix(m, so);
+    }
+    red_qxl_put_gl_scanout(qxl->st, so);
 }
 
 static void marshall_gl_draw(RedChannelClient *rcc,
diff --git a/server/dcc.c b/server/dcc.c
index 74514db..70a9b99 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -467,7 +467,8 @@ void dcc_start(DisplayChannelClient *dcc)
         dcc_create_all_streams(dcc);
     }
 
-    if (qxl->st->scanout.drm_dma_buf_fd >= 0) {
+    SpiceMsgDisplayGlScanoutUnix *scanout = red_qxl_get_gl_scanout(qxl->st);
+    if (scanout) {
         if (reds_stream_is_plain_unix(rcc->stream) &&
             red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_GL_SCANOUT)) {
             red_channel_client_pipe_add(rcc, dcc_gl_scanout_item_new(rcc, NULL, 0));
@@ -476,6 +477,7 @@ void dcc_start(DisplayChannelClient *dcc)
             spice_printerr("FIXME: GL not supported on this kind of connection");
         }
     }
+    red_qxl_put_gl_scanout(qxl->st, scanout);
 }
 
 static void dcc_destroy_stream_agents(DisplayChannelClient *dcc)
diff --git a/server/display-channel.c b/server/display-channel.c
index 346e120..ee0a84b 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -268,10 +268,10 @@ void display_channel_surface_unref(DisplayChannel *display, uint32_t surface_id)
 
     surface->context.canvas->ops->destroy(surface->context.canvas);
     if (surface->create.info) {
-        qxl->st->qif->release_resource(qxl, surface->create);
+        qxl_if(qxl)->release_resource(qxl, surface->create);
     }
     if (surface->destroy.info) {
-        qxl->st->qif->release_resource(qxl, surface->destroy);
+        qxl_if(qxl)->release_resource(qxl, surface->destroy);
     }
 
     region_destroy(&surface->draw_dirty_region);
@@ -2162,9 +2162,7 @@ static void set_gl_draw_async_count(DisplayChannel *display, int num)
     display->gl_draw_async_count = num;
 
     if (num == 0) {
-        struct AsyncCommand *async = qxl->st->gl_draw_async;
-        qxl->st->gl_draw_async = NULL;
-        red_qxl_async_complete(qxl->st->red_qxl, async);
+        red_qxl_gl_draw_async_complete(qxl->st);
     }
 }
 
diff --git a/server/red-qxl.c b/server/red-qxl.c
index de7dc91..f79922a 100644
--- a/server/red-qxl.c
+++ b/server/red-qxl.c
@@ -45,7 +45,7 @@ struct AsyncCommand {
     uint64_t cookie;
 };
 
-struct RedQXL {
+struct QXLState {
     QXLWorker base;
     QXLInstance *qxl;
     Dispatcher dispatcher;
@@ -56,12 +56,16 @@ struct RedQXL {
     int use_hardware_cursor;
     QXLDevSurfaceCreate surface_create;
     unsigned int max_monitors;
+
+    pthread_mutex_t scanout_mutex;
+    SpiceMsgDisplayGlScanoutUnix scanout;
+    struct AsyncCommand *gl_draw_async;
 };
 
 static int red_qxl_check_qxl_version(RedQXL *rq, int major, int minor)
 {
-    int qxl_major = rq->qxl->st->qif->base.major_version;
-    int qxl_minor = rq->qxl->st->qif->base.minor_version;
+    int qxl_major = qxl_if(rq->qxl)->base.major_version;
+    int qxl_minor = qxl_if(rq->qxl)->base.minor_version;
 
     return ((qxl_major > major) ||
             ((qxl_major == major) && (qxl_minor >= minor)));
@@ -206,15 +210,15 @@ static void red_qxl_update_area(RedQXL *red_qxl, uint32_t surface_id,
 gboolean red_qxl_use_client_monitors_config(RedQXL *red_qxl)
 {
     return (red_qxl_check_qxl_version(red_qxl, 3, 3) &&
-        red_qxl->qxl->st->qif->client_monitors_config &&
-        red_qxl->qxl->st->qif->client_monitors_config(red_qxl->qxl, NULL));
+        qxl_if(red_qxl->qxl)->client_monitors_config &&
+        qxl_if(red_qxl->qxl)->client_monitors_config(red_qxl->qxl, NULL));
 }
 
 gboolean red_qxl_client_monitors_config(RedQXL *red_qxl,
                                         VDAgentMonitorsConfig *monitors_config)
 {
-    return (red_qxl->qxl->st->qif->client_monitors_config &&
-        red_qxl->qxl->st->qif->client_monitors_config(red_qxl->qxl,
+    return (qxl_if(red_qxl->qxl)->client_monitors_config &&
+        qxl_if(red_qxl->qxl)->client_monitors_config(red_qxl->qxl,
                                                           monitors_config));
 }
 
@@ -640,49 +644,49 @@ static void qxl_worker_loadvm_commands(QXLWorker *qxl_worker,
 
 void red_qxl_set_mm_time(RedQXL *red_qxl, uint32_t mm_time)
 {
-    red_qxl->qxl->st->qif->set_mm_time(red_qxl->qxl, mm_time);
+    qxl_if(red_qxl->qxl)->set_mm_time(red_qxl->qxl, mm_time);
 }
 
 void red_qxl_attach_worker(RedQXL *red_qxl)
 {
     QXLInstance *qxl = red_qxl->qxl;
-    qxl->st->qif->attache_worker(qxl, &red_qxl->base);
+    qxl_if(red_qxl->qxl)->attache_worker(qxl, &red_qxl->base);
 }
 
 void red_qxl_set_compression_level(RedQXL *red_qxl, int level)
 {
-    red_qxl->qxl->st->qif->set_compression_level(red_qxl->qxl, level);
+    qxl_if(red_qxl->qxl)->set_compression_level(red_qxl->qxl, level);
 }
 
 uint32_t red_qxl_get_ram_size(RedQXL *red_qxl)
 {
     QXLDevInitInfo qxl_info;
-    red_qxl->qxl->st->qif->get_init_info(red_qxl->qxl, &qxl_info);
+    qxl_if(red_qxl->qxl)->get_init_info(red_qxl->qxl, &qxl_info);
     return qxl_info.qxl_ram_size;
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_wakeup(QXLInstance *instance)
 {
-    red_qxl_wakeup(instance->st->red_qxl);
+    red_qxl_wakeup(instance->st);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_oom(QXLInstance *instance)
 {
-    red_qxl_oom(instance->st->red_qxl);
+    red_qxl_oom(instance->st);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_start(QXLInstance *instance)
 {
-    red_qxl_start(instance->st->red_qxl);
+    red_qxl_start(instance->st);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_stop(QXLInstance *instance)
 {
-    red_qxl_stop(instance->st->red_qxl);
+    red_qxl_stop(instance->st);
 }
 
 SPICE_GNUC_VISIBLE
@@ -690,133 +694,150 @@ void spice_qxl_update_area(QXLInstance *instance, uint32_t surface_id,
                     struct QXLRect *area, struct QXLRect *dirty_rects,
                     uint32_t num_dirty_rects, uint32_t clear_dirty_region)
 {
-    red_qxl_update_area(instance->st->red_qxl, surface_id, area, dirty_rects,
+    red_qxl_update_area(instance->st, surface_id, area, dirty_rects,
                         num_dirty_rects, clear_dirty_region);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_add_memslot(QXLInstance *instance, QXLDevMemSlot *slot)
 {
-    red_qxl_add_memslot(instance->st->red_qxl, slot);
+    red_qxl_add_memslot(instance->st, slot);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_del_memslot(QXLInstance *instance, uint32_t slot_group_id, uint32_t slot_id)
 {
-    red_qxl_del_memslot(instance->st->red_qxl, slot_group_id, slot_id);
+    red_qxl_del_memslot(instance->st, slot_group_id, slot_id);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_reset_memslots(QXLInstance *instance)
 {
-    red_qxl_reset_memslots(instance->st->red_qxl);
+    red_qxl_reset_memslots(instance->st);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_destroy_surfaces(QXLInstance *instance)
 {
-    red_qxl_destroy_surfaces(instance->st->red_qxl);
+    red_qxl_destroy_surfaces(instance->st);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_destroy_primary_surface(QXLInstance *instance, uint32_t surface_id)
 {
-    red_qxl_destroy_primary_surface(instance->st->red_qxl, surface_id, 0, 0);
+    red_qxl_destroy_primary_surface(instance->st, surface_id, 0, 0);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_create_primary_surface(QXLInstance *instance, uint32_t surface_id,
                                 QXLDevSurfaceCreate *surface)
 {
-    red_qxl_create_primary_surface(instance->st->red_qxl, surface_id, surface, 0, 0);
+    red_qxl_create_primary_surface(instance->st, surface_id, surface, 0, 0);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_reset_image_cache(QXLInstance *instance)
 {
-    red_qxl_reset_image_cache(instance->st->red_qxl);
+    red_qxl_reset_image_cache(instance->st);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_reset_cursor(QXLInstance *instance)
 {
-    red_qxl_reset_cursor(instance->st->red_qxl);
+    red_qxl_reset_cursor(instance->st);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_destroy_surface_wait(QXLInstance *instance, uint32_t surface_id)
 {
-    red_qxl_destroy_surface_wait(instance->st->red_qxl, surface_id, 0, 0);
+    red_qxl_destroy_surface_wait(instance->st, surface_id, 0, 0);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_loadvm_commands(QXLInstance *instance, struct QXLCommandExt *ext, uint32_t count)
 {
-    red_qxl_loadvm_commands(instance->st->red_qxl, ext, count);
+    red_qxl_loadvm_commands(instance->st, ext, count);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_update_area_async(QXLInstance *instance, uint32_t surface_id, QXLRect *qxl_area,
                                  uint32_t clear_dirty_region, uint64_t cookie)
 {
-    red_qxl_update_area_async(instance->st->red_qxl, surface_id, qxl_area,
+    red_qxl_update_area_async(instance->st, surface_id, qxl_area,
                                      clear_dirty_region, cookie);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_add_memslot_async(QXLInstance *instance, QXLDevMemSlot *slot, uint64_t cookie)
 {
-    red_qxl_add_memslot_async(instance->st->red_qxl, slot, cookie);
+    red_qxl_add_memslot_async(instance->st, slot, cookie);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_destroy_surfaces_async(QXLInstance *instance, uint64_t cookie)
 {
-    red_qxl_destroy_surfaces_async(instance->st->red_qxl, cookie);
+    red_qxl_destroy_surfaces_async(instance->st, cookie);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_destroy_primary_surface_async(QXLInstance *instance, uint32_t surface_id, uint64_t cookie)
 {
-    red_qxl_destroy_primary_surface(instance->st->red_qxl, surface_id, 1, cookie);
+    red_qxl_destroy_primary_surface(instance->st, surface_id, 1, cookie);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_create_primary_surface_async(QXLInstance *instance, uint32_t surface_id,
                                 QXLDevSurfaceCreate *surface, uint64_t cookie)
 {
-    red_qxl_create_primary_surface(instance->st->red_qxl, surface_id, surface, 1, cookie);
+    red_qxl_create_primary_surface(instance->st, surface_id, surface, 1, cookie);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_destroy_surface_async(QXLInstance *instance, uint32_t surface_id, uint64_t cookie)
 {
-    red_qxl_destroy_surface_wait(instance->st->red_qxl, surface_id, 1, cookie);
+    red_qxl_destroy_surface_wait(instance->st, surface_id, 1, cookie);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_flush_surfaces_async(QXLInstance *instance, uint64_t cookie)
 {
-    red_qxl_flush_surfaces_async(instance->st->red_qxl, cookie);
+    red_qxl_flush_surfaces_async(instance->st, cookie);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors_config,
                                      int group_id, uint64_t cookie)
 {
-    red_qxl_monitors_config_async(instance->st->red_qxl, monitors_config, group_id, cookie);
+    red_qxl_monitors_config_async(instance->st, monitors_config, group_id, cookie);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_set_max_monitors(QXLInstance *instance, unsigned int max_monitors)
 {
-    instance->st->red_qxl->max_monitors = MAX(1u, max_monitors);
+    instance->st->max_monitors = MAX(1u, max_monitors);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_driver_unload(QXLInstance *instance)
 {
-    red_qxl_driver_unload(instance->st->red_qxl);
+    red_qxl_driver_unload(instance->st);
+}
+
+SpiceMsgDisplayGlScanoutUnix *red_qxl_get_gl_scanout(RedQXL *red_qxl)
+{
+    pthread_mutex_lock(&red_qxl->scanout_mutex);
+    if (red_qxl->scanout.drm_dma_buf_fd >= 0) {
+        return &red_qxl->scanout;
+    }
+    pthread_mutex_unlock(&red_qxl->scanout_mutex);
+    return NULL;
+}
+
+void red_qxl_put_gl_scanout(RedQXL *red_qxl, SpiceMsgDisplayGlScanoutUnix *scanout)
+{
+    if (scanout) {
+        pthread_mutex_unlock(&red_qxl->scanout_mutex);
+    }
 }
 
 SPICE_GNUC_VISIBLE
@@ -827,15 +848,17 @@ void spice_qxl_gl_scanout(QXLInstance *qxl,
                           int y_0_top)
 {
     spice_return_if_fail(qxl != NULL);
-    spice_return_if_fail(qxl->st->gl_draw_async == NULL);
 
-    pthread_mutex_lock(&qxl->st->scanout_mutex);
+    RedQXL *red_qxl = qxl->st;
+    spice_return_if_fail(red_qxl->gl_draw_async == NULL);
 
-    if (qxl->st->scanout.drm_dma_buf_fd != -1) {
-        close(qxl->st->scanout.drm_dma_buf_fd);
+    pthread_mutex_lock(&red_qxl->scanout_mutex);
+
+    if (red_qxl->scanout.drm_dma_buf_fd != -1) {
+        close(red_qxl->scanout.drm_dma_buf_fd);
     }
 
-    qxl->st->scanout = (SpiceMsgDisplayGlScanoutUnix) {
+    red_qxl->scanout = (SpiceMsgDisplayGlScanoutUnix) {
         .flags = y_0_top ? SPICE_GL_SCANOUT_FLAGS_Y0TOP : 0,
         .drm_dma_buf_fd = fd,
         .width = width,
@@ -844,10 +867,10 @@ void spice_qxl_gl_scanout(QXLInstance *qxl,
         .drm_fourcc_format = format
     };
 
-    pthread_mutex_unlock(&qxl->st->scanout_mutex);
+    pthread_mutex_unlock(&red_qxl->scanout_mutex);
 
     /* FIXME: find a way to coallesce all pending SCANOUTs */
-    dispatcher_send_message(&qxl->st->red_qxl->dispatcher,
+    dispatcher_send_message(&red_qxl->dispatcher,
                             RED_WORKER_MESSAGE_GL_SCANOUT, NULL);
 }
 
@@ -867,11 +890,11 @@ void spice_qxl_gl_draw_async(QXLInstance *qxl,
     };
 
     spice_return_if_fail(qxl != NULL);
-    spice_return_if_fail(qxl->st->scanout.drm_dma_buf_fd != -1);
-    spice_return_if_fail(qxl->st->gl_draw_async == NULL);
+    red_qxl = qxl->st;
+    spice_return_if_fail(red_qxl->scanout.drm_dma_buf_fd != -1);
+    spice_return_if_fail(red_qxl->gl_draw_async == NULL);
 
-    red_qxl = qxl->st->red_qxl;
-    qxl->st->gl_draw_async = async_command_alloc(red_qxl, message, cookie);
+    red_qxl->gl_draw_async = async_command_alloc(red_qxl, message, cookie);
     dispatcher_send_message(&red_qxl->dispatcher, message, &draw);
 }
 
@@ -897,11 +920,19 @@ void red_qxl_async_complete(RedQXL *red_qxl,
     default:
         spice_warning("unexpected message %d", async_command->message);
     }
-    red_qxl->qxl->st->qif->async_complete(red_qxl->qxl,
-                                             async_command->cookie);
+    qxl_if(red_qxl->qxl)->async_complete(red_qxl->qxl,
+                                         async_command->cookie);
     free(async_command);
 }
 
+void red_qxl_gl_draw_async_complete(RedQXL *red_qxl)
+{
+    /* this reset before usage prevent a possible race condition */
+    struct AsyncCommand *async = red_qxl->gl_draw_async;
+    red_qxl->gl_draw_async = NULL;
+    red_qxl_async_complete(red_qxl, async);
+}
+
 void red_qxl_init(QXLInstance *qxl)
 {
     RedQXL *red_qxl;
@@ -909,7 +940,7 @@ void red_qxl_init(QXLInstance *qxl)
     ClientCbs client_cbs = { NULL, };
 
     spice_return_if_fail(qxl != NULL);
-    spice_return_if_fail(qxl->st->red_qxl == NULL);
+    spice_return_if_fail(qxl->st == NULL);
 
     static gsize initialized = FALSE;
     if (g_once_init_enter(&initialized)) {
@@ -920,6 +951,8 @@ void red_qxl_init(QXLInstance *qxl)
 
     red_qxl = spice_new0(RedQXL, 1);
     red_qxl->qxl = qxl;
+    pthread_mutex_init(&red_qxl->scanout_mutex, NULL);
+    red_qxl->scanout.drm_dma_buf_fd = -1;
     dispatcher_init(&red_qxl->dispatcher, RED_WORKER_MESSAGE_COUNT, NULL);
     red_qxl->base.major_version = SPICE_INTERFACE_QXL_MAJOR;
     red_qxl->base.minor_version = SPICE_INTERFACE_QXL_MINOR;
@@ -967,7 +1000,7 @@ void red_qxl_init(QXLInstance *qxl)
 
     red_worker_run(worker);
 
-    qxl->st->red_qxl = red_qxl;
+    qxl->st = red_qxl;
 }
 
 struct Dispatcher *red_qxl_get_dispatcher(RedQXL *red_qxl)
diff --git a/server/red-qxl.h b/server/red-qxl.h
index ada032e..8eafd56 100644
--- a/server/red-qxl.h
+++ b/server/red-qxl.h
@@ -20,7 +20,7 @@
 
 #include "red-channel.h"
 
-typedef struct RedQXL RedQXL;
+typedef struct QXLState RedQXL;
 
 typedef struct AsyncCommand AsyncCommand;
 
@@ -41,6 +41,9 @@ gboolean red_qxl_use_client_monitors_config(RedQXL *red_qxl);
 gboolean red_qxl_client_monitors_config(RedQXL *red_qxl, VDAgentMonitorsConfig *monitors_config);
 gboolean red_qxl_get_primary_active(RedQXL *red_qxl);
 gboolean red_qxl_get_allow_client_mouse(RedQXL *red_qxl, gint *x_res, gint *y_res);
+SpiceMsgDisplayGlScanoutUnix *red_qxl_get_gl_scanout(RedQXL *red_qxl);
+void red_qxl_put_gl_scanout(RedQXL *red_qxl, SpiceMsgDisplayGlScanoutUnix *scanout);
+void red_qxl_gl_draw_async_complete(RedQXL *qxl);
 
 typedef uint32_t RedWorkerMessage;
 
diff --git a/server/red-worker.c b/server/red-worker.c
index 283a044..cc7cad1 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -127,8 +127,8 @@ void red_drawable_unref(RedDrawable *red_drawable)
     if (--red_drawable->refs) {
         return;
     }
-    red_drawable->qxl->st->qif->release_resource(red_drawable->qxl,
-                                                 red_drawable->release_info_ext);
+    qxl_if(red_drawable->qxl)->release_resource(red_drawable->qxl,
+                                                red_drawable->release_info_ext);
     red_put_drawable(red_drawable);
     free(red_drawable);
 }
@@ -145,12 +145,12 @@ static int red_process_cursor(RedWorker *worker, int *ring_is_empty)
 
     *ring_is_empty = FALSE;
     while (red_channel_max_pipe_size(RED_CHANNEL(worker->cursor_channel)) <= MAX_PIPE_SIZE) {
-        if (!worker->qxl->st->qif->get_cursor_command(worker->qxl, &ext_cmd)) {
+        if (!qxl_if(worker->qxl)->get_cursor_command(worker->qxl, &ext_cmd)) {
             *ring_is_empty = TRUE;
             if (worker->cursor_poll_tries < CMD_RING_POLL_RETRIES) {
                 worker->event_timeout = MIN(worker->event_timeout, CMD_RING_POLL_TIMEOUT);
             } else if (worker->cursor_poll_tries == CMD_RING_POLL_RETRIES &&
-                       !worker->qxl->st->qif->req_cursor_notification(worker->qxl)) {
+                       !qxl_if(worker->qxl)->req_cursor_notification(worker->qxl)) {
                 continue;
             }
             worker->cursor_poll_tries++;
@@ -203,12 +203,12 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
     worker->process_display_generation++;
     *ring_is_empty = FALSE;
     while (red_channel_max_pipe_size(RED_CHANNEL(worker->display_channel)) <= MAX_PIPE_SIZE) {
-        if (!worker->qxl->st->qif->get_command(worker->qxl, &ext_cmd)) {
+        if (!qxl_if(worker->qxl)->get_command(worker->qxl, &ext_cmd)) {
             *ring_is_empty = TRUE;
             if (worker->display_poll_tries < CMD_RING_POLL_RETRIES) {
                 worker->event_timeout = MIN(worker->event_timeout, CMD_RING_POLL_TIMEOUT);
             } else if (worker->display_poll_tries == CMD_RING_POLL_RETRIES &&
-                       !worker->qxl->st->qif->req_cmd_notification(worker->qxl)) {
+                       !qxl_if(worker->qxl)->req_cmd_notification(worker->qxl)) {
                 continue;
             }
             worker->display_poll_tries++;
@@ -245,9 +245,9 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
                 spice_warning("Invalid surface in QXL_CMD_UPDATE");
             } else {
                 display_channel_draw(worker->display_channel, &update.area, update.surface_id);
-                worker->qxl->st->qif->notify_update(worker->qxl, update.update_id);
+                qxl_if(worker->qxl)->notify_update(worker->qxl, update.update_id);
             }
-            worker->qxl->st->qif->release_resource(worker->qxl, update.release_info_ext);
+            qxl_if(worker->qxl)->release_resource(worker->qxl, update.release_info_ext);
             red_put_update_cmd(&update);
             break;
         }
@@ -262,7 +262,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
             /* alert: accessing message.data is insecure */
             spice_warning("MESSAGE: %s", message.data);
 #endif
-            worker->qxl->st->qif->release_resource(worker->qxl, message.release_info_ext);
+            qxl_if(worker->qxl)->release_resource(worker->qxl, message.release_info_ext);
             red_put_message(&message);
             break;
         }
@@ -507,11 +507,12 @@ static void guest_set_client_capabilities(RedWorker *worker)
         SPICE_DISPLAY_CAP_COMPOSITE,
         SPICE_DISPLAY_CAP_A8_SURFACE,
     };
+    QXLInterface *qif = qxl_if(worker->qxl);
 
-    if (worker->qxl->st->qif->base.major_version < 3 ||
-        (worker->qxl->st->qif->base.major_version == 3 &&
-        worker->qxl->st->qif->base.minor_version < 2) ||
-        !worker->qxl->st->qif->set_client_capabilities) {
+    if (qif->base.major_version < 3 ||
+        (qif->base.major_version == 3 &&
+        qif->base.minor_version < 2) ||
+        !qif->set_client_capabilities) {
         return;
     }
 #define SET_CAP(a,c)                                                    \
@@ -525,7 +526,7 @@ static void guest_set_client_capabilities(RedWorker *worker)
     }
     if ((worker->display_channel == NULL) ||
         (RED_CHANNEL(worker->display_channel)->clients_num == 0)) {
-        worker->qxl->st->qif->set_client_capabilities(worker->qxl, FALSE, caps);
+        qif->set_client_capabilities(worker->qxl, FALSE, caps);
     } else {
         // Take least common denominator
         for (i = 0 ; i < sizeof(caps_available) / sizeof(caps_available[0]); ++i) {
@@ -538,7 +539,7 @@ static void guest_set_client_capabilities(RedWorker *worker)
                     CLEAR_CAP(caps, caps_available[i]);
             }
         }
-        worker->qxl->st->qif->set_client_capabilities(worker->qxl, TRUE, caps);
+        qif->set_client_capabilities(worker->qxl, TRUE, caps);
     }
 }
 
@@ -577,14 +578,14 @@ static void handle_dev_update_async(void *opaque, void *payload)
     uint32_t num_dirty_rects = 0;
 
     spice_return_if_fail(worker->running);
-    spice_return_if_fail(worker->qxl->st->qif->update_area_complete);
+    spice_return_if_fail(qxl_if(worker->qxl)->update_area_complete);
 
     flush_display_commands(worker);
     display_channel_update(worker->display_channel,
                            msg->surface_id, &msg->qxl_area, msg->clear_dirty_region,
                            &qxl_dirty_rects, &num_dirty_rects);
 
-    worker->qxl->st->qif->update_area_complete(worker->qxl, msg->surface_id,
+    qxl_if(worker->qxl)->update_area_complete(worker->qxl, msg->surface_id,
                                                 qxl_dirty_rects, num_dirty_rects);
     free(qxl_dirty_rects);
 }
@@ -844,9 +845,9 @@ static void handle_dev_oom(void *opaque, void *payload)
     while (red_process_display(worker, &ring_is_empty)) {
         red_channel_push(display_red_channel);
     }
-    if (worker->qxl->st->qif->flush_resources(worker->qxl) == 0) {
+    if (qxl_if(worker->qxl)->flush_resources(worker->qxl) == 0) {
         display_channel_free_some(worker->display_channel);
-        worker->qxl->st->qif->flush_resources(worker->qxl);
+        qxl_if(worker->qxl)->flush_resources(worker->qxl);
     }
     spice_debug("OOM2 #draw=%u, #glz_draw=%u current %u pipes %u",
                 display->drawable_count,
@@ -1469,7 +1470,7 @@ RedWorker* red_worker_new(QXLInstance *qxl, RedQXL *red_qxl)
     Dispatcher *dispatcher;
     const char *record_filename;
 
-    qxl->st->qif->get_init_info(qxl, &init_info);
+    qxl_if(qxl)->get_init_info(qxl, &init_info);
 
     worker = spice_new0(RedWorker, 1);
     worker->core = event_loop_core;
diff --git a/server/reds.c b/server/reds.c
index bd79dd4..8153a9a 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -571,7 +571,7 @@ static void reds_set_mouse_mode(RedsState *reds, uint32_t mode)
     reds->mouse_mode = mode;
 
     for (l = reds->red_qxls; l != NULL; l = l->next)
-        red_qxl_set_mouse_mode(l->data, mode);
+        red_qxl_set_mouse_mode((RedQXL*) l->data, mode);
 
     main_channel_push_mouse_mode(reds->main_channel, reds->mouse_mode, reds->is_client_mouse_allowed);
 }
@@ -3205,12 +3205,8 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
         }
 
         qxl = SPICE_CONTAINEROF(sin, QXLInstance, base);
-        qxl->st = spice_new0(QXLState, 1);
-        pthread_mutex_init(&qxl->st->scanout_mutex, NULL);
-        qxl->st->scanout.drm_dma_buf_fd = -1;
-        qxl->st->qif = SPICE_CONTAINEROF(interface, QXLInterface, base);
         red_qxl_init(qxl);
-        red_qxl = qxl->st->red_qxl;
+        red_qxl = qxl->st;
         reds->red_qxls = g_list_prepend(reds->red_qxls, red_qxl);
 
         /* this function has to be called after the qxl is on the list
@@ -4172,7 +4168,7 @@ void reds_on_vm_stop(RedsState *reds)
     GList *l;
 
     for (l = reds->red_qxls; l != NULL; l = l->next)
-        red_qxl_stop(l->data);
+        red_qxl_stop((RedQXL*) l->data);
 }
 
 void reds_on_vm_start(RedsState *reds)
@@ -4180,7 +4176,7 @@ void reds_on_vm_start(RedsState *reds)
     GList *l;
 
     for (l = reds->red_qxls; l != NULL; l = l->next)
-        red_qxl_start(l->data);
+        red_qxl_start((RedQXL*) l->data);
 }
 
 uint32_t reds_qxl_ram_size(RedsState *reds)
diff --git a/server/reds.h b/server/reds.h
index 46cea85..4932b2c 100644
--- a/server/reds.h
+++ b/server/reds.h
@@ -34,13 +34,10 @@
 typedef struct RedsState RedsState;
 extern RedsState *reds;
 
-struct QXLState {
-    QXLInterface          *qif;
-    struct RedQXL  *red_qxl;
-    pthread_mutex_t scanout_mutex;
-    SpiceMsgDisplayGlScanoutUnix scanout;
-    struct AsyncCommand *gl_draw_async;
-};
+static inline QXLInterface * qxl_if(QXLInstance *qxl)
+{
+    return SPICE_CONTAINEROF(qxl->base.sif, QXLInterface, base);
+}
 
 struct TunnelWorker;
 struct SpiceNetWireState {
-- 
2.5.0



More information about the Spice-devel mailing list