SFML community forums

Help => Graphics => Topic started by: gsaurus on September 13, 2010, 05:35:00 pm

Title: Graphical operations in a thread
Post by: gsaurus on September 13, 2010, 05:35:00 pm
Hi,

My images loading code was working fine, until I put a thread doing the job.
Here is the minimal code:

Code: [Select]

class ThreadProblems : public sf::Thread{
private:
    void Run(){
        unsigned int width = 150;
        unsigned int height = 100;
        sf::Uint8 pixelsData[width*height*4];
        sf::Image img;
        img.LoadFromPixels(width, height, pixelsData);
    }
};

int main(){
    ThreadProblems t;
    t.Launch();
    t.Wait();
}



std::cerr:

Quote
An internal OpenGL call failed in Image.cpp (549) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (624) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (630) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (631) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (632) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (633) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (634) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (635) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (636) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (637) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
An internal OpenGL call failed in Image.cpp (758) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state


What's happening here?  :?
Title: Graphical operations in a thread
Post by: Laurent on September 13, 2010, 06:07:27 pm
You need a sf::Context in your thread to perform graphical operations.

Code: [Select]
void Run(){
        sf::Context context;

        unsigned int width = 150;
        unsigned int height = 100;
        sf::Uint8 pixelsData[width*height*4];
        sf::Image img;
        img.LoadFromPixels(width, height, pixelsData);
}
Title: Graphical operations in a thread
Post by: gsaurus on September 13, 2010, 06:48:18 pm
I see, thank you Laurent  :)

However if I create and destroy a window before launching the thread, I get a "Failed to share the openGL context".
I'm not thinking on doing such thing on my app, just curious.

code:
Code: [Select]
class SomeThread : public sf::Thread{
private:
    void Run(){
        sf::Context context;
        sf::Image img;
        img.Create(100,100);
    }
};

int main(){
    {  // you know, minimal code!
        sf::RenderWindow app(sf::VideoMode(800, 600, 32), "something");
    }
    SomeThread t;
    t.Launch();
    t.Wait();
}
Title: Graphical operations in a thread
Post by: Laurent on September 14, 2010, 09:02:18 pm
It should be ok now, but... I may have awoken an old bug involving GLX and ATI cards. Not sure :?
Title: Graphical operations in a thread
Post by: Beliar on September 16, 2010, 01:36:38 pm
Quote from: "Laurent"
[...] I may have awoken an old bug involving GLX and ATI cards. Not sure :?


If you mean this : http://www.sfml-dev.org/forum/viewtopic.php?t=1426
then yes, you have :(

[edit]
Of course the problem could be that i create from a already present handle from wxWdigets 2.9, though that worked with SFML 1.6 (after a few modifications to wxSFMLCanvas)
[/edit]
Title: Graphical operations in a thread
Post by: Laurent on September 16, 2010, 02:18:20 pm
Quote
Of course the problem could be that i create from a already present handle from wxWdigets 2.9, though that worked with SFML 1.6 (after a few modifications to wxSFMLCanvas)

Can you test the minimal example above, as well as the one in the thread that you linked?
Title: Graphical operations in a thread
Post by: Beliar on September 16, 2010, 03:15:43 pm
The code above, the simple code taken from the RenderWindow tutorial and the minimal example you posted on the first page of the thread all give this:

Code: [Select]
X Error of failed request:  GLXBadContext
  Major opcode of failed request:  155 (GLX)
  Minor opcode of failed request:  3 (X_GLXCreateContext)
  Serial number of failed request:  24
  Current serial number in output stream:  29
Title: Graphical operations in a thread
Post by: Laurent on September 16, 2010, 03:34:53 pm
Ok, thanks...
Title: Graphical operations in a thread
Post by: Beliar on September 16, 2010, 03:44:37 pm
Not sure if that was already mentioned in the other thread, but if i comment out this line (and leave everything else as it was)
Code: [Select]
CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0));

in GlxContext::GlxContext in in GlxContent.cpp, the error is  not shown and the following minimal example does work fully:

Code: [Select]
#include <iostream>
#include <SFML/Graphics.hpp>

sf::Image image;
void ThreadFunc(void*)
{
   sf::Context context;
   sf::Sleep(1.f);
   image.LoadFromFile("rock.png");
   std::cout << "OK!" << std::endl;
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Testsuite");

    sf::Thread thread(&ThreadFunc);
    thread.Launch();

    while (window.IsOpened())
    {
        sf::Event event;
        while (window.GetEvent(event))
        {
            if ((event.Type == sf::Event::KeyPressed && event.Key.Code == sf::Key::Escape)
                || (event.Type ==sf::Event::Closed))
                window.Close();
        }

        window.Clear();
        window.Draw(sf::Shape::Rectangle(0, 0, 100, 100, sf::Color::White));
        window.Display();
    }

    return 0;
}


I am not sure what this line is supposed to do though, so it probably broke something else.

[Edit]
Ok, when i try to draw the image that was loaded (and comment out the drawing of the Shape) only a white rectangle is shown. The image is drawn when loaded from the main function though, so i guess thats what the line is for (threading)?
Title: Graphical operations in a thread
Post by: Laurent on September 16, 2010, 03:58:37 pm
What this call does is to create the OpenGL contexts that are not linked to a window: sf::Context and the dummy global one with which every other context is shared. So yes, removing it breaks a lot of things ;)
Title: Graphical operations in a thread
Post by: Beliar on September 17, 2010, 12:18:36 am
Hmm, i just found out something that seems strange:
Commenting out "if (shared)" does fix the error, but when i debug it and set a breakpoint there (when the line is not commented out) it evaluates to true and SetActive(true); is called. When the line is commented out that is called too, so it seems that whatever "if (shared)" implicitly does, produces the error.
Title: Graphical operations in a thread
Post by: Laurent on September 17, 2010, 08:08:33 am
"if (shared)" is false only once: it's when constructing the very first context, the one constructed at global startup and that will be shared with all others (so the "shared" argument will then always be a pointer to this context).
Title: Graphical operations in a thread
Post by: Beliar on September 17, 2010, 08:44:06 am
hmm, yeah, seems like its the second time the construcor is called is when the error happens. The debugger jumped directly from that line to "ContextType defaultContext(&referenceContext);" so i thought that, for whatever reason, the if statement called this.

Well, i guess i surely won't find anything that was not already found in the other thread, so i guess i read through that.
Title: Graphical operations in a thread
Post by: Laurent on September 17, 2010, 08:56:17 am
Maybe I have a solution, I'll let you know when it's ready so that you can test it.
Title: Graphical operations in a thread
Post by: Beliar on September 17, 2010, 09:28:34 am
Ok, i'll watch for that. Anyway, i just ruled out that its the Gallium3D* drivers i use, since the error happens when using the normal xorg-video-ati/radeon drivers too.

*Since the officical drivers from AMD don't support my card anymore these are the only way to get better 3d functionality (like GLSL)
Title: Graphical operations in a thread
Post by: Laurent on September 17, 2010, 06:46:50 pm
I've commited my new fix, can you test it?
Title: Graphical operations in a thread
Post by: Beliar on September 17, 2010, 09:06:02 pm
It does seem to work, i don't get any errors and most examples run (except shader but that doesn't run in the previous revision too)

So, i guess its fixed, thanks.