add more debug functionalities

This commit is contained in:
JerryXiao 2023-04-28 14:13:46 +08:00
parent 50b6435aa7
commit f3465fe871
Signed by: Jerry
GPG key ID: 22618F758B5BE2E5
3 changed files with 62 additions and 20 deletions

18
drm.c
View file

@ -130,6 +130,10 @@ void drm_cleanup() {
close(kmsvnc->drm->drm_fd); close(kmsvnc->drm->drm_fd);
kmsvnc->drm->drm_fd = 0; kmsvnc->drm->drm_fd = 0;
} }
if (kmsvnc->drm->plane_res) {
drmModeFreePlaneResources(kmsvnc->drm->plane_res);
kmsvnc->drm->plane_res = NULL;
}
free(kmsvnc->drm); free(kmsvnc->drm);
kmsvnc->drm = NULL; kmsvnc->drm = NULL;
} }
@ -153,13 +157,13 @@ int drm_open() {
{ {
perror("Failed to set universal planes capability: primary planes will not be usable"); perror("Failed to set universal planes capability: primary planes will not be usable");
} }
if (drm->source_plane > 0) if (kmsvnc->source_plane > 0)
{ {
drm->plane = drmModeGetPlane(drm->drm_fd, drm->source_plane); drm->plane = drmModeGetPlane(drm->drm_fd, kmsvnc->source_plane);
if (!drm->plane) if (!drm->plane)
DRM_FATAL("Failed to get plane %d: %s\n", drm->source_plane, strerror(errno)); DRM_FATAL("Failed to get plane %d: %s\n", kmsvnc->source_plane, strerror(errno));
if (drm->plane->fb_id == 0) if (drm->plane->fb_id == 0)
fprintf(stderr, "Place %d does not have an attached framebuffer\n", drm->source_plane); fprintf(stderr, "Place %d does not have an attached framebuffer\n", kmsvnc->source_plane);
} }
else else
{ {
@ -176,7 +180,7 @@ int drm_open() {
continue; continue;
} }
printf("Plane %u CRTC %u FB %u\n", drm->plane->plane_id, drm->plane->crtc_id, drm->plane->fb_id); printf("Plane %u CRTC %u FB %u\n", drm->plane->plane_id, drm->plane->crtc_id, drm->plane->fb_id);
if ((drm->source_crtc > 0 && drm->plane->crtc_id != drm->source_crtc) || drm->plane->fb_id == 0) if ((kmsvnc->source_crtc != 0 && drm->plane->crtc_id != kmsvnc->source_crtc) || drm->plane->fb_id == 0)
{ {
// Either not connected to the target source CRTC // Either not connected to the target source CRTC
// or not active. // or not active.
@ -188,9 +192,9 @@ int drm_open() {
} }
if (i == drm->plane_res->count_planes) if (i == drm->plane_res->count_planes)
{ {
if (drm->source_crtc > 0) if (kmsvnc->source_crtc != 0)
{ {
DRM_FATAL("No usable planes found on CRTC %d\n", drm->source_crtc); DRM_FATAL("No usable planes found on CRTC %d\n", kmsvnc->source_crtc);
} }
else else
{ {

View file

@ -49,7 +49,7 @@ static void update_screen_buf(char* to, char *from, int width, int height) {
int min_y = INT32_MAX; int min_y = INT32_MAX;
int max_x = -1; int max_x = -1;
int max_y = -1; int max_y = -1;
if (width % 2 == 0) { if (!kmsvnc->vnc_opt->disable_cmpfb && width % 2 == 0) {
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x+=2) { for (int x = 0; x < width; x+=2) {
if (*double_pix_from != *double_pix_to) { if (*double_pix_from != *double_pix_to) {
@ -71,6 +71,11 @@ static void update_screen_buf(char* to, char *from, int width, int height) {
} }
} }
} }
else {
memcpy(to, from, width * height * BYTES_PER_PIXEL);
rfbMarkRectAsModified(kmsvnc->server, 0, 0, width, height);
return;
}
max_x = max_x < 0 ? 0 : max_x; max_x = max_x < 0 ? 0 : max_x;
max_y = max_y < 0 ? 0 : max_y; max_y = max_y < 0 ? 0 : max_y;
min_x = min_x > width ? 0 : min_x; min_x = min_x > width ? 0 : min_x;
@ -79,7 +84,7 @@ static void update_screen_buf(char* to, char *from, int width, int height) {
//printf("dirty: %d, %d, %d, %d\n", min_x, min_y, max_x, max_y); //printf("dirty: %d, %d, %d, %d\n", min_x, min_y, max_x, max_y);
if (max_x || max_y || min_x || min_y) { if (max_x || max_y || min_x || min_y) {
memcpy(to, from, width * height * BYTES_PER_PIXEL); memcpy(to, from, width * height * BYTES_PER_PIXEL);
rfbMarkRectAsModified(kmsvnc->server, min_x, min_y, max_x, max_y); rfbMarkRectAsModified(kmsvnc->server, min_x, min_y, max_x + 2, max_y + 1);
} }
} }
@ -123,13 +128,17 @@ void signal_handler(int signum){
static struct argp_option kmsvnc_main_options[] = { static struct argp_option kmsvnc_main_options[] = {
{"device", 'd', "/dev/dri/card0", 0, "DRM device"}, {"device", 'd', "/dev/dri/card0", 0, "DRM device"},
{"force-driver", 0xfefe, "i915", 0, "force a certain driver (for debug)"}, {"source-plane", 0xfefc, "0", 0, "Use specific plane"},
{"source-crtc", 0xfefd, "0", 0, "Use specific crtc (to list all crtcs and planes, set this to -1)"},
{"force-driver", 0xfefe, "i915", 0, "force a certain driver (for debugging)"},
{"bind", 'b', "0.0.0.0", 0, "Listen on (ipv4 address)"}, {"bind", 'b', "0.0.0.0", 0, "Listen on (ipv4 address)"},
{"bind6", 0xfeff, "::", 0, "Listen on (ipv6 address)"}, {"bind6", 0xfeff, "::", 0, "Listen on (ipv6 address)"},
{"port", 'p', "5900", 0, "Listen port"}, {"port", 'p', "5900", 0, "Listen port"},
{"disable-ipv6", '4', 0, OPTION_ARG_OPTIONAL, "Disable ipv6"}, {"disable-ipv6", '4', 0, OPTION_ARG_OPTIONAL, "Disable ipv6"},
{"fps", 0xff00, "30", 0, "Target frames per second"}, {"fps", 0xff00, "30", 0, "Target frames per second"},
{"disable-always-shared", 0xff01, 0, OPTION_ARG_OPTIONAL, "Do not always treat incoming connections as shared"}, {"disable-always-shared", 0xff01, 0, OPTION_ARG_OPTIONAL, "Do not always treat incoming connections as shared"},
{"disable-compare-fb", 0xff02, 0, OPTION_ARG_OPTIONAL, "Do not compare pixels"},
{"capture-raw-fb", 0xff03, "/tmp/rawfb.bin", 0, "Capture RAW framebuffer instead of starting the vnc server (for debugging)"},
{"disable-input", 'i', 0, OPTION_ARG_OPTIONAL, "Disable uinput"}, {"disable-input", 'i', 0, OPTION_ARG_OPTIONAL, "Disable uinput"},
{"desktop-name", 'n', "kmsvnc", 0, "Specify vnc desktop name"}, {"desktop-name", 'n', "kmsvnc", 0, "Specify vnc desktop name"},
{0} {0}
@ -142,6 +151,12 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
case 'd': case 'd':
kmsvnc->card = arg; kmsvnc->card = arg;
break; break;
case 0xfefc:
kmsvnc->source_plane = atoi(arg);
break;
case 0xfefd:
kmsvnc->source_crtc = atoi(arg);
break;
case 0xfefe: case 0xfefe:
kmsvnc->force_driver = arg; kmsvnc->force_driver = arg;
break; break;
@ -177,6 +192,13 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
case 0xff01: case 0xff01:
kmsvnc->vnc_opt->always_shared = 0; kmsvnc->vnc_opt->always_shared = 0;
break; break;
case 0xff02:
kmsvnc->vnc_opt->disable_cmpfb = 1;
break;
case 0xff03:
kmsvnc->debug_capture_fb = arg;
kmsvnc->disable_input = 1;
break;
case 'i': case 'i':
kmsvnc->disable_input = 1; kmsvnc->disable_input = 1;
break; break;
@ -214,14 +236,14 @@ int main(int argc, char **argv)
struct argp argp = {kmsvnc_main_options, parse_opt, args_doc, doc}; struct argp argp = {kmsvnc_main_options, parse_opt, args_doc, doc};
argp_parse(&argp, argc, argv, 0, 0, NULL); argp_parse(&argp, argc, argv, 0, 0, NULL);
const char* XKB_DEFAULT_LAYOUT = getenv("XKB_DEFAULT_LAYOUT");
if (!XKB_DEFAULT_LAYOUT || strcmp(XKB_DEFAULT_LAYOUT, "") == 0) {
printf("No keyboard layout set from environment variables, use US layout by default\n");
printf("See https://xkbcommon.org/doc/current/structxkb__rule__names.html\n");
setenv("XKB_DEFAULT_LAYOUT", "us", 1);
}
if (!kmsvnc->disable_input) { if (!kmsvnc->disable_input) {
const char* XKB_DEFAULT_LAYOUT = getenv("XKB_DEFAULT_LAYOUT");
if (!XKB_DEFAULT_LAYOUT || strcmp(XKB_DEFAULT_LAYOUT, "") == 0) {
printf("No keyboard layout set from environment variables, use US layout by default\n");
printf("See https://xkbcommon.org/doc/current/structxkb__rule__names.html\n");
setenv("XKB_DEFAULT_LAYOUT", "us", 1);
}
if (xkb_init()) { if (xkb_init()) {
cleanup(); cleanup();
return 1; return 1;
@ -236,6 +258,20 @@ int main(int argc, char **argv)
return 1; return 1;
} }
if (kmsvnc->debug_capture_fb) {
int wfd = open(kmsvnc->debug_capture_fb, O_WRONLY | O_CREAT, 00644);
if (wfd > 0) {
write(wfd, kmsvnc->drm->mapped, kmsvnc->drm->mfb->width * kmsvnc->drm->mfb->height * BYTES_PER_PIXEL);
fsync(wfd);
printf("wrote raw frame buffer to %s\n", kmsvnc->debug_capture_fb);
}
else {
fprintf(stderr, "open file %s failed, %s\n", kmsvnc->debug_capture_fb, strerror(errno));
}
cleanup();
return 0;
}
size_t buflen = kmsvnc->drm->mfb->width * kmsvnc->drm->mfb->height * BYTES_PER_PIXEL; size_t buflen = kmsvnc->drm->mfb->width * kmsvnc->drm->mfb->height * BYTES_PER_PIXEL;
kmsvnc->buf = malloc(buflen); kmsvnc->buf = malloc(buflen);
memset(kmsvnc->buf, 0, buflen); memset(kmsvnc->buf, 0, buflen);

View file

@ -19,16 +19,20 @@ struct vnc_opt
char *bind6; char *bind6;
char disable_ipv6; char disable_ipv6;
int sleep_ns; int sleep_ns;
int always_shared; char always_shared;
char disable_cmpfb;
char *desktop_name; char *desktop_name;
}; };
struct kmsvnc_data struct kmsvnc_data
{ {
char *debug_capture_fb;
char *card; char *card;
char *force_driver; char *force_driver;
struct vnc_opt *vnc_opt; struct vnc_opt *vnc_opt;
char disable_input; char disable_input;
int source_plane;
int source_crtc;
struct kmsvnc_drm_data *drm; struct kmsvnc_drm_data *drm;
struct kmsvnc_input_data *input; struct kmsvnc_input_data *input;
struct kmsvnc_keymap_data *keymap; struct kmsvnc_keymap_data *keymap;
@ -73,8 +77,6 @@ struct kmsvnc_drm_data
int drm_fd; int drm_fd;
drmVersionPtr drm_ver; drmVersionPtr drm_ver;
int prime_fd; int prime_fd;
int source_plane;
int source_crtc;
drmModePlane *plane; drmModePlane *plane;
drmModePlaneRes *plane_res; drmModePlaneRes *plane_res;
drmModeFB2 *mfb; drmModeFB2 *mfb;