server: Drop current frame if formats change

If the currently in-flight frame was dispatched before a format change,
it might be the wrong format for the client, so it's better to drop it.
pull/110/head
Andri Yngvason 2024-02-02 22:24:01 +00:00
parent ef106b92f1
commit 9fa1027353
2 changed files with 16 additions and 0 deletions

View File

@ -108,6 +108,7 @@ struct nvnc_client {
struct encoder* tight_encoder; struct encoder* tight_encoder;
uint32_t cursor_seq; uint32_t cursor_seq;
int quality; int quality;
bool formats_changed;
#ifdef HAVE_CRYPTO #ifdef HAVE_CRYPTO
struct crypto_key* apple_dh_secret; struct crypto_key* apple_dh_secret;

View File

@ -938,6 +938,7 @@ static int on_client_set_pixel_format(struct nvnc_client* client)
memcpy(&client->pixfmt, fmt, sizeof(client->pixfmt)); memcpy(&client->pixfmt, fmt, sizeof(client->pixfmt));
client->has_pixfmt = true; client->has_pixfmt = true;
client->formats_changed = true;
nvnc_log(NVNC_LOG_DEBUG, "Client %p chose pixel format: %s", client, nvnc_log(NVNC_LOG_DEBUG, "Client %p chose pixel format: %s", client,
rfb_pixfmt_to_string(fmt)); rfb_pixfmt_to_string(fmt));
@ -1007,6 +1008,7 @@ static int on_client_set_encodings(struct nvnc_client* client)
encoding_list); encoding_list);
client->n_encodings = n; client->n_encodings = n;
client->formats_changed = true;
return sizeof(*msg) + 4 * n_encodings; return sizeof(*msg) + 4 * n_encodings;
} }
@ -1186,6 +1188,7 @@ static void process_fb_update_requests(struct nvnc_client* client)
pixman_region_init(&client->damage); pixman_region_init(&client->damage);
client->is_updating = true; client->is_updating = true;
client->formats_changed = false;
client->current_fb = fb; client->current_fb = fb;
nvnc_fb_hold(fb); nvnc_fb_hold(fb);
nvnc_fb_ref(fb); nvnc_fb_ref(fb);
@ -1207,6 +1210,7 @@ static void process_fb_update_requests(struct nvnc_client* client)
nvnc_log(NVNC_LOG_ERROR, "Failed to encode current frame"); nvnc_log(NVNC_LOG_ERROR, "Failed to encode current frame");
client_unref(client); client_unref(client);
client->is_updating = false; client->is_updating = false;
client->formats_changed = false;
assert(client->current_fb); assert(client->current_fb);
nvnc_fb_release(client->current_fb); nvnc_fb_release(client->current_fb);
nvnc_fb_unref(client->current_fb); nvnc_fb_unref(client->current_fb);
@ -2105,6 +2109,17 @@ static void finish_fb_update(struct nvnc_client* client, struct rcbuf* payload,
if (client->net_stream->state == STREAM_STATE_CLOSED) if (client->net_stream->state == STREAM_STATE_CLOSED)
goto complete; goto complete;
if (client->formats_changed) {
/* Client has requested new pixel format or encoding in the
* meantime, so it probably won't know what to do with this
* frame. Pending requests get incremented because this one is
* dropped.
*/
nvnc_log(NVNC_LOG_DEBUG, "Client changed pixel format or encoding with in-flight buffer");
client->n_pending_requests++;
goto complete;
}
DTRACE_PROBE2(neatvnc, send_fb_start, client, pts); DTRACE_PROBE2(neatvnc, send_fb_start, client, pts);
n_rects += will_send_pts(client, pts) ? 1 : 0; n_rects += will_send_pts(client, pts) ? 1 : 0;
struct rfb_server_fb_update_msg update_msg = { struct rfb_server_fb_update_msg update_msg = {