QNICE-FPGA
QNICE-FPGA copied to clipboard
Emulator: Optimize vga_refresh_rendering() for VGA_FONT_DATA and VGA_PALETTE_DATA
Currently, when a program writes to the font data or palette data register vga_refresh_rendering();
is being called, which is heavily decreasing (if not even completely killing) performance in case a program changes for example the font graphics frequently.
Here is an idea of how to improve the performance on the native platform (WASM seems to support threads too, need to investigate):
- Add an optional parameter to
vga_refresh_rendering()
. If it is not specified then the function behaves like today. If it is specified, then it only changes certain characters on the screen. This saves tremendous computing power, as the font patterns can be only changed on pattern at a time and therefore it is known, which character is affected from the change.
That means something like this:
void vga_refresh_rendering(char filter = 0)
{
for (int y = 0; y < screen_dy; y++)
for (int x = 0; x < screen_dx; x++)
{
unsigned int vram_val = vram[y * screen_dx + x + vga_offs_display];
if (!filter || (vram_val & 0x00FF == filter)) //ignore color, just filter for the char
vga_render_to_pixelbuffer(x, y, vram_val);
}
- Make the whole re-rendering of the screen due to font changes multithreaded in the following sense:
- FIFO buffer that contains jobs to be done for a worker thread (we already have a threadsafe FIFO in
fifo.h
andfifo.c
). So this here
case VGA_FONT_DATA:
qnice_font[font_addr & 0x0FFF] = value;
vga_refresh_rendering();
break;
would be replaced by something like this here (pseudo-code):
case VGA_FONT_DATA:
qnice_font[font_addr & 0x0FFF] = value;
add_to_refresh_fifo(font_addr); //is font_addr equal to the character we need to filter for?
break;
-
Worker thread takes jobs from the fifo and runs
vga_refresh_rendering(filter_value_pulled_from_fifo)
. -
The worker thread creates a race condition, since it is writing to the VRAM in parallel to other threads who are writing to the VRAM. But this race condition is completely harmless and a human will notice a slight flicker - if at all.
-
P.S. Is
& 0x0FFF
right anyway? This would imply 12bit color instead of 15bit.
A similar thing might be done for the palette and palette changes.
As a test, we might use #ifdef EMULATOR
in vga_circle.c
to have a simplified version that does not rely on the scanline interrupt and/or scanlines in general, so that we can check, if the optimization works at all.
This issue blocks #17.
@MJoergen I can support you with all of this, if you want, but as I am still on my boat, you might be faster :-)