summaryrefslogtreecommitdiffstats
path: root/server/display-channel.c
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2015-11-18 14:22:25 +0100
committerFrediano Ziglio <fziglio@redhat.com>2015-11-18 14:27:45 +0000
commit3941d03d116df8213836719dce179d40bf55a6ca (patch)
tree8c99529d316fa14dec228568ee0fda1946d5cdff /server/display-channel.c
parentb12b248cae9b446bd581bfec081d30de94e97d8d (diff)
downloadspice-3941d03d116df8213836719dce179d40bf55a6ca.tar.gz
spice-3941d03d116df8213836719dce179d40bf55a6ca.tar.xz
spice-3941d03d116df8213836719dce179d40bf55a6ca.zip
worker: move surfaces to DisplayChannel
Ok. this one was painful.Note that in some cases, DCC_TO_DC should be made safer (there used to be a if !dcc guard in some places, although that looks wrong anyway)... Acked-by: Pavel Grunt <pgrunt@redhat.com>
Diffstat (limited to 'server/display-channel.c')
-rw-r--r--server/display-channel.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/server/display-channel.c b/server/display-channel.c
index 63d56b46..222b2e30 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -320,3 +320,64 @@ void display_channel_set_stream_video(DisplayChannel *display, int stream_video)
display->stream_video = stream_video;
}
+
+static void stop_streams(DisplayChannel *display)
+{
+ Ring *ring = &display->streams;
+ RingItem *item = ring_get_head(ring);
+
+ while (item) {
+ Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
+ item = ring_next(ring, item);
+ if (!stream->current) {
+ stream_stop(display, stream);
+ } else {
+ spice_info("attached stream");
+ }
+ }
+
+ display->next_item_trace = 0;
+ memset(display->items_trace, 0, sizeof(display->items_trace));
+}
+
+void display_channel_surface_unref(DisplayChannel *display, uint32_t surface_id)
+{
+ RedSurface *surface = &display->surfaces[surface_id];
+ RedWorker *worker = COMMON_CHANNEL(display)->worker;
+ QXLInstance *qxl = red_worker_get_qxl(worker);
+ DisplayChannelClient *dcc;
+ RingItem *link, *next;
+
+ if (--surface->refs != 0) {
+ return;
+ }
+
+ // only primary surface streams are supported
+ if (is_primary_surface(display, surface_id)) {
+ stop_streams(display);
+ }
+ spice_assert(surface->context.canvas);
+
+ surface->context.canvas->ops->destroy(surface->context.canvas);
+ if (surface->create.info) {
+ qxl->st->qif->release_resource(qxl, surface->create);
+ }
+ if (surface->destroy.info) {
+ qxl->st->qif->release_resource(qxl, surface->destroy);
+ }
+
+ region_destroy(&surface->draw_dirty_region);
+ surface->context.canvas = NULL;
+ FOREACH_DCC(display, link, next, dcc) {
+ dcc_push_destroy_surface(dcc, surface_id);
+ }
+
+ spice_warn_if(!ring_is_empty(&surface->depend_on_me));
+}
+
+/* TODO: perhaps rename to "ready" or "realized" ? */
+bool display_channel_surface_has_canvas(DisplayChannel *display,
+ uint32_t surface_id)
+{
+ return display->surfaces[surface_id].context.canvas != NULL;
+}