Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Asynchronous loading (streaming data)

This thread is locked; no one can reply to it. rss feed Print
Asynchronous loading (streaming data)
roger levy
Member #2,513
July 2002

This just popped into my head, I'm not making a game that requires this per se, but the knowledge would be handy. For instance simply for making loading screens more entertaining.

Does Allegro support the ability to load data in a background thread? And in particular, Allegro-specific objects such as images and samples?

I hope to turn this into a discussion of streaming techniques with code examples.

Chris Katko
Member #1,881
January 2002
avatar

I think OpenGL only supports a single thread tied to the graphics context. You could probably write something that parses and decodes PNG's/etc into memory, and then queues them up in the main thread to be turned into textures.

[edit]

You can make a second context and load then share the data between contexts. But not all data, and there are other restrictions:

https://gamedev.stackexchange.com/questions/131825/opengl-threaded-loading

Seems like way more problems for little gain, in my opinion. But you know what you want to do.

Be sure to read the second answer for reasons not to do it.

It's not guaranteed that calls come in order between multiple threads so you can LOAD a texture, and the other thread attempts to USE it, before the first thread finishes uploading it.

http://higherorderfun.com/blog/2011/05/26/multi-thread-opengl-texture-loading/

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

roger levy
Member #2,513
July 2002

Sounds like the simple answer if you want to do some OpenGL-hacking is "no".

But I like your first solution. It wouldn't be the most efficient but it would get the job done. I wonder if the background thread could load compressed images as memory bitmaps and then the main thread turn those into video bitmaps? (to give the main thread more headroom)

EDIT:

I just did a little experiment and it worked! Very cool. I can load jpeg's into memory bitmaps in another thread and upload them to the GPU on the main thread once available.

What would be cool now is if the graphics driver could somehow be told to upload the texture asynchronously...

Edgar Reynaldo
Member #8,592
May 2007
avatar

Roger Levy said:

But I like your first solution. It wouldn't be the most efficient but it would get the job done. I wonder if the background thread could load compressed images as memory bitmaps and then the main thread turn those into video bitmaps? (to give the main thread more headroom)

Allegro can load memory bitmaps from any thread, however to use a thread it has to be converted to a video bitmap in main (or the thread that created the display you're drawing on)...

Main shows nice loading anime.

Thread A loads memory bitmaps, then signals main.

Main converts memory bitmaps to video bitmaps compatible with the display, and then finishes up.

So it will save you a little time... but not a lot these days unless you're loading large sets of assets.

roger levy
Member #2,513
July 2002

I just threw together a test program that does this and it works as described. It's my first foray into multithreaded programming ever, so I'm just tickled.

I am fascinated by games that utilize data streaming, such as Breath of the Wild.

EDIT:

Question: Does Allegro have to be initialized from the main thread? Same goes for creating display windows. Can I put my entire renderer in another thread?

Edgar Reynaldo
Member #8,592
May 2007
avatar

The one problem is that you can only draw on a display from the thread that created that display, otherwise the video bitmaps have no home... they have to be compatible with the display in use ie its context.

It's best to load in a thread and then convert in main. You can then use them normally, or in whatever thread you create your display on. So threads aren't that useful. You can work on memory bitmaps with threads, but no hardware accel.

You may be able to call al_init() from any thread, but I would call it from main, because it registers itself with atexit unless you specify null in al_install_system().

Roger Levy said:

Same goes for creating display windows. Can I put my entire renderer in another thread?

Yes, but I question what the benefit will be. Normally, adding threads only complicates things.

roger levy
Member #2,513
July 2002

I suppose it is more trouble than it is worth to think of ways to maximize the benefit of a rendering-only thread since you'd need to somehow give it all the necessary data without it affecting the game logic for the next frame. Making a full copy or some kind of display list system. I believe there is already some degree of built-in parallelism to GPU drivers as it is. And if you want more you might as well use Vulcan ... but we're not insane.

I think two definite good uses for threads at this point are disk operations and sound processing. If you initialize the audio library on another thread and set up a streaming callback it should be more likely to use another core, right?

Go to: