Skip to content

Draw the video frame in text row-sized chunks#3108

Closed
kcgen wants to merge 1 commit intomainfrom
kc/text-parts-1
Closed

Draw the video frame in text row-sized chunks#3108
kcgen wants to merge 1 commit intomainfrom
kc/text-parts-1

Conversation

@kcgen
Copy link
Copy Markdown
Member

@kcgen kcgen commented Nov 12, 2023

Description

When in text video modes, we were drawing video video frames with per-line timings. Because DOSBox's own text console rasterizer just draws to the video memory as-is without doing fancy buffer-swapping or flipping, there could be instances where the updating frame "reveals" line-level differences during the frame update.

This PR adjusts the VGA draw part size to match the number of text rows (when in text mode), which granularizes the text updates at the row level to avoid revealing inter-row differences (at the pixel-line level).

Of course - differences can still occur mid-frame, but they will be at the text-row level.

Graphical modes are unaffected.

Manual testing

Tested rapidly running ls, and also tested rapid text-based demos:

out_001.mp4
out_003.mp4
out_004.mp4
out_005.mp4

Checklist

I have:

  • followed the project's contributing guidelines and code of conduct.
  • performed a self-review of my code.
  • commented on the particularly hard-to-understand areas of my code.
  • split my work into well-defined, bisectable commits, and I named my commits well.
  • applied the appropriate labels (bug, enhancement, refactoring, documentation, etc.)
  • checked that all my commits can be built.
  • confirmed that my code does not cause performance regressions (e.g., by running the Quake benchmark).
  • added unit tests where applicable to prove the correctness of my code and to avoid future regressions.
  • made corresponding changes to the documentation or the website according to the documentation guidelines.
  • locally verified my website or documentation changes.

@kcgen kcgen added bug Something isn't working video Graphics and video related issues labels Nov 12, 2023
@kcgen kcgen requested review from johnnovak and kklobe November 12, 2023 02:40
@kcgen kcgen self-assigned this Nov 12, 2023
@kcgen kcgen force-pushed the kc/text-parts-1 branch 5 times, most recently from 417f405 to 6f306d3 Compare November 12, 2023 02:48
@johnnovak
Copy link
Copy Markdown
Member

johnnovak commented Nov 12, 2023

I appreciate the effort @kcgen , but frankly, it was better before. Before this change only a single scanline was glitching, now it's an entire row, so it's worse. See attached video (just remove the second .zip extension).

If there's always gonna be glitching with the current DOSBox-side text output method, it's best to restrict the artifacts to a single scanline.

glitch.avi.zip

Cool text demos, but as we were saying, proper emulated DOS programs are different, those are expected to work without artifacts anyway.

@kcgen
Copy link
Copy Markdown
Member Author

kcgen commented Nov 12, 2023

Before this change only a single scanline was glitching, now it's an entire row, so it's worse.

This was deliberate because the smallest "logical unit" in text modes is a text cell, so switching from per-line to per-row chunks (or "atomic row changes") means we'll only see row-level changes, and never slice through the middle of a text character (or strange effects like that).

But yeah - if we're just trying to shrink this region of change (as the frame is updated); then pixel-lines is the way to go.

Cool text demos, but as we were saying, proper emulated DOS programs are different

I wasn't booted into real MS-DOS; so the text demo was making INT10 text calls into DOSBox's emulated DOS routines, and from there the drawn text is render to the VGA side where this per-line chunked behavior is seen.

(In the videos, you will also see there's no tearing or sub-row slicing; and the demo is using a real text mode).

But regardless, I'd rather the per-line updates anyway 😅

@johnnovak
Copy link
Copy Markdown
Member

johnnovak commented Nov 12, 2023

I wasn't booted into real MS-DOS; so the text demo was making INT10 text calls into DOSBox's emulated DOS routines, and from there the drawn text is render to the VGA side where this per-line chunked behavior is seen.

(In the videos, you will also see there's no tearing or sub-row slicing; and the demo is using a real text mode).

Ok, but do we get any slicing/tearing artifacts with these text demos prior to this change, when rendering by scanline? I think not, we established that the probable cause for text tearing at the DOS prompt is that our emulated DOS prompt implementation does "weird things" and doesn't quite go through the normal "emulation pathways" like regular DOS programs do, unlike our DOS commands.

Can you post the names of these demos, links to them, or the demos themselves? Then I can also test if there's any tearing when rendering by line as before.

But regardless, I'd rather the per-line updates anyway 😅

Let's take a step back 😄 I brought this up because the single scanline glitches annoyed me in our DOS prompt only. I never encountered these glitches on any other text programs, just with our DOS prompt.

So, if running actual DOS programs that use text mode never glitch anyway with per scanline rendering (to be tested if you send links to the demos), then this change only magnifies the problem with the DOS prompt. So yeah, then it's worse because it's more noticeable now and more distracting 😄 Am I missing some benefits of the per-row rendering here?

@kcgen
Copy link
Copy Markdown
Member Author

kcgen commented Nov 12, 2023

Before I close it out, I did a deeper dive into what's happening as the frame level.

Notice that DIR isn't affected by this issue despite both it and LSjust printing text using WriteOut(char*), so what's going on?

DIR, stepping per-millisecond

  1. DIR step 1

    2023-11-12_13-30

  2. After tapping Enter, DIR prints all of its content within the same millisecond moment in time:

    2023-11-12_13-31

    There are no intermediate steps.

LS, stepping per-millisecond

Now let's see how LS behaves:

  1. LS step 1, just before pressing Enter

    2023-11-12_13-31-2

  2. Ater pressing Enter, LS prints an initial new line causing the entire frame to scroll up one row:

    2023-11-12_13-33

  3. There's still more time spent here.. notice the cursor at the bottom is just starting to be drawn in. We're now several milliseconds in:

    2023-11-12_13-34

  4. Finally LS prints all its content, causing the frame to scroll up even more rows:

    2023-11-12_14-40

So the big difference is that LS has three visible drawing events, all of which can drive frame updates. These seems to appear (nearly) instantly, but it's really doing things in proper sequence: scrolling content up and then re-drawing in the new scrolled stated.

@kcgen kcgen closed this Nov 12, 2023
@kcgen
Copy link
Copy Markdown
Member Author

kcgen commented Nov 12, 2023

Can you post the names of these demos, links to them, or the demos themselves? Then I can also test if there's any tearing when rendering by line as before.

Yup - that one is textro

So, if running actual DOS programs that use text mode never glitch anyway with per scanline rendering (to be tested if you send links to the demos), then this change only magnifies the problem with the DOS prompt.

I'm still digging; what I've concluded so far is that the our DOSBox-side commands (like LS and DIR) are able to use WriteOut(char*), which is a DOSBox API that interfaces with the real text frame content.

Basically, we can call WriteOut("hello world") and instantly inject text right into the DOS console; and this is very fast and independent of CPU cycle count.

Compare that with DOS-side programs - if they want to print text, they use INT10H interrupt, which DOSBox emulates.

Both text pathways ultimately terminate in the same BIOS text frame handling code.

Am I missing some benefits of the per-row rendering here?

I don't think so!

(more to come.. :-)

@kcgen kcgen deleted the kc/text-parts-1 branch November 12, 2023 22:57
@johnnovak
Copy link
Copy Markdown
Member

johnnovak commented Nov 12, 2023

Couple of ideas:

  • Don't instantly inject text into the DOS console, just go through the normal channels as other DOS programs (i.e., BIOS interrupts, or write characters to the raw video memory the same way actual programs do)
  • Just render a single "slice" (part) for text modes. Or would that break any weird text mode demos? I don't think so, but would need testing.

The first option seems better to me.

Compare that with DOS-side programs - if they want to print text, they use INT10H interrupt, which DOSBox emulates.

Just for clarification @kcgen: many programs write character codes to the text mode video memory area directly (starts at B8000h on VGA). In the DOS days, I just maintained my own 80x25 / 80x50 buffer and then flipped the whole thing to the vmem on vsync in one go on VGA. Much faster than the BIOS interrupts and you have more freedom manipulating your character buffer directly.

I'm sure the text mode demo does the exact same thing, so it's quite impossible to get the same glitchy behaviour with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working video Graphics and video related issues

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants