Skip to content

Commit

Permalink
Reduce cursor latency by rendering to VNC framebuf
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ndsl7109256 committed Nov 4, 2024
1 parent 9be6240 commit 68ae09c
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 1 deletion.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions backend/vnc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions configs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ comment "Logging is disabled"
config CURSOR
bool "Manipulate cursor"
default n
depends on !BACKEND_VNC

endmenu

Expand Down
2 changes: 2 additions & 0 deletions include/twin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/*
Expand Down
2 changes: 1 addition & 1 deletion src/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <stddef.h>
#include <twin.h>

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,
Expand Down

0 comments on commit 68ae09c

Please sign in to comment.