summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2018-04-23 18:45:44 +0200
committerChristophe Fergeau <cfergeau@redhat.com>2018-04-23 18:52:23 +0200
commit82a959af896724c1df619860a0602df556602328 (patch)
tree241b4b269d7b9d46a661a44ffeb41489c9084a0f
parentc08f18830b62caa6eea53faea27bcc4c1692381b (diff)
store pointer to RedSurfaceCmd in DisplayChannel rather than copying releaseinfoext
-rw-r--r--server/display-channel-private.h7
-rw-r--r--server/display-channel.c22
-rw-r--r--server/display-channel.h2
3 files changed, 20 insertions, 11 deletions
diff --git a/server/display-channel-private.h b/server/display-channel-private.h
index 617ce30d..d9c9ce7f 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 229f2c0f..0cc32813 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 e26d2ba1..a4df9317 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);