From 3a61b8dbb613b2a5917d548f525490d8268f374e Mon Sep 17 00:00:00 2001 From: "ndsl7109256@gmail.com" Date: Tue, 24 Dec 2024 16:13:03 +0800 Subject: [PATCH] Optimize VNC screen update to reduce delays Previously, the VNC renderer fed the damaged region to the buffer line by line, resulting in significant rendering delays due to frequent buffer updates. The implementation has been optimized to aggregate all updates during the current screen refresh cycle. The buffer is now updated once per refresh with the complete damaged region, reducing rendering delays and preventing screen tearing. Close #81 --- backend/vnc.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/backend/vnc.c b/backend/vnc.c index 1b2ec22..d5dfbd8 100644 --- a/backend/vnc.c +++ b/backend/vnc.c @@ -75,16 +75,8 @@ static void _twin_vnc_put_span(twin_coord_t left, size_t span_width = right - left; memcpy(fb_pixels, pixels, span_width * sizeof(*fb_pixels)); - - pixman_region_init_rect(&tx->damage_region, left, top, span_width, 1); - - if (pixman_region_not_empty(&tx->damage_region)) { - nvnc_display_feed_buffer(tx->display, tx->current_fb, - &tx->damage_region); - pixman_region_clear(&tx->damage_region); - } - aml_poll(tx->aml, 0); - aml_dispatch(tx->aml); + pixman_region_union_rect(&tx->damage_region, &tx->damage_region, left, top, + span_width, 1); } static void twin_vnc_get_screen_size(twin_vnc_t *tx, int *width, int *height) @@ -96,9 +88,13 @@ static void twin_vnc_get_screen_size(twin_vnc_t *tx, int *width, int *height) static bool _twin_vnc_work(void *closure) { twin_screen_t *screen = SCREEN(closure); - - if (twin_screen_damaged(screen)) + twin_vnc_t *tx = PRIV(closure); + if (twin_screen_damaged(screen)) { + pixman_region_clear(&tx->damage_region); twin_screen_update(screen); + nvnc_display_feed_buffer(tx->display, tx->current_fb, + &tx->damage_region); + } return true; } @@ -262,6 +258,14 @@ twin_context_t *twin_vnc_init(int width, int height) return NULL; } +static bool twin_vnc_poll(twin_context_t *ctx) +{ + twin_vnc_t *tx = PRIV(ctx); + aml_poll(tx->aml, 0); + aml_dispatch(tx->aml); + return true; +} + static void twin_vnc_configure(twin_context_t *ctx) { int width, height; @@ -288,6 +292,7 @@ static void twin_vnc_exit(twin_context_t *ctx) const twin_backend_t g_twin_backend = { .init = twin_vnc_init, + .poll = twin_vnc_poll, .configure = twin_vnc_configure, .exit = twin_vnc_exit, };