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>
This commit is contained in:
Marc-André Lureau 2015-11-18 14:22:25 +01:00 committed by Frediano Ziglio
parent b12b248cae
commit 3941d03d11
3 changed files with 576 additions and 617 deletions

View File

@ -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;
}

View File

@ -288,6 +288,30 @@ void monitors_config_unref (MonitorsCo
#define NUM_TRACE_ITEMS (1 << TRACE_ITEMS_SHIFT)
#define ITEMS_TRACE_MASK (NUM_TRACE_ITEMS - 1)
typedef struct DrawContext {
SpiceCanvas *canvas;
int canvas_draws_on_surface;
int top_down;
uint32_t width;
uint32_t height;
int32_t stride;
uint32_t format;
void *line_0;
} DrawContext;
typedef struct RedSurface {
uint32_t refs;
Ring current;
Ring current_list;
DrawContext context;
Ring depend_on_me;
QRegion draw_dirty_region;
//fix me - better handling here
QXLReleaseInfoExt create, destroy;
} RedSurface;
#define NUM_DRAWABLES 1000
typedef struct _Drawable _Drawable;
struct _Drawable {
@ -326,6 +350,10 @@ struct DisplayChannel {
uint32_t next_item_trace;
uint64_t streams_size_total;
RedSurface surfaces[NUM_SURFACES];
uint32_t n_surfaces;
SpiceImageSurfaces image_surfaces;
ImageCache image_cache;
RedCompressBuf *free_compress_bufs;
@ -384,6 +412,10 @@ int display_channel_get_streams_timeout (DisplayCha
void display_channel_compress_stats_print (const DisplayChannel *display);
void display_channel_compress_stats_reset (DisplayChannel *display);
void display_channel_drawable_unref (DisplayChannel *display, Drawable *drawable);
void display_channel_surface_unref (DisplayChannel *display,
uint32_t surface_id);
bool display_channel_surface_has_canvas (DisplayChannel *display,
uint32_t surface_id);
static inline int is_equal_path(SpicePath *path1, SpicePath *path2)
{

File diff suppressed because it is too large Load Diff