[console] VirtCon save/restore on graphics enter/exit#2671
Conversation
This change allows someone to start a game on one virtual console
and then return to text mode with all consoles' content preserved.
* RAM-backed virtual consoles for small-memory video adapters:
Re-enables CONFIG_CONSOLES_MAX (1-8). When the requested VC
count exceeds the adapter's video RAM, heap buffers are
allocated for backing VCs. If video memory is sufficient,
this has no impact.
* Console text preservation through video mode changes:
The DCGET_GRAPH ioctl snapshots console text pages to heap;
DCREL_GRAPH restores them and resets the CRTC start address.
If VCs are RAM-backed, only the current console page is saved
since background VCs already live on the heap. Page-flip mode
must save every VC since graphics writes may destroy all
text pages (e.g. CGA mode 4).
* Why bundle:
Bundled into one change-set because MDA cards didn't have
more than one supported VC, and many MDA cards are actually
Hercules graphics, which would use this feature. Since
detecting Hercules is error-prone, using RAM buffers when
the BIOS equipment word indicates MDA is the safe bet.
Alt-F1..F8 keybindings widened from F1..F4 to match the new VC
upper bound.
Tested on Leading Edge Model D with both MDA and CGA monitors,
2 VCs each. 20+ graphics entry/exit cycles per config; text
preserved across every transition in each console; no memory leaks.
|
Hello @cpiker, Nicely done. Do these enhancements allow running Nano-X and switching back to text mode, restoring the previous text display? If so, this is a major enhancement to usability of ELKS. Nice idea using off-card memory for the video buffers, I wouldn't have thought of that idea. I am wondering a bit whether it might be better to allocate out of main memory rather than the kernel heap; some systems may be pretty tight on kernel heap free space. I haven't had time to fully review your code yet, the VC allocation only occurs once and during kernel init, right? That decreases any heap checkerboarding that might otherwise occurring using either heap.
Which games have you tested with this mod? We will likely (separately) also have to deal with the problem of notifying the graphics-drawing program to stop drawing or possibly not be scheduled for any execution while text mode is active. I need to think a bit more about how exactly that should work. On graphics restoration, a signal or another mechanism could be sent to the process to tell it to regenerate the graphic display. Thank you! |
|
Running Nano-X (or other graphics) and then switching back to text mode is exactly the operation I'm trying to support. Mostly I had in mind short lived programs such as image viewers, games, etc. but I guess this could be useful to full desktop environments too. I was nervous about using any extra memory, so allocation only happens in two instances:
I wanted this to be a no-ram-cost extension to current capabilities as much as possible, so if you never run a graphical program and have at least a CGA card, there is no effect on memory usage. I didn't test with any games per-se because I noticed this issue before I started porting anything to use the DCGET_GRAPH ioctl. Instead I made a test program that exercised:
It basically switched, drew a test pattern, and switched back so that I could make sure the text restored correctly. A caveat: I haven't setup any hardware to provide a dual-monitor testbed so currently Can you provide guidance on using main memory instead of the kernel heap, especially with a link to example source code? I'm new and thought I was supposed to use the kernel heap. Happy to make changes. |
Given that your code is well written, and this new capability could be very beneficial for those wanting to switch between Nano-X and other graphical programs, I'm inclined to want to accept the PR now, mostly as-is, rather then waiting until after v0.9.1 is released. As you may have read, I botched the Nano-X binary in the v0.9.0 release and running nxstart crashes the system. This is now fixed, and then a bunch of easy fixable kernel bugs were identified with some AI analyses, so those fixes went in too. I don't think there's time to get graphics/text mode switching working well immediately and I was thinking of releasing v0.9.1 very soon. That said, in order to get this first step committed, I would like to have all its features turned off by default, so that there is no need for testing Nano-X compatibility at this time, including any memory allocations of any kind. The code would be included, and you could continue to experiment with actually running the various games/graphics/nano-x included on the distribution(s), and we can come up with a mechanism that would allow graphics programs to coexist with a switchable text/graphics console. To do this, I would suggest making the following mods right now, after which I can commit:
Other small issues are to be consistent with #if vs #ifdef VC_GRAPH_SAVE_RESTORE - the ifdef is incorrect when set to 0, so just use #if throughout. The kernel is getting dangerously short on both text and data segment space, so I'm leaning towards less warning messages etc. long term. However, during development these are quite useful so we can leave them in for now. This can be discussed more fully later. The fact that we're almost out of near text space in the kernel may also mandate options to not include features (possibly like this) which may not be wanted by all users. That can also be sorted out later, and I will look further into how much space is left after commit, but another reason why it would be temporarily nice to have a way to turn off the entire new feature so close to releasing v0.9.1.
These are some of the reasons I'm thinking of turning off the feature until v0.9.1 is released. I don't want to change the default VC numbers or possibly have ELKS kernel run out of memory when running nano-X until more is known about how the system operates. Version 0.9.0 provides some big enhancements to Nano-X so it is a priority for v0.9.1 to make sure it's working.
I agree and nice idea, for sure. But memory is still allocated just during the switch to text mode, right? The text mode buffer(s) always have to be copied since a graphics program may use it.
Let's not worry about that until getting the basic text/graphics switching code working with the DCSET_ and DCREL_ ioctls. (BTW, you may have noticed that the Nano-X driver microwindows/src/drivers/scr_vga.c already has commented out ioctl's for this. However, they are currently designed to disallow switching to text mode once started - also not implemented). All-in-all, this is a very nice first step, thank you for your work :) |
|
Regarding the business of how Microwindows/Nano-X actually works with text/graphics mode switching on Linux, you might want to look at microwndows/src/drivers/vtswitch.c. This code is part of the user-space driver which starts and stops graphics drawing in the Nano-X server. I don't think we necessarily want to go this route of complexity, but the code does show some of the issues involved, such as programs being able to query the console switch state, as well as refusing a switch, etc. All of this and more will have to be considered for what might want to happen on ELKS. As I said earlier, I think possibly a much simpler approach of literally un-scheduling the graphics app from running, and then signaling a way to redraw the graphics will be much superior than the mechanism vtswitch.c and Linux Nano-X use. All of this can be discussed in more detail later. |
Could you expand on 'very soon'? Are you thinking tomorrow, next weekend? Tomorrow is a heavy work day for me so the earliest I could update the PR would be late in the evening and more realistic is late Tues night.
Sure I can do that.
You're right. Currently the feature as implemented always saves the console state when something grabs the graphics lock. Even setting CONFIG_CONSOLES_MAX = 1 causes 4K to be allocated.
You're more than welcome. ELKS is a gem, happy to contribute where I can. |
|
I've worked through the PR update and am almost there. Need to run a couple hardware tests first. Should be done tomorrow night. |
No worries - I think I'll publish v0.9.1 in the next day or so and then commit this afterwards. It'll be better to not worry about breaking v0.9.1, so no need to rush. |
|
Sounds good. Say if you could hold off on merging this even after v0.9.1 is out the door for just a little bit I'd appreciate it. I realized that my changes to allow up to 8 VC's were based off old Configure.help text that didn't really go with the mentality of the rest of the code in the master branch, so I backed that out to make a smaller change-set. Would like to amend the PR before it's merged anyway. |
This change allows someone to start a game on one virtual console and then return to text mode with all consoles' content preserved.
RAM-backed virtual consoles for small-memory video adapters:
Re-enables CONFIG_CONSOLES_MAX (1-8). When the requested VC count exceeds the adapter's video RAM, heap buffers are allocated for backing VCs. If video memory is sufficient, this has no impact.
Console text preservation through video mode changes:
The DCGET_GRAPH ioctl snapshots console text pages to heap; DCREL_GRAPH restores them and resets the CRTC start address.
If VCs are RAM-backed, only the current console page is saved since background VCs already live on the heap. Page-flip mode must save every VC since graphics writes may destroy all text pages (e.g. CGA mode 4).
Why bundle:
Bundled into one change-set because MDA cards didn't have more than one supported VC, and many MDA cards are actually Hercules graphics, which would use this feature. Since detecting Hercules is error-prone, using RAM buffers when the BIOS equipment word indicates MDA is the safe bet.
Alt-F1..F8 keybindings widened from F1..F4 to match the new VC upper bound.
Tested on Leading Edge Model D with both MDA and CGA monitors, 2 VCs each. 20+ graphics entry/exit cycles per config; text preserved across every transition in each console; no memory leaks.