Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:X0F
kmscon_fork
kmscon_PR71.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File kmscon_PR71.patch of Package kmscon_fork
From 41166aebe9cd2b83bbb57c629197a73a32583c32 Mon Sep 17 00:00:00 2001 From: Skyler Ferris <skyvine@protonmail.com> Date: Mon, 5 Jun 2023 13:01:53 -0700 Subject: [PATCH 1/2] Add arguments to set the desired resolution. This adds the --desired-width and --desired-height arguments which tell kmscon what resolution the user *desires*. They are specifically called desired because it is not guaranteed that this resolution will be used: it will only work if the exact width and height match a supported mode as reported by the system, and it will only work in DRM mode (kmscon does not generally support modesetting in fbdev). Additionally, it might not be possible to use the mode if there is not enough memory to store the framebuffers. Using `video=<width>x<height>` on the kernel's command line was enough to make sure that sufficient memory was available on my machine. In this case, if we try to use the desired mode then the user will be presented with a blank screen. In either of the above cases, kmscon will revert to using the default mode, which is what kmscon always uses prior to this patch. --- docs/man/kmscon.1.xml.in | 21 +++++++++++++++++++++ src/kmscon_conf.c | 21 +++++++++++++++------ src/kmscon_conf.h | 3 +++ src/kmscon_main.c | 7 +++++-- src/kmscon_terminal.c | 10 ++++++++++ src/uterm_drm_shared.c | 23 +++++++++++++++++++++++ src/uterm_video.c | 8 ++++++-- src/uterm_video.h | 3 ++- src/uterm_video_internal.h | 4 ++++ tests/test_output.c | 12 ++++++++++-- 10 files changed, 99 insertions(+), 13 deletions(-) diff --git a/docs/man/kmscon.1.xml.in b/docs/man/kmscon.1.xml.in index c6ddb0f0..a2f17c5d 100644 --- a/docs/man/kmscon.1.xml.in +++ b/docs/man/kmscon.1.xml.in @@ -482,6 +482,27 @@ only be used to debug render engines. (default: off)</para> </listitem> </varlistentry> + + <varlistentry> + <term><option>--desired-width {pixels}</option></term> + <term><option>--desired-height {pixels}</option></term> + <listitem> + <para>Set the desired width and height of the output. The given width + and height must match a supported more exactly for this option to have + any effect; if there is no supported mode that matches exactly, or if there is + an error when using the desired mode, then the default mode (first valid mode + found) will be used.</para> + + <para>Modesetting is only supported in DRM mode, so these options do + nothing with fbdev. However, fbset can still be used to externally set + the mode when fbdev is in use.</para> + + <para>Other system components may need configuration in order to use the desired + mode effectively. For example, the `video={width}x{height}` kernel parameter may + be required in order to ensure that there is enough memory to store the + framebuffers for a large resolution.</para> + </listitem> + </varlistentry> </variablelist> <para>Font Options:</para> diff --git a/src/kmscon_conf.c b/src/kmscon_conf.c index 2f3b1519..09e5f432 100644 --- a/src/kmscon_conf.c +++ b/src/kmscon_conf.c @@ -136,12 +136,19 @@ static void print_help() "\t Create new terminal session\n" "\n" "Video Options:\n" - "\t --drm [on] Use DRM if available\n" - "\t --hwaccel [off] Use 3D hardware-acceleration if\n" - "\t available\n" - "\t --gpus={all,aux,primary}[all] GPU selection mode\n" - "\t --render-engine <eng> [-] Console renderer\n" - "\t --render-timing [off] Print renderer timing information\n" + "\t --drm [on] Use DRM if available\n" + "\t --hwaccel [off] Use 3D hardware-acceleration if\n" + "\t available\n" + "\t --gpus={all,aux,primary} [all] GPU selection mode\n" + "\t --render-engine <eng> [-] Console renderer\n" + "\t --render-timing [off] Print renderer timing information\n" + "\t --desired-width <pixels> [0]\n" + "\t --desired-height <pixels> [0] Set the desired width/height of\n" + "\t the output. If the desired mode\n" + "\t is not available or encounters an\n" + "\t error, a default mode will be\n" + "\t used. See the man page for\n" + "\t additional details.\n" "\n" "Font Options:\n" "\t --font-engine <engine> [pango]\n" @@ -734,6 +741,8 @@ int kmscon_conf_new(struct conf_ctx **out) CONF_OPTION_BOOL(0, "hwaccel", &conf->hwaccel, false), CONF_OPTION(0, 0, "gpus", &conf_gpus, NULL, NULL, NULL, &conf->gpus, KMSCON_GPU_ALL), CONF_OPTION_STRING(0, "render-engine", &conf->render_engine, NULL), + CONF_OPTION_UINT(0, "desired-width", &conf->desired_width, 0), + CONF_OPTION_UINT(0, "desired-height", &conf->desired_height, 0), /* Font Options */ CONF_OPTION_STRING(0, "font-engine", &conf->font_engine, "pango"), diff --git a/src/kmscon_conf.h b/src/kmscon_conf.h index 9ae9ecff..580ba8aa 100644 --- a/src/kmscon_conf.h +++ b/src/kmscon_conf.h @@ -145,6 +145,9 @@ struct kmscon_conf_t { unsigned int gpus; /* render engine */ char *render_engine; + /* screen resolution */ + unsigned int desired_width; + unsigned int desired_height; /* Font Options */ /* font engine */ diff --git a/src/kmscon_main.c b/src/kmscon_main.c index cc7f3edc..9020559b 100644 --- a/src/kmscon_main.c +++ b/src/kmscon_main.c @@ -367,13 +367,16 @@ static int app_seat_add_video(struct app_seat *seat, mode = UTERM_VIDEO_FBDEV; } - ret = uterm_video_new(&vid->video, seat->app->eloop, node, mode); + ret = uterm_video_new(&vid->video, seat->app->eloop, node, mode, + seat->conf->desired_width, seat->conf->desired_height); if (ret) { if (mode == UTERM_VIDEO_DRM3D) { log_info("cannot create drm3d device %s on seat %s (%d); trying drm2d mode", vid->node, seat->name, ret); ret = uterm_video_new(&vid->video, seat->app->eloop, - node, UTERM_VIDEO_DRM2D); + node, UTERM_VIDEO_DRM2D, + seat->conf->desired_width, + seat->conf->desired_height); if (ret) goto err_node; } else { diff --git a/src/kmscon_terminal.c b/src/kmscon_terminal.c index 508bd971..ab17f715 100644 --- a/src/kmscon_terminal.c +++ b/src/kmscon_terminal.c @@ -114,6 +114,8 @@ static void do_clear_margins(struct screen *scr) sw, dh); } +static int font_set(struct kmscon_terminal *term); + static void do_redraw_screen(struct screen *scr) { int ret; @@ -129,6 +131,14 @@ static void do_redraw_screen(struct screen *scr) kmscon_text_render(scr->txt); ret = uterm_display_swap(scr->disp, false); + + if (ret == -EAGAIN) { + uterm_display_deactivate(scr->disp); + uterm_display_activate(scr->disp, NULL); + font_set(scr->term); + ret = uterm_display_swap(scr->disp, false); + } + if (ret) { log_warning("cannot swap display %p", scr->disp); return; diff --git a/src/uterm_drm_shared.c b/src/uterm_drm_shared.c index ec486ab4..de1b4c3b 100644 --- a/src/uterm_drm_shared.c +++ b/src/uterm_drm_shared.c @@ -362,6 +362,11 @@ int uterm_drm_display_swap(struct uterm_display *disp, uint32_t fb, ret = drmModePageFlip(vdrm->fd, ddrm->crtc_id, fb, DRM_MODE_PAGE_FLIP_EVENT, disp); if (ret) { + if (disp->desired_mode != disp->default_mode) { + disp->desired_mode = disp->default_mode; + log_debug("Unable to page-flip desired mode! Switching to default mode."); + return -EAGAIN; + } log_error("cannot page-flip on DRM-CRTC (%d): %m", errno); return -EFAULT; @@ -616,9 +621,27 @@ static void bind_display(struct uterm_video *video, drmModeRes *res, if (!disp->default_mode) disp->default_mode = mode; + if (video->desired_width != 0 && + video->desired_height != 0 && + mode->ops->get_width(mode) == video->desired_width && + mode->ops->get_height(mode) == video->desired_height) + disp->desired_mode = mode; + uterm_mode_unref(mode); } + if (!disp->desired_mode) { + disp->desired_mode = disp->default_mode; + } + + log_debug("Default mode %dx%d", + disp->default_mode->ops->get_width(disp->default_mode), + disp->default_mode->ops->get_height(disp->default_mode)); + + log_debug("Desired mode %dx%d", + disp->desired_mode->ops->get_width(disp->desired_mode), + disp->desired_mode->ops->get_height(disp->desired_mode)); + if (shl_dlist_empty(&disp->modes)) { log_warn("no valid mode for display found"); ret = -EFAULT; diff --git a/src/uterm_video.c b/src/uterm_video.c index 0323ecfa..cdea650d 100644 --- a/src/uterm_video.c +++ b/src/uterm_video.c @@ -410,7 +410,7 @@ int uterm_display_activate(struct uterm_display *disp, struct uterm_mode *mode) return -EINVAL; if (!mode) - mode = disp->default_mode; + mode = disp->desired_mode; return VIDEO_CALL(disp->ops->activate, 0, disp, mode); } @@ -544,7 +544,8 @@ int uterm_display_fake_blendv(struct uterm_display *disp, SHL_EXPORT int uterm_video_new(struct uterm_video **out, struct ev_eloop *eloop, - const char *node, const struct uterm_video_module *mod) + const char *node, const struct uterm_video_module *mod, + unsigned int desired_width, unsigned int desired_height) { struct uterm_video *video; int ret; @@ -572,6 +573,9 @@ int uterm_video_new(struct uterm_video **out, struct ev_eloop *eloop, if (ret) goto err_hook; + video->desired_width = desired_width; + video->desired_height = desired_height; + ev_eloop_ref(video->eloop); log_info("new device %p", video); *out = video; diff --git a/src/uterm_video.h b/src/uterm_video.h index fe3cb787..53120f07 100644 --- a/src/uterm_video.h +++ b/src/uterm_video.h @@ -192,7 +192,8 @@ int uterm_display_fake_blendv(struct uterm_display *disp, /* video interface */ int uterm_video_new(struct uterm_video **out, struct ev_eloop *eloop, - const char *node, const struct uterm_video_module *mod); + const char *node, const struct uterm_video_module *mod, + unsigned int desired_width, unsigned int desired_height); void uterm_video_ref(struct uterm_video *video); void uterm_video_unref(struct uterm_video *video); diff --git a/src/uterm_video_internal.h b/src/uterm_video_internal.h index e2c9d954..1ad786f6 100644 --- a/src/uterm_video_internal.h +++ b/src/uterm_video_internal.h @@ -118,6 +118,7 @@ struct uterm_display { struct shl_hook *hook; struct shl_dlist modes; struct uterm_mode *default_mode; + struct uterm_mode *desired_mode; struct uterm_mode *current_mode; int dpms; @@ -159,6 +160,9 @@ struct uterm_video { struct shl_dlist displays; struct shl_hook *hook; + unsigned int desired_width; + unsigned int desired_height; + const struct uterm_video_module *mod; const struct video_ops *ops; void *data; diff --git a/tests/test_output.c b/tests/test_output.c index 830720e5..204b23c4 100644 --- a/tests/test_output.c +++ b/tests/test_output.c @@ -58,6 +58,8 @@ struct { bool fbdev; bool test; char *dev; + unsigned int desired_width; + unsigned int desired_height; } output_conf; static int blit_outputs(struct uterm_video *video) @@ -187,6 +189,8 @@ struct conf_option options[] = { CONF_OPTION_BOOL(0, "fbdev", &output_conf.fbdev, false), CONF_OPTION_BOOL(0, "test", &output_conf.test, false), CONF_OPTION_STRING(0, "dev", &output_conf.dev, NULL), + CONF_OPTION_UINT(0, "desired-width", &output_conf.desired_width, 0), + CONF_OPTION_UINT(0, "desired-height", &output_conf.desired_height, 0), }; int main(int argc, char **argv) @@ -215,12 +219,16 @@ int main(int argc, char **argv) log_notice("Creating video object using %s...", node); - ret = uterm_video_new(&video, eloop, node, mode); + ret = uterm_video_new(&video, eloop, node, mode, + output_conf.desired_width, + output_conf.desired_height); if (ret) { if (mode == UTERM_VIDEO_DRM3D) { log_notice("cannot create drm device; trying drm2d mode"); ret = uterm_video_new(&video, eloop, node, - UTERM_VIDEO_DRM2D); + UTERM_VIDEO_DRM2D, + output_conf.desired_width, + output_conf.desired_height); if (ret) goto err_exit; } else { From 02a7542a436337786d02eefb87e85ed87818e52a Mon Sep 17 00:00:00 2001 From: Skyler Ferris <skyvine@protonmail.com> Date: Wed, 21 Jun 2023 18:03:31 -0700 Subject: [PATCH 2/2] Add retry logic to display activation Also add intermediate error checks to the retry logic added in the previous commit. --- src/kmscon_seat.c | 2 ++ src/kmscon_terminal.c | 8 +++++--- src/uterm_drm2d_video.c | 7 ++++++- src/uterm_drm3d_video.c | 6 +++++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/kmscon_seat.c b/src/kmscon_seat.c index 56a65366..92fb62ca 100644 --- a/src/kmscon_seat.c +++ b/src/kmscon_seat.c @@ -159,6 +159,8 @@ static void activate_display(struct kmscon_display *d) * files. */ if (uterm_display_get_state(d->disp) == UTERM_DISPLAY_INACTIVE) { ret = uterm_display_activate(d->disp, NULL); + if (ret == -EAGAIN) + ret = uterm_display_activate(d->disp, NULL); if (ret) return; diff --git a/src/kmscon_terminal.c b/src/kmscon_terminal.c index ab17f715..430cb0ba 100644 --- a/src/kmscon_terminal.c +++ b/src/kmscon_terminal.c @@ -134,9 +134,11 @@ static void do_redraw_screen(struct screen *scr) if (ret == -EAGAIN) { uterm_display_deactivate(scr->disp); - uterm_display_activate(scr->disp, NULL); - font_set(scr->term); - ret = uterm_display_swap(scr->disp, false); + ret = uterm_display_activate(scr->disp, NULL); + if (!ret) + ret = font_set(scr->term); + if (!ret) + ret = uterm_display_swap(scr->disp, false); } if (ret) { diff --git a/src/uterm_drm2d_video.c b/src/uterm_drm2d_video.c index a784c0c4..b991c452 100644 --- a/src/uterm_drm2d_video.c +++ b/src/uterm_drm2d_video.c @@ -190,7 +190,12 @@ static int display_activate(struct uterm_display *disp, struct uterm_mode *mode) ret = drmModeSetCrtc(vdrm->fd, ddrm->crtc_id, d2d->rb[0].fb, 0, 0, &ddrm->conn_id, 1, minfo); - if (ret) { + + if (ret && mode == disp->desired_mode && mode != disp->default_mode) { + mode = disp->desired_mode = disp->default_mode; + ret = -EAGAIN; + goto err_fb; + } else if (ret) { log_err("cannot set drm-crtc"); ret = -EFAULT; goto err_fb; diff --git a/src/uterm_drm3d_video.c b/src/uterm_drm3d_video.c index 2dd3b5a1..25883687 100644 --- a/src/uterm_drm3d_video.c +++ b/src/uterm_drm3d_video.c @@ -213,7 +213,11 @@ static int display_activate(struct uterm_display *disp, ret = drmModeSetCrtc(vdrm->fd, ddrm->crtc_id, d3d->current->fb, 0, 0, &ddrm->conn_id, 1, minfo); - if (ret) { + if (ret && mode == disp->desired_mode && mode != disp->default_mode) { + mode = disp->desired_mode = disp->default_mode; + ret = -EAGAIN; + goto err_bo; + } else if (ret) { log_err("cannot set drm-crtc"); ret = -EFAULT; goto err_bo;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor