I just gave the code a quick look, focussed on the NES emulator screen draw function. I could check further some time, but maybe someone knows more about it.
What I understood so far, please correct anything that is wrong:
vidQueue (a FreeRTOS queue) is used to transmit pointers to a full frame buffer to videoTask. The videoTask uses a screen draw function ili9341_write_frame_nes, which applies some palette and write it into line-buffers that you somehow get from an SPI task? This part gets somehow confusing to me, and I didn't go into the SPI code from IDF yet.... Nevertheless, here I don't understand where this "diagonal tearing" would come from. Maybe it is actually NES-rendering specific (about which I know nothing)? Otherwise it could be a problem with the SPI transmissions to the display?
I am not an expert at all on the ESP32, but also wonder a few other things in general:
- Could we add some double buffering to improve the situation, is there enough memory left, or wouldn't it solve the problem anyway?
- Is the effect I am seeing actually a frame-drop effect? So actually the frame is canceled to be drawn, since the next frame needs to be drawn already? And you decide to rather display just part of the frame instead of dropping it entirely? But why is it cut diagonal then? Is it something like a memcpy that writes memory in a strange order?
- Everything I have seen so far seems to be pinned to the App CPU, right? Couldn't we separate video/audio/spi tasks from the emulator?
Thanks for shedding some light!