summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/display-channel.c45
-rw-r--r--server/display-channel.h16
-rw-r--r--server/red_worker.c130
3 files changed, 95 insertions, 96 deletions
diff --git a/server/display-channel.c b/server/display-channel.c
index 00be6654..0fdec413 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -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;
+}
diff --git a/server/display-channel.h b/server/display-channel.h
index d8728a55..c4c55ff7 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -310,5 +310,21 @@ DrawablePipeItem* drawable_pipe_item_new (DisplayCha
void drawable_pipe_item_unref (DrawablePipeItem *dpi);
DrawablePipeItem* drawable_pipe_item_ref (DrawablePipeItem *dpi);
+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_ */
diff --git a/server/red_worker.c b/server/red_worker.c
index e23c4600..58480f67 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -241,19 +241,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;
@@ -359,6 +346,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;
@@ -462,8 +451,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;
@@ -583,8 +570,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
@@ -754,26 +740,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) {
@@ -8463,7 +8429,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);
}
@@ -9106,7 +9072,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;
}
@@ -9163,7 +9129,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;
}
@@ -9567,7 +9533,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;
@@ -9582,47 +9548,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");
@@ -9643,34 +9591,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,
@@ -10031,9 +9969,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);
}