Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Solved] Loading Images Inside a Thread  (Read 36335 times)

0 Members and 1 Guest are viewing this topic.

lzr

  • Newbie
  • *
  • Posts: 48
    • View Profile
    • http://lzr.cc
[Solved] Loading Images Inside a Thread
« on: April 30, 2008, 07:50:51 am »
I am in the long process of porting a game from Direct3d/Win32 to SFML, and before I did all my loading on a separate thread, while a loading animation played in the main thread. For some reason, all the images I load while in the separate thread come out as blank, white, boxes. Is there any way to fix this?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
[Solved] Loading Images Inside a Thread
« Reply #1 on: April 30, 2008, 09:15:20 am »
That's because your OpenGL context is bound to the main thread, thus any OpenGL call occuring in the secondary thread will fail (the standard error output should be full of messages).

The solution would be to unbind the OpenGL context from the main thread (Window::SetActive(false)), bind it to the secondary one and load your images. But it wouldn't work in this case because you still need the context in the main thread to display your animation.

You would be able to do what you want if OpenGL was not restricted to one thread at a time, but that's not the case.
Laurent Gomila - SFML developer

workmad3

  • Jr. Member
  • **
  • Posts: 71
    • View Profile
[Solved] Loading Images Inside a Thread
« Reply #2 on: May 01, 2008, 08:50:39 am »
Hmm... considering how multi-threaded SFML is and designed to be, wouldn't it be prudent to provide an 'OGL wrapper thread' that can track OGL drawing and state calls in a queue and get all the OGL calls done in a single thread to avoid issues like this? I was just considering the possibility of writing my own but then realised it would have problems with SFML code which would be making it's own calls to OGL in the same period.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
[Solved] Loading Images Inside a Thread
« Reply #3 on: May 01, 2008, 10:10:50 am »
Hmm... and how would you do that ?
Laurent Gomila - SFML developer

lzr

  • Newbie
  • *
  • Posts: 48
    • View Profile
    • http://lzr.cc
[Solved] Loading Images Inside a Thread
« Reply #4 on: May 02, 2008, 01:11:47 am »
I think what workmad3 is suggesting is that you move all OpenGL operations to a completely separate thread that watches a queue that contains a list of the operations that need doing. This would work, but could complicate a lot. Would all the OpenGL calls then become asynchronous? That actually might be kind of cool.

Another thing that might work (I don't know, I've never tried) is to lock an in-engine mutex before every OpenGL command. That way OpenGL is never called in two threads at once and you can ensure that it is always activated in the current thread. Since most of the loading time isn't spent calling OpenGL, the loading animation would still play for most of the time.

I do think that since the engine supports threads, there should be some internal handling of problems like this.

BTW, thanks for your hard work, sorry if I'm asking for too much.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
[Solved] Loading Images Inside a Thread
« Reply #5 on: May 02, 2008, 05:06:52 am »
Quote
I think what workmad3 is suggesting is that you move all OpenGL operations to a completely separate thread that watches a queue that contains a list of the operations that need doing. This would work, but could complicate a lot. Would all the OpenGL calls then become asynchronous? That actually might be kind of cool.

That would definitively be complicated and even might slowdown global performances.

Quote
Another thing that might work (I don't know, I've never tried) is to lock an in-engine mutex before every OpenGL command. That way OpenGL is never called in two threads at once and you can ensure that it is always activated in the current thread. Since most of the loading time isn't spent calling OpenGL, the loading animation would still play for most of the time

I can't bind OpenGL to a thread if you haven't first unbound it from the other thread.

In conclusion, I can't help much about threading issues, as it's highly related to pure OpenGL stuff.
Laurent Gomila - SFML developer

workmad3

  • Jr. Member
  • **
  • Posts: 71
    • View Profile
[Solved] Loading Images Inside a Thread
« Reply #6 on: May 03, 2008, 06:12:18 pm »
Its a common problem with OGL and one of the 'standard' solutions is as I described... all OGL operations need to be in a single thread, so a complete OGL wrapper is created to do this... it provides wrapper functions for all OGL calls (close to the normal OGL names) or even a more flexible system that allows extensions as well, and queues them all up to be executed in a single thread.

The reason I suggest it as part of SFML is because SFML itself uses OGL, so any third party solution would either need to rewrite some SFML stuff to use the wrapper, or deal with issues of SFML not using the wrapper.

As for complexity and performance... yes it would increase complexity and decrease performance slightly, but it would increase the ease-of-use of the library when users are integrating with OGL themselves.

It would still have problems if people ignored the OGL wrapper as then you would have issues with 2 threads still (especially if the user binds OGL to their own thread, meaning SFML loses itscontrol of the API) but as there can be worse consequences on some peoples machines than just blank screens (I've heard it can do things like corrupt the stack and crash applications and possibly even the computer), it may be worthwhile to investigate possible solutions to the multi-threaded OGL problem. Of course, all these problems may be solved when OGL 3.0 is finally released and implementations appear :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
[Solved] Loading Images Inside a Thread
« Reply #7 on: May 03, 2008, 06:29:03 pm »
What about the 95% of users who won't use multithreading, and get the cost of threads and mutex locking for each OpenGL call they do through SFML ?

In fact... do you have some solid test / reference when you say "decrease performance slightly" ? ;)
Laurent Gomila - SFML developer

workmad3

  • Jr. Member
  • **
  • Posts: 71
    • View Profile
[Solved] Loading Images Inside a Thread
« Reply #8 on: May 03, 2008, 11:11:31 pm »
with the simplicity of multi-threading with SFML, do you have any statistics showing it's only 5% that use threading? ;) It's certainly something I'm relying on heavily in the code I'm writing at the moment due to it's simplicity.

As for slightly... I don't have any solid reference data, but the process is a very common pattern, especially with what I do at work where performance is a major concern :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
[Solved] Loading Images Inside a Thread
« Reply #9 on: May 04, 2008, 08:13:44 am »
It seems we need a real benchmark ;)

I'll try to implement it and do some tests. I'll let you know the results.
Laurent Gomila - SFML developer

workmad3

  • Jr. Member
  • **
  • Posts: 71
    • View Profile
[Solved] Loading Images Inside a Thread
« Reply #10 on: May 04, 2008, 08:18:48 pm »
Sounds good :)

I'll have a go too when I have a chance, see what sort of implementation I can come up with myself ;)

deps

  • Newbie
  • *
  • Posts: 14
    • View Profile
[Solved] Loading Images Inside a Thread
« Reply #11 on: May 09, 2008, 01:13:40 pm »
Just one idea that popped up in my head while reading this.

How about you load the images into the system RAM instead of the graphics memory? (Like in the good old days)
Add a flag to the image loading functions to let people decide for them self if they want to use this.
Then, when the thread is finished you just call a function that transfers it into graphics memory. Would that work? Or do the image loading code depend much on OpenGL?

Forgive me if it was a silly idea, I'm not that skilled when it comes to lowlevel stuff. :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
[Solved] Loading Images Inside a Thread
« Reply #12 on: May 09, 2008, 02:55:50 pm »
I first thought it was not a good idea, but then I realized that it could easily be done without altering the public interface, nor requiring extra calls from the user.

I modified the code so that internal OpenGL textures are now not created right after loading, but rather on first use. So that loading can be done anywhere with no restriction.

Thanks for the idea :)
Laurent Gomila - SFML developer

deps

  • Newbie
  • *
  • Posts: 14
    • View Profile
[Solved] Loading Images Inside a Thread
« Reply #13 on: May 09, 2008, 03:26:42 pm »
:shock:

I... I made an contribution? Holy crap!  :lol:

How about a function to create the internal textures right away? Some people might want to know that everything is loaded and ready when the main loop starts. (just to make everyone happy :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
[Solved] Loading Images Inside a Thread
« Reply #14 on: May 09, 2008, 04:35:20 pm »
Quote
How about a function to create the internal textures right away? Some people might want to know that everything is loaded and ready when the main loop starts. (just to make everyone happy

There's no point doing that, people just want to know that everything's working as expected and shouldn't care about the internal stuff as long as it has no impact on the external behaviour.
Laurent Gomila - SFML developer