I'm currently testing the SDL console on macos.
Sometimes, rendered surface seems not to be presented to the window. It happens more likely in REPL when 2 lines are printed without any user interaction. (Typically, "Ready" is not displayed)
I tracked the issue deeply in the code to check is there was a missing call to present_canvas(). Everything seems alright.
With the following code at the very end of force_present_canvas(), I managed to reproduce the issue:
self.canvas.surface().save_bmp("screen.bmp").map_err(string_error_to_io_error)
So here is the rendered BMP (everything is OK here):

And here is the screenshot of the actual window:

The "Ready" prompt is missing! It has correctly been rendered in the underlying surface, but is not shown to the actual window! If I hit a key, let's say "B" the Ready prompt is correctly render and the "B" letter is shown at the right place...
I initially thought the issue was coming from the unusual way to render to the window (rendering to a surface and then blitting the surface to the window surface). SDL documentation and example wants you to render directly to a window canvas typically created by calling window.into_canvas().build(). This is also the way to enable hardware acceleration and Rust SDL documentation emphasizes that rendering to a surface is slow and not accelerated. So I heavily modified the code to do the rendering to a window canvas and to present the canvas.
This did not work! Same issue.
I then read a bunch of example of SDL code. In all example, the render is always done the same way:
- consume all events
- render the whole scene
- wait some time to achieve 30 or 60 fps
- present the canvas
The critical part missing from the endbasic SDL rendering code is the wait time. I confirmed this by adding a dumb std::thread::sleep in force_present_canvas() function. No more missing frames.
I'm not sure how to fix this. I think the best way would be to have a dedicated thread that does main loop the way sdl wants it to be (poll events/render/wait/present) and communicates with the rest of endbasic (the Console trait impl) with channels.
I'm currently testing the SDL console on macos.
Sometimes, rendered surface seems not to be presented to the window. It happens more likely in REPL when 2 lines are printed without any user interaction. (Typically, "Ready" is not displayed)
I tracked the issue deeply in the code to check is there was a missing call to
present_canvas(). Everything seems alright.With the following code at the very end of
force_present_canvas(), I managed to reproduce the issue:So here is the rendered BMP (everything is OK here):

And here is the screenshot of the actual window:

The "Ready" prompt is missing! It has correctly been rendered in the underlying surface, but is not shown to the actual window! If I hit a key, let's say "B" the Ready prompt is correctly render and the "B" letter is shown at the right place...
I initially thought the issue was coming from the unusual way to render to the window (rendering to a surface and then blitting the surface to the window surface). SDL documentation and example wants you to render directly to a window canvas typically created by calling
window.into_canvas().build(). This is also the way to enable hardware acceleration and Rust SDL documentation emphasizes that rendering to a surface is slow and not accelerated. So I heavily modified the code to do the rendering to a window canvas and to present the canvas.This did not work! Same issue.
I then read a bunch of example of SDL code. In all example, the render is always done the same way:
The critical part missing from the endbasic SDL rendering code is the wait time. I confirmed this by adding a dumb
std::thread::sleepinforce_present_canvas()function. No more missing frames.I'm not sure how to fix this. I think the best way would be to have a dedicated thread that does main loop the way sdl wants it to be (poll events/render/wait/present) and communicates with the rest of endbasic (the
Consoletrait impl) with channels.