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

Author Topic: "Failed to share the OpenGL context" when loading texture in a thread [Solved]  (Read 6080 times)

0 Members and 1 Guest are viewing this topic.

Xyst

  • Guest
I've run into this problem while trying to load a texture in a thread. It works for a while, but after a few iterations the error "Failed to share the OpenGL context" pops up. After some more iterations, "An internal OpenGL call failed in Texture.cpp <n> : GL_INVALID_OPERATION, the specified operation is not allowed in the current state" is written 15 times, with n changing between 38, 45, 95, 136, 144-149, 198, 335, 336 and 498. I've narrowed down the problem to this snippet of code:

#include <iostream>
#include <SFML/Graphics.hpp>

void getMandelbrot() {
    sf::Context context;
    std::cout << "rendering... ";
    sf::Image image;
    image.create(100, 100);
    sf::Texture texture;
    texture.loadFromImage(image);
    std::cout << "done \n";
}

int main() {

    sf::RenderWindow window(sf::VideoMode(300, 300), "Test");

    sf::Thread update(&getMandelbrot);

    while (window.isOpen()) {
        sf::Event event;

        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        update.launch();
    }

}
 

The problem seems to lie in "texture.loadFromImage(image);". Removing sf::Context context doesn't change anything.
« Last Edit: October 05, 2015, 11:40:54 pm by Xyst »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: "Failed to share the OpenGL context" when loading texture in a thread
« Reply #1 on: October 05, 2015, 10:33:34 am »
How much time did you invest in looking if there are similar issues reported on the forum? ;)

Each thread you create/launch will create its own OpenGL context. Due to SFML's current implementation contexts get only freed at the end of the application's lifetime.
Reuse the thread by letting it sleep, or don't use threads at all.

As a note to your code, OpenGL is not multi-threaded so loading an image into VRAM in a separate thread does not gain you any advantage. If you want to do something in parallel, load the image from disk into VRAM in a separate thread and then you can upload it to VRAM in your main thread.
In the end you'll have to know a lot about threading before you can use it without creating possible crashes etc.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Xyst

  • Guest
Re: "Failed to share the OpenGL context" when loading texture in a thread
« Reply #2 on: October 05, 2015, 11:39:51 pm »
Ok, thanks for the info! I actually tried finding a solution, but could for some reason not find anything that I could apply to my code.

Putting the code to be executed in an endless loop fixed the problem! The reason I want to load images in a separate thread is for a fractal explorer, I wanted to be able do render the image without it stopping the application.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: "Failed to share the OpenGL context" when loading texture in a thread
« Reply #3 on: October 06, 2015, 12:14:25 am »
Putting the code to be executed in an endless loop fixed the problem! The reason I want to load images in a separate thread is for a fractal explorer, I wanted to be able do render the image without it stopping the application.
As I said, OpenGL is not multi-threading capable. Any call you make will be put onto the queue that gets processed one at a time. Doing OpenGL work from a separate thread has only its uses in very edge cases for people with a lot of experience in OpenGL and parallel programming.
So again, you can load the image from disk in a separate thread, but you don't gain anything (if you don't actually lose performance) by calling loadFromImage in the separate thread.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Xyst

  • Guest
The thing is that I want to render a fractal, which is quite resource heavy (takes about 5 seconds). I don't want the whole application to freeze up while doing this, so having the rendering of the fractal in a separate thread was the only solution I could find. Making the function an infinite loop let me "call" it, without having to launch a new thread each time.

So, the reason that I'm loading the image in a separate thread is to be able to generate the fractal while doing other things, simultaneously.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Maybe you should separate the computation of the fractal from the rendering.

Rendering alone doesn't take a lot of time.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Xyst

  • Guest
Hm, didn't think of that. Will make sure to keep it in mind if i ever run into this situation again