go-play
go-play copied to clipboard
[Discussion] Reduce Tearing in NES
I want to reduce tearing problem in NES. I copied our discussion from odroid forum to here
How it works now
The way the display system currently works:
- emulator finishes a frame on core 0
- frame is copied and the copy is sent to core 1
- emulator works on next frame on core 0
meanwhile on core 1:
- a frame is received from core 0
- a group of scanlines is processed (palette and scaling).
- the group is sent to DMA.
- the next group of scanlines is processed while DMA is in progress.
meanwhile on DMA:
- data is received by the DMA engine and is fed to the SPI hardware
- DMA notifies completion.
There are two frame buffers, two scanline buffers of 3 lines, and multiple DMA buffers.
At 40Mhz SPI, there is 40,000Kbps / 8 bits = 5KBps. A frame is 320 * 240 * 2 bytes / 1024 = 150KB. 5KBps / 150KB = 33.3 fps. However, because there is protocol overhead, the achieved frame rate is less (closer to 30fps). The LCD updates at 70fps (61 is the slowest but looked worse). 70fps / 30fps = 2.3 refreshes for every frame displayed.
LCD controller specs
Other's improvement on IL9341 over SPI
My proposal
- Use two frame buffers to do swap instead of memcpy
- Find minimal different rectangle between two frame buffer and send the delta over SPI
- Use Good old interlacing is added into the mix: if the amount of pixels that needs updating is detected to be too much that the SPI bus cannot handle it, the driver adaptively resorts to doing an interlaced update, uploading even and odd scanlines at subsequent frames. Once the number of pending pixels to write returns to manageable amounts, progressive updating is resumed. This effectively doubles the maximum display update rate.