From 68ae09c5631290da66865d7afd4c9631acaacbf0 Mon Sep 17 00:00:00 2001 From: "ndsl7109256@gmail.com" Date: Fri, 1 Nov 2024 16:36:23 +0800 Subject: [PATCH] Reduce cursor latency by rendering to VNC framebuf Previously, cursor movement was handled by passing pointer events into twin screen, and then calculated the damage region for the cursor's new position and transmitted it to the VNC framebuffer. This process introduced latency in cursor display due to the multiple steps involved. To address this delay, the cursor is now rendered directly within the VNC framebuffer by leveraging neatvnc's internal cursor API. This change bypasses the intermediate steps and provides a smoother and more responsive cursor movement experience in the VNC backend. --- Makefile | 1 + backend/vnc.c | 22 ++++++++++++++++++++++ configs/Kconfig | 1 + include/twin.h | 2 ++ src/cursor.c | 2 +- 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5bfab3d..10e9ae1 100644 --- a/Makefile +++ b/Makefile @@ -113,6 +113,7 @@ endif ifeq ($(CONFIG_BACKEND_VNC), y) BACKEND = vnc libtwin.a_files-y += backend/vnc.c +libtwin.a_files-y += src/cursor.c libtwin.a_cflags-y += $(shell pkg-config --cflags neatvnc aml pixman-1) TARGET_LIBS += $(shell pkg-config --libs neatvnc aml pixman-1) endif diff --git a/backend/vnc.c b/backend/vnc.c index 997e609..0246571 100644 --- a/backend/vnc.c +++ b/backend/vnc.c @@ -47,6 +47,9 @@ typedef struct { enum nvnc_button_mask prev_button; } twin_peer_t; +#define CURSOR_WIDTH 14 +#define CURSOR_HEIGHT 20 + static void _twin_vnc_put_begin(twin_coord_t left, twin_coord_t top, twin_coord_t right, @@ -147,6 +150,21 @@ static void _twin_vnc_pointer_event(struct nvnc_client *client, twin_screen_dispatch(tx->screen, &tev); } +static struct nvnc_fb *_twin_vnc_create_cursor() +{ + struct nvnc_fb *fb = nvnc_fb_new(CURSOR_WIDTH, CURSOR_HEIGHT, + DRM_FORMAT_ARGB8888, CURSOR_WIDTH); + uint32_t *pixels = nvnc_fb_get_addr(fb); + for (int i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++) { + uint32_t a = _twin_cursor_default[i * 4]; + uint32_t r = _twin_cursor_default[i * 4 + 1]; + uint32_t g = _twin_cursor_default[i * 4 + 2]; + uint32_t b = _twin_cursor_default[i * 4 + 3]; + pixels[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + return fb; +} + twin_context_t *twin_vnc_init(int width, int height) { twin_context_t *ctx = calloc(1, sizeof(twin_context_t)); @@ -200,6 +218,10 @@ twin_context_t *twin_vnc_init(int width, int height) nvnc_set_pointer_fn(tx->server, _twin_vnc_pointer_event); nvnc_set_new_client_fn(tx->server, _twin_vnc_new_client); nvnc_set_userdata(tx->server, tx, NULL); + struct nvnc_fb *cursor = _twin_vnc_create_cursor(); + nvnc_set_cursor(tx->server, cursor, CURSOR_WIDTH, CURSOR_HEIGHT, 0, 0, + true); + nvnc_fb_unref(cursor); ctx->screen = twin_screen_create(width, height, _twin_vnc_put_begin, _twin_vnc_put_span, ctx); diff --git a/configs/Kconfig b/configs/Kconfig index 7166f2f..20b173c 100644 --- a/configs/Kconfig +++ b/configs/Kconfig @@ -41,6 +41,7 @@ comment "Logging is disabled" config CURSOR bool "Manipulate cursor" default n + depends on !BACKEND_VNC endmenu diff --git a/include/twin.h b/include/twin.h index 356ccaa..ae8fa06 100644 --- a/include/twin.h +++ b/include/twin.h @@ -613,6 +613,8 @@ void twin_path_convolve(twin_path_t *dest, * cursor.c */ +extern const uint8_t _twin_cursor_default[]; + twin_pixmap_t *twin_make_cursor(int *hx, int *hy); /* diff --git a/src/cursor.c b/src/cursor.c index dcfe8b6..f8ba085 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -9,7 +9,7 @@ #include #include -static const uint8_t _twin_cursor_default[] = { +const uint8_t _twin_cursor_default[] = { 0x19, 0x19, 0x19, 0xb8, 0x1e, 0x1e, 0x1e, 0xc8, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,