but in this case it's probably not SFML which is causing the problems
That's right, it's generally multi-threading and shared contexts with OpenGL.
Here are two
very interesting links:
-
http://www.opengl.org/wiki/OpenGL_and_multithreading-
http://developer.amd.com/gpu_assets/GDC2005_OpenGL_Performance.pdfIn the PDF start at slice 33.
I'd be very interested to see your most minimal/simple example that doesn't work as expected.
Here you go:
http://pastebin.com/bMeGSRpaKeep in mind what I said before: It doesn't work for some OS/GPU combinations only! I hadn't got any problems, it were 2 out of 12 users who had problems when I loaded textures in parallel (both Win7 64 bit, AMD GPU, latest drivers at that time).
you have to store all the intermediate images, consuming unnecessary memory, and map them to some unique ID (which may not be a filename) so that you can assign them to their matching sf::Texture.
At first, you do not consume unnecessary memory: You also consume the same amount of memory when doing loadFromFile(), except for a shorter time. When loading images in parallel and finalizing the textures in an update() step, yes, memory is used for a larger time – some milliseconds maybe. That's definitely not an issue.
Also you do not need to map anything, the details are hidden in your class design. In FlexWorld for example as soon as a texture is requested, a pointer is held to the same object – if it has the texture initialized already or not. When it gets ready, it's used. If not, then you see just nothing. But as this happens only for a couple of milliseconds, it's not noticable.
That of course depends on your OOP skill. If you use only SFML's classes, then yes, you have to keep mappings somewhere. But for everything else than Pacman or other smaller projects you'll likely have some sort of resource management externally that takes care of such things.
And avoid a big freeze of the application when you do it.
Again: You can't avoid freezes that happen due to texture preparation (except you're using pixel buffers, but that's another topic). Freezes are mostly the result of time spent both on the hard-disk and decompression. So if that's the bottleneck, I have to avoid it – not loading textures to the GPU which can't be made faster.
Seriously, am I the kind of guy to implement such a big feature if it is useless?
Normally not, this is why I'm surprised you want to keep it, even if it means having issues. ;-) Seriously, I just searched the forums for "multiple windows" and found some threads. Not a single thread revealed what they're used for except "Can I do it?".
Besides of that: Multiple windows are of course still possible, the critical part is the shared context. If you have two isolated contexts for each window, everything's fine, no issues. So I rather ask to drop the shared context, sorry for being unclear.
By the way... can you remind me how disabling shared contexts and multiple windows would help to solve the initial problem? Why are we discussing these details?
I rechecked a recent stacktrace of an SFGUI crash. Take a look at it:
ntdll.dll!77d9a2ce()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
Label.exe!sf::priv::MutexImpl::Lock() Line 52 + 0xc bytes C++
Label.exe!sf::Mutex::Lock() Line 62 C++
Label.exe!sf::Lock::Lock(sf::Mutex & mutex) Line 39 C++
Label.exe!sf::priv::WglContext::CreateContext(sf::priv::WglContext * shared, unsigned int bitsPerPixel, const sf::ContextSettings & settings) Line 315 + 0x10 bytes C++
Label.exe!sf::priv::WglContext::WglContext(sf::priv::WglContext * shared) Line 59 C++
Label.exe!sf::priv::GlContext::New() Line 142 + 0x28 bytes C++
Label.exe!`anonymous namespace'::GetInternalContext() Line 87 + 0x5 bytes C++
Label.exe!sf::priv::GlContext::EnsureContext() Line 135 + 0x7 bytes C++
Label.exe!sf::GlResource::EnsureGlContext() Line 83 C++
Label.exe!sf::Texture::~Texture() Line 98 C++
Label.exe!sfg::Renderer::~Renderer() Line 45 + 0x36 bytes C++
Label.exe!sfg::Renderer::`scalar deleting destructor'() + 0x16 bytes C++
Label.exe!sfg::ReferenceCount<sfg::Renderer>::Dispose() Line 61 + 0x1f bytes C++
Label.exe!sfg::ReferenceCountBase::RemoveStrongReference() Line 34 + 0xf bytes C++
Label.exe!sfg::StrongReferenceCount::~StrongReferenceCount() Line 84 C++
Label.exe!sfg::SharedPtr<sfg::Renderer>::~SharedPtr<sfg::Renderer>() + 0x19 bytes C++
Label.exe!`dynamic atexit destructor for 'sfg::Renderer::m_instance''() + 0xd bytes C++
Label.exe!doexit(int code, int quick, int retcaller) Line 567 C
Label.exe!exit(int code) Line 393 + 0xd bytes C
Label.exe!__tmainCRTStartup() Line 284 C
Label.exe!mainCRTStartup() Line 189 C
kernel32.dll!76cb339a()
ntdll.dll!77d79ef2()
ntdll.dll!77d79ec5()
You could of course also try to workaround resource destruction by checking if there's a valid context and if not skip the cleanup (Texture::~Texture). But imho the context management is somewhat messed up.