My plan is to add an option that allows the user to control screen flickering.
Options are: Never | In interlace mode | Always
( default is "In interlace mode" )

I don't understand the third option value 'Always'. Does that not mean it would also flicker even if not in interlace mode? Or in other words, 320x256 and it is flickering ? In which case one would like to choose this option ? Maybe I understand this not correctly and 'always' has another meaning ?
Does that not mean it would also flicker even if not in interlace mode?
yes.
In which case one would like to choose this option ?
Hmm, well, don't know 馃.
Maybe we should go with "Never" and "In Interlace Mode".
Interlace flickering is up and running.
There are some caveats though. The effect only looks good if the GPU runs at exactly 60 fps. If you load something from disk, you will notice annoying graphics glitches (like flashes). I think the root cause is twofold:
If something is loaded from disk, debug output is produced. I think this makes the GPU drop some frames, so the emulator is running temporarily below 60 Hz. This wouldn't be too severe, if the second effect wasn't there.
The flicker effect is emulated by darkening every second row. This means that we have Moir茅 effects which cause the two textures having different luminance. When the frame rate drops, one of the textures is displayed more often than the other which changes the luminance of the whole picture. At the moment, I think this is the root cause for the graphics glitches looking like flashes.
Update: It's not due to Moir茅 effects (same happens if flickering is emulated inside the fragment shader). I think the effect is much simpler. If black and white swaps at 60 Hz, the human eye recognises grey color (luminance = 50%). When the frame rate drops, a flash is recognised, because the white pixels stay long enough to let the eye detect the real luminance (100%) for a short period of time (hence, the flashes).
Hypothesis: GPU framerate drops when the GUI processes incoming messages from the emulator (which is done in the main thread).
Todo: Check if MTKView stuff can be executed outside the main thread.
Todo: Check if MTKView stuff can be executed outside the main thread.
According to
https://stackoverflow.com/questions/55769612/mtkview-drawing-performance,
it might be better to implement a MTKView delegate instead of subclassing MTKView (which I did).
Renderer is a MTKViewDelegate now.
Most helpful comment
yes.
Hmm, well, don't know 馃.
Maybe we should go with "Never" and "In Interlace Mode".