mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-08-10 01:32:16 +00:00
Move monitors_config to display
Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
This commit is contained in:
parent
791d5a2d46
commit
fae3f7a062
@ -36,3 +36,48 @@ DisplayChannelClient *dcc_new(DisplayChannel *display,
|
||||
|
||||
return dcc;
|
||||
}
|
||||
|
||||
MonitorsConfig* monitors_config_ref(MonitorsConfig *monitors_config)
|
||||
{
|
||||
monitors_config->refs++;
|
||||
|
||||
return monitors_config;
|
||||
}
|
||||
|
||||
void monitors_config_unref(MonitorsConfig *monitors_config)
|
||||
{
|
||||
if (!monitors_config) {
|
||||
return;
|
||||
}
|
||||
if (--monitors_config->refs != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
spice_debug("freeing monitors config");
|
||||
free(monitors_config);
|
||||
}
|
||||
|
||||
static void monitors_config_debug(MonitorsConfig *mc)
|
||||
{
|
||||
int i;
|
||||
|
||||
spice_debug("monitors config count:%d max:%d", mc->count, mc->max_allowed);
|
||||
for (i = 0; i < mc->count; i++)
|
||||
spice_debug("+%d+%d %dx%d",
|
||||
mc->heads[i].x, mc->heads[i].y,
|
||||
mc->heads[i].width, mc->heads[i].height);
|
||||
}
|
||||
|
||||
MonitorsConfig* monitors_config_new(QXLHead *heads, ssize_t nheads, ssize_t max)
|
||||
{
|
||||
MonitorsConfig *mc;
|
||||
|
||||
mc = spice_malloc(sizeof(MonitorsConfig) + nheads * sizeof(QXLHead));
|
||||
mc->refs = 1;
|
||||
mc->count = nheads;
|
||||
mc->max_allowed = max;
|
||||
memcpy(mc->heads, heads, nheads * sizeof(QXLHead));
|
||||
monitors_config_debug(mc);
|
||||
|
||||
return mc;
|
||||
}
|
||||
|
||||
@ -237,4 +237,21 @@ DisplayChannelClient* dcc_new (DisplayCha
|
||||
uint32_t *caps,
|
||||
int num_caps);
|
||||
|
||||
typedef struct MonitorsConfig {
|
||||
int refs;
|
||||
int count;
|
||||
int max_allowed;
|
||||
QXLHead heads[0];
|
||||
} MonitorsConfig;
|
||||
|
||||
typedef struct MonitorsConfigItem {
|
||||
PipeItem pipe_item;
|
||||
MonitorsConfig *monitors_config;
|
||||
} MonitorsConfigItem;
|
||||
|
||||
MonitorsConfig* monitors_config_new (QXLHead *heads, ssize_t nheads,
|
||||
ssize_t max);
|
||||
MonitorsConfig * monitors_config_ref (MonitorsConfig *config);
|
||||
void monitors_config_unref (MonitorsConfig *config);
|
||||
|
||||
#endif /* DISPLAY_CHANNEL_H_ */
|
||||
|
||||
@ -258,19 +258,6 @@ typedef struct SurfaceDestroyItem {
|
||||
PipeItem pipe_item;
|
||||
} SurfaceDestroyItem;
|
||||
|
||||
typedef struct MonitorsConfig {
|
||||
int refs;
|
||||
struct RedWorker *worker;
|
||||
int count;
|
||||
int max_allowed;
|
||||
QXLHead heads[0];
|
||||
} MonitorsConfig;
|
||||
|
||||
typedef struct MonitorsConfigItem {
|
||||
PipeItem pipe_item;
|
||||
MonitorsConfig *monitors_config;
|
||||
} MonitorsConfigItem;
|
||||
|
||||
typedef struct StreamActivateReportItem {
|
||||
PipeItem pipe_item;
|
||||
uint32_t stream_id;
|
||||
@ -376,6 +363,8 @@ Ring glz_dictionary_list = {&glz_dictionary_list, &glz_dictionary_list};
|
||||
struct DisplayChannel {
|
||||
CommonChannel common; // Must be the first thing
|
||||
|
||||
MonitorsConfig *monitors_config;
|
||||
|
||||
uint32_t num_renderers;
|
||||
uint32_t renderers[RED_RENDERER_LAST];
|
||||
uint32_t renderer;
|
||||
@ -489,8 +478,6 @@ typedef struct RedWorker {
|
||||
uint32_t n_surfaces;
|
||||
SpiceImageSurfaces image_surfaces;
|
||||
|
||||
MonitorsConfig *monitors_config;
|
||||
|
||||
Ring current_list;
|
||||
uint32_t current_size;
|
||||
uint32_t drawable_count;
|
||||
@ -609,8 +596,7 @@ static void display_channel_client_release_item_before_push(DisplayChannelClient
|
||||
PipeItem *item);
|
||||
static void display_channel_client_release_item_after_push(DisplayChannelClient *dcc,
|
||||
PipeItem *item);
|
||||
|
||||
static void red_push_monitors_config(DisplayChannelClient *dcc);
|
||||
static void dcc_push_monitors_config(DisplayChannelClient *dcc);
|
||||
|
||||
/*
|
||||
* Macros to make iterating over stuff easier
|
||||
@ -752,26 +738,6 @@ QXLInstance* red_worker_get_qxl(RedWorker *worker)
|
||||
return worker->qxl;
|
||||
}
|
||||
|
||||
static MonitorsConfig *monitors_config_getref(MonitorsConfig *monitors_config)
|
||||
{
|
||||
monitors_config->refs++;
|
||||
|
||||
return monitors_config;
|
||||
}
|
||||
|
||||
static void monitors_config_decref(MonitorsConfig *monitors_config)
|
||||
{
|
||||
if (!monitors_config) {
|
||||
return;
|
||||
}
|
||||
if (--monitors_config->refs > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
spice_debug("freeing monitors config");
|
||||
free(monitors_config);
|
||||
}
|
||||
|
||||
static inline int is_primary_surface(RedWorker *worker, uint32_t surface_id)
|
||||
{
|
||||
if (surface_id == 0) {
|
||||
@ -8510,7 +8476,7 @@ static void on_new_display_channel_client(DisplayChannelClient *dcc)
|
||||
red_current_flush(worker, 0);
|
||||
push_new_primary_surface(dcc);
|
||||
red_push_surface_image(dcc, 0);
|
||||
red_push_monitors_config(dcc);
|
||||
dcc_push_monitors_config(dcc);
|
||||
red_pipe_add_verb(rcc, SPICE_MSG_DISPLAY_MARK);
|
||||
red_disply_start_streams(dcc);
|
||||
}
|
||||
@ -9153,7 +9119,7 @@ static void display_channel_client_release_item_after_push(DisplayChannelClient
|
||||
case PIPE_ITEM_TYPE_MONITORS_CONFIG: {
|
||||
MonitorsConfigItem *monconf_item = SPICE_CONTAINEROF(item,
|
||||
MonitorsConfigItem, pipe_item);
|
||||
monitors_config_decref(monconf_item->monitors_config);
|
||||
monitors_config_unref(monconf_item->monitors_config);
|
||||
free(item);
|
||||
break;
|
||||
}
|
||||
@ -9210,7 +9176,7 @@ static void display_channel_client_release_item_before_push(DisplayChannelClient
|
||||
case PIPE_ITEM_TYPE_MONITORS_CONFIG: {
|
||||
MonitorsConfigItem *monconf_item = SPICE_CONTAINEROF(item,
|
||||
MonitorsConfigItem, pipe_item);
|
||||
monitors_config_decref(monconf_item->monitors_config);
|
||||
monitors_config_unref(monconf_item->monitors_config);
|
||||
free(item);
|
||||
break;
|
||||
}
|
||||
@ -9617,7 +9583,7 @@ void handle_dev_destroy_surfaces(void *opaque, void *payload)
|
||||
dev_destroy_surfaces(worker);
|
||||
}
|
||||
|
||||
static MonitorsConfigItem *get_monitors_config_item(
|
||||
static MonitorsConfigItem *monitors_config_item_new(
|
||||
RedChannel* channel, MonitorsConfig *monitors_config)
|
||||
{
|
||||
MonitorsConfigItem *mci;
|
||||
@ -9632,47 +9598,29 @@ static MonitorsConfigItem *get_monitors_config_item(
|
||||
|
||||
static inline void red_monitors_config_item_add(DisplayChannelClient *dcc)
|
||||
{
|
||||
DisplayChannel *dc = DCC_TO_DC(dcc);
|
||||
MonitorsConfigItem *mci;
|
||||
RedWorker *worker = dcc->common.worker;
|
||||
|
||||
mci = get_monitors_config_item(dcc->common.base.channel,
|
||||
monitors_config_getref(worker->monitors_config));
|
||||
mci = monitors_config_item_new(dcc->common.base.channel,
|
||||
monitors_config_ref(dc->monitors_config));
|
||||
red_channel_client_pipe_add(&dcc->common.base, &mci->pipe_item);
|
||||
}
|
||||
|
||||
static void worker_update_monitors_config(RedWorker *worker,
|
||||
QXLMonitorsConfig *dev_monitors_config,
|
||||
uint16_t count, uint16_t max_allowed)
|
||||
static void display_update_monitors_config(DisplayChannel *display,
|
||||
QXLMonitorsConfig *config,
|
||||
uint16_t count, uint16_t max_allowed)
|
||||
{
|
||||
int heads_size;
|
||||
MonitorsConfig *monitors_config;
|
||||
int i;
|
||||
|
||||
monitors_config_decref(worker->monitors_config);
|
||||
if (display->monitors_config)
|
||||
monitors_config_unref(display->monitors_config);
|
||||
|
||||
spice_debug("monitors config %d(%d)",
|
||||
count,
|
||||
max_allowed);
|
||||
for (i = 0; i < count; i++) {
|
||||
spice_debug("+%d+%d %dx%d",
|
||||
dev_monitors_config->heads[i].x,
|
||||
dev_monitors_config->heads[i].y,
|
||||
dev_monitors_config->heads[i].width,
|
||||
dev_monitors_config->heads[i].height);
|
||||
}
|
||||
heads_size = count * sizeof(QXLHead);
|
||||
worker->monitors_config = monitors_config =
|
||||
spice_malloc(sizeof(*monitors_config) + heads_size);
|
||||
monitors_config->refs = 1;
|
||||
monitors_config->worker = worker;
|
||||
monitors_config->count = count;
|
||||
monitors_config->max_allowed = max_allowed;
|
||||
memcpy(monitors_config->heads, dev_monitors_config->heads, heads_size);
|
||||
display->monitors_config =
|
||||
monitors_config_new(config->heads, count, max_allowed);
|
||||
}
|
||||
|
||||
static void red_push_monitors_config(DisplayChannelClient *dcc)
|
||||
static void dcc_push_monitors_config(DisplayChannelClient *dcc)
|
||||
{
|
||||
MonitorsConfig *monitors_config = DCC_TO_WORKER(dcc)->monitors_config;
|
||||
MonitorsConfig *monitors_config = DCC_TO_DC(dcc)->monitors_config;
|
||||
|
||||
if (monitors_config == NULL) {
|
||||
spice_warning("monitors_config is NULL");
|
||||
@ -9693,34 +9641,24 @@ static void red_worker_push_monitors_config(RedWorker *worker)
|
||||
RingItem *item, *next;
|
||||
|
||||
WORKER_FOREACH_DCC_SAFE(worker, item, next, dcc) {
|
||||
red_push_monitors_config(dcc);
|
||||
dcc_push_monitors_config(dcc);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_monitors_config_to_primary(RedWorker *worker)
|
||||
{
|
||||
QXLHead *head;
|
||||
DrawContext *context;
|
||||
DrawContext *context = &worker->surfaces[0].context;
|
||||
DisplayChannel *display = worker->display_channel;
|
||||
QXLHead head = { 0, };
|
||||
|
||||
if (!worker->surfaces[0].context.canvas) {
|
||||
spice_warning("no primary surface");
|
||||
return;
|
||||
}
|
||||
monitors_config_decref(worker->monitors_config);
|
||||
context = &worker->surfaces[0].context;
|
||||
worker->monitors_config =
|
||||
spice_malloc(sizeof(*worker->monitors_config) + sizeof(QXLHead));
|
||||
worker->monitors_config->refs = 1;
|
||||
worker->monitors_config->worker = worker;
|
||||
worker->monitors_config->count = 1;
|
||||
worker->monitors_config->max_allowed = 1;
|
||||
head = worker->monitors_config->heads;
|
||||
head->id = 0;
|
||||
head->surface_id = 0;
|
||||
head->width = context->width;
|
||||
head->height = context->height;
|
||||
head->x = 0;
|
||||
head->y = 0;
|
||||
spice_return_if_fail(worker->surfaces[0].context.canvas);
|
||||
|
||||
if (display->monitors_config)
|
||||
monitors_config_unref(display->monitors_config);
|
||||
|
||||
head.width = context->width;
|
||||
head.height = context->height;
|
||||
display->monitors_config = monitors_config_new(&head, 1, 1);
|
||||
}
|
||||
|
||||
static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
|
||||
@ -10098,9 +10036,9 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)
|
||||
/* TODO: raise guest bug (requires added QXL interface) */
|
||||
return;
|
||||
}
|
||||
worker_update_monitors_config(worker, dev_monitors_config,
|
||||
MIN(count, msg->max_monitors),
|
||||
MIN(max_allowed, msg->max_monitors));
|
||||
display_update_monitors_config(worker->display_channel, dev_monitors_config,
|
||||
MIN(count, msg->max_monitors),
|
||||
MIN(max_allowed, msg->max_monitors));
|
||||
red_worker_push_monitors_config(worker);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user