What about single-buffering?

…And any chances it ever will?

Almost certainly not. That isn’t a thing anyone needs, and isn’t possible on some platforms.

As I said earlier, if you’re trying to simulate the way Chip8 flickered, you’re better off doing it over multiple frames. On a modern computer, even a single-buffered display isn’t going to flicker the same way Chip8 did.

And accurately simulating all the side effects of the hardware, like screen flicker or the way a certain system’s FM synthesis music sounded, is why writing a good emulator is hard.

1 Like

This is absolutely not an SDL problem nor a technical problem with double buffering, you just need to figure out algorithmically how to display your buffer as it’s being drawn. There is one immediately obvious way, which is to do the emulated framebuffer filling in another thread, and your main thread (which is the one with the main loop that drives the SDL graphics and event processing) copies that buffer whenever it needs to display it. So you just put your whole emulation in that thread, timing everything as best as you can and let your main SDL thread display things in parallel as they come.

But that might be overkill, another way if you know in your emulator when the display is meant to be visually updated (the emulated screen controller probably has some sort of refresh rate?) is to simply display the frame buffer whenever it’s needed, and you never clear it. Again it has nothing to do with double buffering, you just need to understand what you need to do. Double buffering just means that you only display your framebuffer on the display when you choose to, so for you the question is choosing when or how to decide when it should be done.

SDL_RenderPresent() is likely to perform a ‘swap buffers’ behind the scenes so in general “never clearing” the framebuffer won’t work: you have to assume that after the screen update the contents of the buffer are undetermined, and call SDL_RenderClear() before starting to create the next frame. This is explicitly called out in the documentation: “The backbuffer should be considered invalidated after each present; do not assume that previous contents will exist between frames”.

Fortunately the solution is relatively simple: use a ‘target texture’ (set using SDL_SetRenderTarget()) rather than the default render target. The contents of the target texture will be preserved from one frame to the next. The screen update is slightly more involved in that case:

targetTexture = SDL_GetRenderTarget(renderer);
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, targetTexture, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_SetRenderTarget(renderer, targetTexture);

That’s not what I’m saying, you’re thinking too complicated. It’s an emulator so it should have its own framebuffer that represents the video controller’s memory that is not SDL-related at all, like an array of bytes (or bits?) in whatever format the emulated machine puts things. So that should be filled independently of SDL rendering. So you’d fill that buffer in whatever thread you see fit and in the main thread have that buffer displayed on screen however you see fit. You shouldn’t try to skip steps and make the emulator thread directly do SDL rendering stuff, you want to keep the state of the emulation not depending on such things. That makes sense if OP wants to add other things on screen, just draw the emulated video controller’s framebuffer wherever in whatever state it is, then draw other elements normally.

Uh… I use SDL_UpdateWindowSurface(). And I am pretty sure it copies the backbuffer into the frontbuffer instead of swapping the two buffers.

The SDL2 docs say “This function is equivalent to the SDL 1.2 API SDL_Flip()” and there it says “On hardware that supports double-buffering, this function sets up a flip and returns” so I’m not so sure.