SDL_RenderPresent freezes/hangs sometimes

I have a problem with the game I’m developing. My game code is pretty complex (I wrapped everything and made much use of OOP) and written in Ada instead of C/C++, so posting source code might not be that helpful (but I can post some if it helps). Instead, I think I’ll explain what’s going on that’s related to SDL.

I can’t remember which version of SDL I’m using and don’t know how to check but Windows says 3/15/2014 as the created date. I tried updating to 2.0.5 but then it goes really slowly and finally freezes. (Is 2.0.5 heavier than older versions?)

My draw function is called whenever anything changes (positions of objects, frames of animations, etc). The algorithm is:

Draw stuff with a combination of SDL_SetTextureColorMod and SDL_RenderCopyEX

After calculating stuff and drawing, it will do an SDL_Delay of at least 2ms. Normally it delays by the period of the framerate (17ms) minus the elapsed time of the processing so it keeps a steady 60FPS.

There’s also music and sound, using SDL_Mixer, as well as joystick and keyboard input.

The part I think the perpetrator is that loading/freeing resources is handled in a separate thread. The main game code specifies a group of resources to load/free next and the thread uses Mix_LoadMUS, Mix_FreeMusic, Mix_LoadWav, Mix_FreeChunk, SDL_CreateTextureFromSurface, SDL_LoadBMP, sometimes SDL_SetColorKey and SDL_DestroyTexture to manage resources.

I think this is responsible because it only happens sometimes (a red flag for threading problems) and if it does freeze, it’s always when stuff is loading or being freed and the SDL_RenderPresent call happens before the call returns.

Thanks in advance for any help. I hope I gave enough information.

You should have an SDL_GetVersion function to get version of the linked SDL library.

[quote=“Devsman, post:1, topic:22907”]
The main game code specifies a group of resources to load/free next and the thread uses […] SDL_CreateTextureFromSurface […] SDL_DestroyTexture[/quote]

Note that the SDL2 render API states that:

These functions must be called from the main thread.

That doesn’t necessarily mean the issue you are seeing comes from this, just be prepared for unexpected behavior. (Unless you had a look at the SDL renderer code and know exactly how to work around this limitation.)

One example is that the direct3d renderer will probably lock to synchronize the calls from different threads. However, it should not slow it down that much that it freezes completely.

Another problem is that SDL usually isn’t thread safe unless explicitly specified. You have to place the locks yourself.

I can’t say for sure what issue this is, but running everything in the main thread (or putting locks at the appropriate places) would be a way to check for threading issues.

We could take a look at what changed between the SDL version you have and 2.0.5. What version is it and what renderer are you using?

Oh, you can also try the other renderers. Besides direct3d, Windows probably also has opengl. If everything goes wrong you can use the software renderer, but this one is obviously slow.

Thanks for the reply! I must have forgotten about that since I started in the project more than a year ago.

I’m using 2.0.3, according to SDL_GetVersion. I already have a method in place to load textures from rwops. I bet I can still do the file I/O in a separate thread as long as it still calls those functions from the main thread.

I’m making the SDL_Window with SDL_CreateWindow, using the flags SDL_WINDOW_SHOWN. I’m then making the SDL_Renderer by passing that window to SDL_CreateRenderer with flags SDL_RENDERER_followed did. I hope that answers your renderer question.

Using RWops in a separate should indeed work. At least on Windows it’s more or less just calling the Windows API. No guarantees, though.

I was actually wondering if you used the direct3d renderer. There were a few changes to this renderer from 2.0.3 to 2.0.5, but I don’t know enough about it and Direct3D itself to say if these could have caused what you are experiencing.

Ok great, thank you. I think I’ll play around and see if using rwops or mutexes will work, but if not I’ll know to load them in the main thread.

It might be a problem due to the Ada bindings.
make sure Ada doesn’t finalize some SDL variables before SDL frees them
AND that you don’t SDL_free objects that are still referenced by Ada.

I had a problem like this with the Ocaml language.

If anyone is still interested, I solved this by making a mutex type of my own (I didn’t try the SDL builtin one) and using it to lock calls so that nothing would ever be drawn while anything was rendering. It has given me no trouble since. Thanks for the help!