SFML community forums

Help => System => Topic started by: kaesemeister on May 30, 2012, 09:57:30 pm

Title: threads and windows
Post by: kaesemeister on May 30, 2012, 09:57:30 pm
Hi,

I recently started to work with SFML.. seems to be a really nice and slim framework which fit's my needs..
I ran into problems when using one window in multiple threads. Background: I want to split my application into different threads:

- thread which render things on screen
- thread which processes user input
- and a few more...

but sadly I can't get it to work without the following exception:
Code: [Select]
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
...: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.

I called XInitThreads just to be shure that this is not the root of my problem.

My code has the following structure (simplified)

class RenderThread {
  virtual void Run() {
        while (active) {
                window.setActive(true);
                glClear(GL_COLOR_BUFFER_BIT);
                window.Display();
        }
  }
}

int main() {
        sf::Window window(sf::VideoMode(1024, 768, 32), "...");
        window.SetActive(false);
        window.UseVerticalSync(true);
       
        RenderThread renderThread(window);
        renderThread.Launch();
       
       
        sf::Event event;
        while (active) {
                // wait a bit to limit frequecy to 100Hz       
                while (window.GetEvent(event)) {
                        if (event.Type == sf::Event::Closed) {
                                active = false;
                        }
                }
        }
       
        renderThread.Wait();
        window.close();
       
        return EXIT_SUCCESS;
}
 

If i add Mutex Locks i can prevent the crash but everything get's extremly slow.

My Questions

Full source (it's still very simple): http://pastebin.com/hJKp7iBa

Title: Re: threads and windows
Post by: Laurent on May 30, 2012, 10:05:14 pm
It's the right way to do things, and XInitThreads should solve your problem. How do you call it?
Title: Re: threads and windows
Post by: kaesemeister on May 30, 2012, 10:13:29 pm
thanks for your fast reply..


Title: Re: threads and windows
Post by: Laurent on May 30, 2012, 10:19:32 pm
Quote
can you explain when I need this call?
Anywhere. At the beginning of the main() is perfect.

Quote
It should be sufficient to call window.setActive outside the loop inside the render thread, right?
Correct.

If I can find the time I'll try to test your code.
Title: Re: threads and windows
Post by: kaesemeister on May 30, 2012, 10:23:09 pm
Okay, thanks for your help..
do you or someone else know some working source which splits these tasks to different threads?
Title: Re: threads and windows
Post by: Laurent on May 30, 2012, 10:29:22 pm
Maybe you can find some on the forum. But they will most likely be similar to yours -- which should work on OS X and Windows, by the way. And XInitThreads() should be all you need to make it work on Linux too.
Title: Re: threads and windows
Post by: kaesemeister on May 30, 2012, 10:31:55 pm
ah.. good point.. i will read a bit into Xlib...
Title: Re: threads and windows
Post by: kaesemeister on May 31, 2012, 01:43:53 am
I switched to sfml2.0 and in combination with calling XInitThreads there is no exception anymore. Here is the code so far:

#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <X11/Xlib.h>

class RenderTask
{
public:
        RenderTask(sf::RenderWindow& window):window(window) {}
        virtual ~RenderTask() {}
       
        void run()
        {
                window.setActive();
                sf::Clock clock;
                while (window.isOpen()) {
                       
                        std::cout << clock.getElapsedTime().asMilliseconds() << std::endl;  
                        clock.restart();
                       
                        glClear(GL_COLOR_BUFFER_BIT);
                        window.display();
                }
        }
       
private:
        sf::RenderWindow& window;
};

int main(int argc, char **argv)
{
        XInitThreads();
       
        sf::RenderWindow window(sf::VideoMode(1024, 768), "Test", sf::Style::Close, sf::ContextSettings(32));
        window.setVerticalSyncEnabled(true);
        window.setActive(false);
       
        RenderTask renderTask(window);
        sf::Thread renderThread(&RenderTask::run, &renderTask);
        renderThread.launch();
       
        while (window.isOpen()) {
                sf::Event event;
                while (window.pollEvent(event)) {
                        if (event.type == sf::Event::Closed)
                                window.close();
                }
        }
       
        renderThread.wait();
       
        return 0;
}
 

But sadly there is still a problem. The printed framerates show very frequently peeks from up to 900ms.. i tried to fix this problems:

Maybe someone can test this code (removing X11 dependency) on windows or mac, and tell me if this issue exists there too. Just to make shure that this is a problem of SFMLs Xlib adapter.

My next step is to do the X stuff manually..
Title: Re: threads and windows
Post by: kaesemeister on May 31, 2012, 04:22:47 am
The peaks are gone.. adding "sf::sleep(sf::milliseconds(10));" at the end of the main loop seems to work.. maybe i've done a mistake in previous tests..

One problem remains:
If I close the program i get a segmentation fault in my graphics driver at cleanup.

I implemented a X11 version (still using SFML for OpenGL context):
http://pastebin.com/tRyDhkUd

I get a segmentation fault too.. Is it possible that there is a bug inside the driver (it's the official one from AMD). Since I do nothing special, the problem is somewhere in SFML or my code, i think.. 

Is it worth trying to fix this?  ::)
Maybe I try to do everything without SFML, just for finding the root of the problem..
Title: Re: threads and windows
Post by: Laurent on May 31, 2012, 08:04:42 am
I'm glad you solved your problem.

Quote
Is it worth trying to fix this?
Before deciding, use the debugger and see where it crashes.