Now that we have a refcounted RedSurfaceCmd, we can store the command
itself in DisplayChannel rather than copying QXLReleaseInfoExt. This
will let us move the release of the QXL guest resources in red-parse-qxl
in the next commit.

Signed-off-by: Christophe Fergeau <cferg...@redhat.com>
---
 server/display-channel-private.h |  7 ++++++-
 server/display-channel.c         | 22 +++++++++++++---------
 server/display-channel.h         |  2 +-
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/server/display-channel-private.h b/server/display-channel-private.h
index 617ce30d2..d9c9ce7f9 100644
--- a/server/display-channel-private.h
+++ b/server/display-channel-private.h
@@ -52,7 +52,12 @@ typedef struct RedSurface {
     QRegion draw_dirty_region;
 
     //fix me - better handling here
-    QXLReleaseInfoExt create, destroy;
+    /* 'create_cmd' holds surface data through a pointer to guest memory, it
+     * must be valid as long as the surface is valid */
+    RedSurfaceCmd *create_cmd;
+    /* QEMU expects the guest data for the command to be valid as long as the
+     * surface is valid */
+    RedSurfaceCmd *destroy_cmd;
 } RedSurface;
 
 typedef struct MonitorsConfig {
diff --git a/server/display-channel.c b/server/display-channel.c
index 229f2c0fd..0cc32813b 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -300,11 +300,15 @@ void display_channel_surface_unref(DisplayChannel 
*display, uint32_t surface_id)
     spice_assert(surface->context.canvas);
 
     surface->context.canvas->ops->destroy(surface->context.canvas);
-    if (surface->create.info) {
-        red_qxl_release_resource(qxl, surface->create);
+    if (surface->create_cmd != NULL) {
+        red_qxl_release_resource(qxl, surface->create_cmd->release_info_ext);
+        red_surface_cmd_unref(surface->create_cmd);
+        surface->create_cmd = NULL;
     }
-    if (surface->destroy.info) {
-        red_qxl_release_resource(qxl, surface->destroy);
+    if (surface->destroy_cmd != NULL) {
+        red_qxl_release_resource(qxl, surface->destroy_cmd->release_info_ext);
+        red_surface_cmd_unref(surface->destroy_cmd);
+        surface->destroy_cmd = NULL;
     }
 
     region_destroy(&surface->draw_dirty_region);
@@ -2164,8 +2168,8 @@ void display_channel_create_surface(DisplayChannel 
*display, uint32_t surface_id
         }
         memset(data, 0, height*abs(stride));
     }
-    surface->create.info = NULL;
-    surface->destroy.info = NULL;
+    g_warn_if_fail(surface->create_cmd == NULL);
+    g_warn_if_fail(surface->destroy_cmd == NULL);
     ring_init(&surface->current);
     ring_init(&surface->current_list);
     ring_init(&surface->depend_on_me);
@@ -2309,7 +2313,7 @@ display_channel_constructed(GObject *object)
 }
 
 void display_channel_process_surface_cmd(DisplayChannel *display,
-                                         const RedSurfaceCmd *surface_cmd,
+                                         RedSurfaceCmd *surface_cmd,
                                          int loadvm)
 {
     uint32_t surface_id;
@@ -2345,7 +2349,7 @@ void display_channel_process_surface_cmd(DisplayChannel 
*display,
                                        reloaded_surface,
                                        // reloaded surfaces will be sent on 
demand
                                        !reloaded_surface);
-        surface->create = surface_cmd->release_info_ext;
+        surface->create_cmd = red_surface_cmd_ref(surface_cmd);
         break;
     }
     case QXL_SURFACE_CMD_DESTROY:
@@ -2353,7 +2357,7 @@ void display_channel_process_surface_cmd(DisplayChannel 
*display,
             spice_warning("avoiding destroying a surface twice");
             break;
         }
-        surface->destroy = surface_cmd->release_info_ext;
+        surface->destroy_cmd = red_surface_cmd_ref(surface_cmd);
         display_channel_destroy_surface(display, surface_id);
         break;
     default:
diff --git a/server/display-channel.h b/server/display-channel.h
index e26d2ba14..a4df9317a 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -148,7 +148,7 @@ void                       display_channel_process_draw     
         (DisplayCha
                                                                       
RedDrawable *red_drawable,
                                                                       uint32_t 
process_commands_generation);
 void                       display_channel_process_surface_cmd       
(DisplayChannel *display,
-                                                                      const 
RedSurfaceCmd *surface_cmd,
+                                                                      
RedSurfaceCmd *surface_cmd,
                                                                       int 
loadvm);
 void                       display_channel_update_compression        
(DisplayChannel *display,
                                                                       
DisplayChannelClient *dcc);
-- 
2.14.3

_______________________________________________
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to