Hi, On Mon, 2016-10-10 at 08:37 -0400, Marc-André Lureau wrote: > Hi > > ----- Original Message ----- > > When the guest receives the monitor configuration message, it > > replies > > (through spice-server) by destroying the primary surface, which > > makes > > the SpiceDisplay disabled if its "resize-guest" property is used. > > This change of the display state (disabled/enabled) leads to > > sending > > a new monitor config message (containing the disabled display) > > after > > a second. Then spice-server sends the monitor configuration > > message, > > spice-gtk replies back and we may end up with a loop of monitor > > configuration messages even if no real change of monitor > > configuration > > happens. > > It's hard follow, could you explain step by step what you mean. sorry, I overlooked your question I did more investigation and following is happening from clients perspective: 1. let window width be 401 2. client sends request to resize 3. client receives PRIMARY_DESTROY 4. client marks the display as disabled (config in the main channel) 5. client receives PRIMARY_CREATE + dimensions of display - width is 400 6. client sends a new resize request since resize-guest is on, and display width != window width Flickering is PRIMARY_DESTROY & PRIMARY_CREATE Pavel > > To avoid the loop, the new monitor configuration messages are only > > sent > > if they are different from the current monitor configuration. > > > > All the issues are visible only with Wayland & QXL driver on the > > guest > > > > Fixes: > > https://bugzilla.redhat.com/show_bug.cgi?id=1266484 > > https://bugs.freedesktop.org/show_bug.cgi?id=94950 > > --- > > v3: rebased, fixed typos > > In v2, Jonathon raised a valid concern: "However, it's theoretically > possible that the last sent configuration may not have been > successful." For ex, vdagent wasn't yet started (whatever handles > the monitor config change). > > Imho, it should be fine for the client to send the same monitor > config, the server should however not notify of changes if none > happened. > > > v2: > > https://lists.freedesktop.org/archives/spice-devel/2015-October/02 > > 2784.html > > --- > > src/channel-main.c | 59 > > +++++++++++++++++++++++++++++++++++------------------- > > 1 file changed, 38 insertions(+), 21 deletions(-) > > > > diff --git a/src/channel-main.c b/src/channel-main.c > > index 990a06a..1a46819 100644 > > --- a/src/channel-main.c > > +++ b/src/channel-main.c > > @@ -105,7 +105,8 @@ struct _SpiceMainChannelPrivate { > > guint agent_msg_pos; > > uint8_t agent_msg_size; > > uint32_t agent_caps[VD_AGENT_CAPS_SIZE]; > > - SpiceDisplayConfig display[MAX_DISPLAY]; > > + SpiceDisplayConfig display_current[MAX_DISPLAY]; /* > > current > > configuration of spice-widgets */ > > + SpiceDisplayConfig display_new[MAX_DISPLAY]; /* new > > requested > > configuration */ > > gint timer_id; > > GQueue *agent_msg_queue; > > GHashTable *file_xfer_tasks; > > @@ -1098,11 +1099,11 @@ gboolean > > spice_main_send_monitor_config(SpiceMainChannel *channel) > > > > if (spice_main_agent_test_capability(channel, > > VD_AGENT_CAP_SPARSE_MONITORS > > _CONFIG)) { > > - monitors = SPICE_N_ELEMENTS(c->display); > > + monitors = SPICE_N_ELEMENTS(c->display_new); > > } else { > > monitors = 0; > > - for (i = 0; i < SPICE_N_ELEMENTS(c->display); i++) { > > - if (c->display[i].display_state == DISPLAY_ENABLED) > > + for (i = 0; i < SPICE_N_ELEMENTS(c->display_new); i++) { > > + if (c->display_new[i].display_state == > > DISPLAY_ENABLED) > > monitors += 1; > > } > > } > > @@ -1117,24 +1118,25 @@ gboolean > > spice_main_send_monitor_config(SpiceMainChannel *channel) > > > > CHANNEL_DEBUG(channel, "sending new monitors config to > > guest"); > > j = 0; > > - for (i = 0; i < SPICE_N_ELEMENTS(c->display); i++) { > > - if (c->display[i].display_state != DISPLAY_ENABLED) { > > + for (i = 0; i < SPICE_N_ELEMENTS(c->display_new); i++) { > > + if (c->display_new[i].display_state != DISPLAY_ENABLED) { > > if (spice_main_agent_test_capability(channel, > > VD_AGENT_CAP_SPARSE_MONITORS > > _CONFIG)) > > j++; > > continue; > > } > > mon->monitors[j].depth = c->display_color_depth ? > > c->display_color_depth : 32; > > - mon->monitors[j].width = c->display[i].width; > > - mon->monitors[j].height = c->display[i].height; > > - mon->monitors[j].x = c->display[i].x; > > - mon->monitors[j].y = c->display[i].y; > > + mon->monitors[j].width = c->display_new[i].width; > > + mon->monitors[j].height = c->display_new[i].height; > > + mon->monitors[j].x = c->display_new[i].x; > > + mon->monitors[j].y = c->display_new[i].y; > > CHANNEL_DEBUG(channel, "monitor #%d: %ux%u+%d+%d @ %u > > bpp", j, > > mon->monitors[j].width, mon- > > >monitors[j].height, > > mon->monitors[j].x, mon->monitors[j].y, > > mon->monitors[j].depth); > > j++; > > } > > + memcpy(c->display_current, c->display_new, MAX_DISPLAY * > > sizeof(SpiceDisplayConfig)); > > > > if (c->disable_display_align == FALSE) > > monitors_align(mon->monitors, mon->num_of_monitors); > > @@ -1469,13 +1471,23 @@ static gboolean > > any_display_has_dimensions(SpiceMainChannel *channel) > > c = channel->priv; > > > > for (i = 0; i < MAX_DISPLAY; i++) { > > - if (c->display[i].width > 0 && c->display[i].height > 0) > > + if (c->display_new[i].width > 0 && c- > > >display_new[i].height > 0) > > return TRUE; > > } > > > > return FALSE; > > } > > > > +static gboolean > > spice_monitor_configuration_changed(SpiceMainChannel > > *channel) > > +{ > > + SpiceMainChannelPrivate *c; > > + > > + g_return_val_if_fail(SPICE_IS_MAIN_CHANNEL(channel), FALSE); > > + c = channel->priv; > > + > > + return memcmp(c->display_current, c->display_new, MAX_DISPLAY > > * > > sizeof(SpiceDisplayConfig)) != 0; > > +} > > + > > /* main context*/ > > static gboolean timer_set_display(gpointer data) > > { > > @@ -1488,6 +1500,11 @@ static gboolean timer_set_display(gpointer > > data) > > if (!c->agent_connected) > > return FALSE; > > > > + if (!spice_monitor_configuration_changed(channel)) { > > + SPICE_DEBUG("Not sending monitors config, configuration > > has not > > changed"); > > + return FALSE; > > + } > > + > > if (!any_display_has_dimensions(channel)) { > > SPICE_DEBUG("Not sending monitors config, at least one > > monitor must > > have dimensions"); > > return FALSE; > > @@ -1499,7 +1516,7 @@ static gboolean timer_set_display(gpointer > > data) > > /* ensure we have an explicit monitor configuration at > > least for > > number of display channels */ > > for (i = 0; i < > > spice_session_get_n_display_channels(session); i++) > > - if (c->display[i].display_state == DISPLAY_UNDEFINED) > > { > > + if (c->display_new[i].display_state == > > DISPLAY_UNDEFINED) { > > SPICE_DEBUG("Not sending monitors config, missing > > monitors"); > > return FALSE; > > } > > @@ -2573,17 +2590,17 @@ void > > spice_main_update_display(SpiceMainChannel > > *channel, int id, > > > > c = SPICE_MAIN_CHANNEL(channel)->priv; > > > > - g_return_if_fail(id < SPICE_N_ELEMENTS(c->display)); > > + g_return_if_fail(id < SPICE_N_ELEMENTS(c->display_new)); > > > > SpiceDisplayConfig display = { > > .x = x, .y = y, .width = width, .height = height, > > - .display_state = c->display[id].display_state > > + .display_state = c->display_new[id].display_state > > }; > > > > - if (memcmp(&display, &c->display[id], > > sizeof(SpiceDisplayConfig)) == 0) > > + if (memcmp(&display, &c->display_new[id], > > sizeof(SpiceDisplayConfig)) == > > 0) > > return; > > > > - c->display[id] = display; > > + c->display_new[id] = display; > > > > if (update) > > update_display_timer(channel, 1); > > @@ -2785,14 +2802,14 @@ void > > spice_main_update_display_enabled(SpiceMainChannel *channel, int > > id, gboole > > > > if (id == -1) { > > gint i; > > - for (i = 0; i < G_N_ELEMENTS(c->display); i++) { > > - c->display[i].display_state = display_state; > > + for (i = 0; i < G_N_ELEMENTS(c->display_new); i++) { > > + c->display_new[i].display_state = display_state; > > } > > } else { > > - g_return_if_fail(id < G_N_ELEMENTS(c->display)); > > - if (c->display[id].display_state == display_state) > > + g_return_if_fail(id < G_N_ELEMENTS(c->display_new)); > > + if (c->display_new[id].display_state == display_state) > > return; > > - c->display[id].display_state = display_state; > > + c->display_new[id].display_state = display_state; > > } > > > > if (update) > > -- > > 2.10.1 > > > > _______________________________________________ > > Spice-devel mailing list > > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > > https://lists.freedesktop.org/mailman/listinfo/spice-devel > > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel