From 16d454784cc5b79aee6a300ce5337d1d05634c39 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 27 Sep 2024 18:20:27 -0700 Subject: [PATCH] GUACAMOLE-377: Migrate VNC to default render loop. --- src/protocols/vnc/cursor.c | 1 + src/protocols/vnc/display.c | 2 ++ src/protocols/vnc/vnc.c | 44 +++++++++++-------------------------- src/protocols/vnc/vnc.h | 6 +++++ 4 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/protocols/vnc/cursor.c b/src/protocols/vnc/cursor.c index 7a1bc1518..079ddd36f 100644 --- a/src/protocols/vnc/cursor.c +++ b/src/protocols/vnc/cursor.c @@ -114,6 +114,7 @@ void guac_vnc_cursor(rfbClient* client, int x, int y, int w, int h, int vnc_bpp) /* Draw operation is now complete */ guac_display_layer_close_raw(cursor_layer, context); + guac_display_render_thread_notify_modified(vnc_client->render_thread); /* libvncclient does not free rcMask as it does rcSource */ if (client->rcMask != NULL) { diff --git a/src/protocols/vnc/display.c b/src/protocols/vnc/display.c index 70b03be8a..8b09f8b6e 100644 --- a/src/protocols/vnc/display.c +++ b/src/protocols/vnc/display.c @@ -129,6 +129,8 @@ void guac_vnc_update(rfbClient* client, int x, int y, int w, int h) { vnc_client->copy_rect_used = 0; } + guac_display_render_thread_notify_modified(vnc_client->render_thread); + } void guac_vnc_copyrect(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) { diff --git a/src/protocols/vnc/vnc.c b/src/protocols/vnc/vnc.c index cdd21bd63..a87d98f57 100644 --- a/src/protocols/vnc/vnc.c +++ b/src/protocols/vnc/vnc.c @@ -596,6 +596,8 @@ void* guac_vnc_client_thread(void* data) { guac_display_end_frame(vnc_client->display); + vnc_client->render_thread = guac_display_render_thread_create(vnc_client->display); + /* Handle messages from VNC server while client is running */ while (client->state == GUAC_CLIENT_RUNNING) { @@ -603,37 +605,13 @@ void* guac_vnc_client_thread(void* data) { int wait_result = guac_vnc_wait_for_messages(rfb_client, GUAC_VNC_FRAME_START_TIMEOUT); if (wait_result > 0) { - /* Read server messages until frame is built */ - guac_timestamp frame_start = guac_timestamp_current(); - do { - - /* Handle any message received */ - if (!guac_vnc_handle_messages(vnc_client)) { - guac_client_abort(client, - GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, - "Error handling message from VNC server."); - break; - } - - int frame_duration = guac_timestamp_current() - frame_start; - - /* Continue processing messages for up to a reasonable minimum - * framerate without an explicit frame boundary indicating that - * the frame is not yet complete */ - if (frame_duration > GUAC_VNC_MAX_FRAME_DURATION) - break; - - /* Do not exceed a reasonable maximum framerate without an - * explicit frame boundary terminating the frame early */ - int allowed_wait = GUAC_VNC_MIN_FRAME_DURATION - frame_duration; - if (allowed_wait < 0) - allowed_wait = 0; - - wait_result = guac_vnc_wait_for_messages(rfb_client, allowed_wait); - - } while (wait_result > 0); - - guac_display_end_frame(vnc_client->display); + /* Handle any message received */ + if (!guac_vnc_handle_messages(vnc_client)) { + guac_client_abort(client, + GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, + "Error handling message from VNC server."); + break; + } } @@ -643,6 +621,10 @@ void* guac_vnc_client_thread(void* data) { } + /* Stop render loop */ + guac_display_render_thread_destroy(vnc_client->render_thread); + vnc_client->render_thread = NULL; + /* Kill client and finish connection */ guac_client_stop(client); guac_client_log(client, GUAC_LOG_INFO, "Internal VNC client disconnected"); diff --git a/src/protocols/vnc/vnc.h b/src/protocols/vnc/vnc.h index 7e5676af8..6b83d41d0 100644 --- a/src/protocols/vnc/vnc.h +++ b/src/protocols/vnc/vnc.h @@ -113,6 +113,12 @@ typedef struct guac_vnc_client { */ guac_display_layer_raw_context* current_context; + /** + * The current instance of the guac_display render thread. If the thread + * has not yet been started, this will be NULL. + */ + guac_display_render_thread* render_thread; + /** * Internal clipboard. */