SFML community forums
Help => Graphics => Topic started 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:
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:
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? :?
-
You need a sf::Context in your thread to perform graphical operations.
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);
}
-
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:
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();
}
-
It should be ok now, but... I may have awoken an old bug involving GLX and ATI cards. Not sure :?
-
[...] 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]
-
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?
-
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:
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
-
Ok, thanks...
-
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)
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:
#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)?
-
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 ;)
-
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.
-
"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).
-
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.
-
Maybe I have a solution, I'll let you know when it's ready so that you can test it.
-
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)
-
I've commited my new fix, can you test it?
-
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.