diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2015-11-18 14:22:25 +0100 |
---|---|---|
committer | Frediano Ziglio <fziglio@redhat.com> | 2015-11-18 14:27:45 +0000 |
commit | 3941d03d116df8213836719dce179d40bf55a6ca (patch) | |
tree | 8c99529d316fa14dec228568ee0fda1946d5cdff /server/display-channel.c | |
parent | b12b248cae9b446bd581bfec081d30de94e97d8d (diff) | |
download | spice-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.c | 61 |
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; +} |