add more debug functionalities
This commit is contained in:
parent
50b6435aa7
commit
f3465fe871
3 changed files with 62 additions and 20 deletions
18
drm.c
18
drm.c
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
56
kmsvnc.c
56
kmsvnc.c
|
@ -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);
|
||||||
|
|
8
kmsvnc.h
8
kmsvnc.h
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue