mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-27 23:49:04 +00:00
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:
parent
b12b248cae
commit
3941d03d11
@ -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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
1100
server/red_worker.c
1100
server/red_worker.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user