Skip to content

[sdl] missing frames #165

Open
Open
@zenria

Description

@zenria

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):
surface_saved

And here is the screenshot of the actual window:
Capture d’écran 2022-04-24 à 18 18 04

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions