SFML community forums
Help => Window => Topic started by: klusark on February 10, 2010, 01:12:12 am
-
Im running SFML 2 revision 1395 on windows 7 x64 using msvc 2008. When the code below is run it outputs "Failed to activate the window's context". Am I doing something wrong?
Thanks.
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
sf::Window *window;
bool good;
void ThreadFunc(void* data)
{
sf::Context context; //Added this line
window->Create(sf::VideoMode(640,480), "test");
window->SetActive(false); //Added this line
good = true;
while (1)
sf::Sleep(1);
}
int main()
{
good = false;
window = new sf::Window();
sf::Thread mythread(&ThreadFunc, NULL);
mythread.Launch();
while (!good)
sf::Sleep(0.001f);
sf::Context context;
window->SetActive(true);
mythread.Terminate();
delete window;
return 0;
}
Edit: updated the code with working code.
-
Yes I am, I should be creating a context in the second thread and then doing SetActive(false). I have updated my first post with a working example for anyone else that has this problem.
-
I got the same problem this morning, I solved it by creating a useless context in the thread. (SFML2 on linux rev 1545)
I guess this is due to this function:
bool GlContext::SetActive(bool active)
{
if (active)
{
// Activate the context
if (MakeCurrent())
{
// If this is the first context to be activated on this thread, make
// it the reference context for the whole thread
if (!threadContext)
threadContext = this;
return true;
}
}
else
{
// Deactivate the context
if (threadContext && (threadContext != this))
{
// To deactivate the context, we actually activate another one
// so that we make sure that there is always an active context
// for subsequent graphics operations
return threadContext->SetActive(true);
}
}
// If we got there then something failed
return false;
}
Is there any other solution than creating a useless context (and make my application start slower)?
-
It's not a problem, it's how SFML 2 work. You have to create an OpenGL context in threads other than the main one if no window is active. That's why the sf::Context class exists.
-
It's not a problem, it's how SFML 2 work. You have to create an OpenGL context in threads other than the main one if no window is active. That's why the sf::Context class exists.
My problem is that there is no thread (even the main one) that do not call window::SetActive. The two threads share the same context and use it.
I guess this design is not compatible with the library.
here is an example:
window is an sf::Window and global to the 2 thread.
Thread 1
t = 1 | window creation
t = 2 | window->SetActive(true);
t = 3 | opengl calls..
t = 4 | opengl calls..
t = 5 | window->SetActive(false);
t = 6 | some non graphic stuffs...
t = 7 | some non graphic stuffs...
t = 8 | some non graphic stuffs...
t = 9 | some non graphic stuffs...
t = 10| window->SetActive(true); with no dummy context in thread 2, this fails too.
t = 11| opengl calls..
Thread 2
t = 1 | need a dummy context here.
t = 2 | some non graphic stuffs...
t = 3 | some non graphic stuffs...
t = 4 | some non graphic stuffs...
t = 5 | some non graphic stuffs...
t = 6 | window->SetActive(true);
t = 7 | opengl calls..
t = 8 | opengl calls..
t = 9 | window->SetActive(false); with no dummy context this fails
t = 10| some non graphic stuffs...
t = 11| some non graphic stuffs...
-
Can you show me a complete and minimal source code that reproduces this problem?
-
Sorry for the delay. In case you plan to fix this, here is the code:
#include <iostream>
#include <SFML/Window.hpp>
#include <X11/Xlib.h>
sf::Mutex mutex;
class EventLoopThread : public sf::Thread
{
public:
EventLoopThread(sf::Window* w)
: win_(w)
{
}
private:
void Run()
{
sf::Context context;
sf::Event event;
while (true)
{
mutex.Lock();
std::cout << "[thread 1] display start" << std::endl;
win_->SetActive(true);
win_->Display();
win_->SetActive(false);
std::cout << "[thread 1] display end" << std::endl;
mutex.Unlock();
}
}
sf::Window* win_;
};
int main()
{
sf::Window window(sf::VideoMode(100, 100), "SFML window");
EventLoopThread th(&window);
th.Launch();
while (window.IsOpened())
{
mutex.Lock();
std::cout << "[thread 0] display start" << std::endl;
window.SetActive(true);
window.Display();
window.SetActive(false);
std::cout << "[thread 0] display end" << std::endl;
mutex.Unlock();
}
}