Allegro 5 threads
julian smit

Hey,

I'm pretty new to using threads in allegro 5.0, and now i wanted to use them in my little 2d Pokemon game. I've looked for some toturials and the only usefull toturial i was able to find was: http://wiki.allegro.cc/index.php?title=Allegro_5_Tutorial/Threads

Now i had a few question about this:

1) How to properly use them? I mean is it possible to draw Bitmaps inside the Thread? I tried to do this but i failed. I was able to create a new working thread, and tried to use it for loading the graphics but it was terrible slow.

2) Are there more usefull toturials i could look at for multithreading in allegro 5?

J-Gamer

1) only the thread that makes the display can load/draw video bitmaps. All other threads use software bitmaps, and those are slooowwwww...

2) You could search the forum for multithreading here on the forum. I have learned a lot from those threads. Otherwise, just try and understand the example programs.(play with their code a bit and you might get to understand threads better)
You might also want to look at some online tutorials about multithreading to get to know what threads are generally used for, what the popular design patterns are,...

julian smit

Ah okay thanks for the help, i also thought it had something todo with the display, and i guess i could look at the way other languanes use the threads.
thanks!.

There's only 1 question though: i'm trying to load all the data in 1 thread (graphics and fonts etc.. (map files later)) anyway i'm able the fonts but when i try to load the graphics they program doesn't crash but i can see the text but the graphics are all black and the program is lagging like hell any ideas why?

J-Gamer

Do you mean that you are loading them in a seperate thread? If so, bitmaps won't load with hardware acceleration, thus making the program terribly slow. I have no idea why they would get blacked out though... Did you properly initialize allegro?(al_init_image_addon() etc.)

Edgar Reynaldo

You need to do all your resource loading in the main thread or you'll get memory bitmaps and may have some strange problems. Display status / progress reports / whatever in the secondary threads.

axilmar

How to properly use them?

  • separate the simulation logic from the presentation logic.

  • update the simulation in a worker thread.

  • when the worker thread is ready, send the simulation state to the presentation thread, i.e. the main thread.

  • the main thread then draws the current simulation state.

  • UI commands from the main thread should be sent to the simulation thread as messages.

Generally, think about the problem has having two programs cooperating: one program does the work, the other displays the work. They communicate by messages.

julian smit

Okay thanks for the help so far, now i'm trying to make a loop in the main thread but when i try this the other thread isn't functionating anymore any ideas/help on how i can fix this?

J-Gamer

It should work... could you give us some code?

julian smit

EDIT: question in new post.

J-Gamer

Do you see that in thread 2, you got a nested loop? you've got one in Thread_2 AND one in NewMain. Thread 1 isn't working because thread 2 never releases the mutex on data(until you exit the NewMain loop)

APPEND: I don't see why your code compiles... main() doesn't return.

julian smit

that's true i was thinking that was the problem but when i didn't use the loop the program shut down. also i've started from the example in the allegro wiki again. my only question now is:

I want to use the main thread for drawing everything, and use the (child) thread for loading everything files,bitmaps etc. now the only problem is that it isn't possible to load bitmaps in a thread except the thread where the display is created?

EDIT: nvm i was able to load them in the other thread thanks anyway!.

EDIT2: When i try to load a map file (without multithreading) the program freezes for a few seconds, now i try to load the file in the second thread now the second thread freezes but the main thread also freezes. any ideas why? although when i use the al_rest(); function in the thread it doesn't slow down the main thread.

EDIT3: I was able to fix it by not using the al_lock_mutex (and unlock) in the main thread ( i didn't need it anyway for updating the values)

Thomas Fjellstrom

You can draw to a display from a thread but that thread has to own the display. Allegro lets you change ownership of a display using the `al_set_target_backbuffer` function. If you created the Display in one thread and want to use it in another, you first have to `al_set_target_backbuffer(0);` in the creating thread, then do `al_set_target_backbuffer(display);` in the thread that wants to use that display. This means only one thread can draw to a display at any one time.

If you want to load bitmaps in a separate thread, make them memory bitmaps, then make the main thread al_clone_bitmap them all as display bitmaps. Loading bitmaps in a secondary thread will cause those bitmaps to not be connected to that display, and make them very slow to draw.

J-Gamer

You should only use mutexes if you are trying to access data that's shared with other threads. Don't unnecessarily lock a mutex.

julian smit

Ah, that clears alot up, although i got one last question your saying that i only should lock the mutex when it's sharing data, what kind of data do you mean and why should i use it than anyway?.

J-Gamer

That's what that DATA class is for. You put all variables that the threads share in there, and you put lock/unlock_mutex calls at places where you want to access those variables.

julian smit

Ah okay thanks i got everything working now although i got one kind of a stupid question, because when i want to load files i normally just would call a void in the main thread for example, although that's now not possible so when i want to load a file for the main thread but don't want to make it freeze i do something like. if(data.load_map == true) map_load(data.map_id); in the (child) thread and in the main thread put the data.load_map = true; are there easier ways to do this? because this seems like a pretty bad solution..

axilmar

Ah okay thanks i got everything working now although i got one kind of a stupid question, because when i want to load files i normally just would call a void in the main thread for example, although that's now not possible so when i want to load a file for the main thread but don't want to make it freeze i do something like. if(data.load_map == true) map_load(data.map_id); in the (child) thread and in the main thread put the data.load_map = true; are there easier ways to do this? because this seems like a pretty bad solution..

Is it so difficult to write English properly? to use punctuation properly? I had to read your text 3 times in order to understand what you ask.

If you want help, then you should ask for it in a proper way.

Anyway, back to your problem: if you want to program any time-consuming job without having to freeze the main thread, you have to do it in a worker thread. When the worker thread finishes, then it notifies the main thread by an event.

julian smit

Sorry for that,
Anyway i'm pretty happy with what i've done so far, i'm able to load almost everything in the worker thread, and actually everything is running fine except when the first thread is using the display, and i want to load the graphics in the the second thread the screen doesn't show up normally but goes like
black-normal-black-normal for a few mseconds. any ideas how to fix this?
Sorry for my bad english anyway.

J-Gamer

Don't load graphics in a thread that didn't create the display. It makes it go to memory bitmaps, instead of hardware-accelerated video bitmaps.

julian smit

so that means you always have to load the graphics in the presentation thread?
because than the presentation thread still freezes for a second when i load a map that needs new graphics.

J-Gamer

The thread that renders the screen should also load graphics... I don't know a workaround for that.

Elias

You can use al_clone_bitmap/al_convert_bitmap from the main thread (like ex_loading_thread in SVN does): https://github.com/elias-pschernig/allegro5/blob/master/examples/ex_loading_thread.c

AMCerasoli

Why al_convert_bitmap function name is so generic? I haven't read the specifications of this function but automatically means that convert from memory to video bitmap? or it's like a switch? if is a MB convert it to VB? and vice versa?

Matthew Leverton

It converts the bitmap to the current settings, much like:

bmp = al_clone_bitmap(bmp);

The main difference is that the original pointer is still valid.

julian smit

thanks, that helped alot.

Thread #608306. Printed from Allegro.cc