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

Author Topic: threads and windows  (Read 4441 times)

0 Members and 1 Guest are viewing this topic.

kaesemeister

  • Newbie
  • *
  • Posts: 6
    • View Profile
threads and windows
« 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
  • Is the general concept okay?
  • When to call setActive? (it's used to connect the opengl context to the active thread, right?)
  • If the concept is bullshit, what's the right way to split eventhandling, inputhandling and rendering?
  • Is there an example which demonstrates how to do it?

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


Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: threads and windows
« Reply #1 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?
Laurent Gomila - SFML developer

kaesemeister

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: threads and windows
« Reply #2 on: May 30, 2012, 10:13:29 pm »
thanks for your fast reply..

  • i just call the function XInitThreads()... it's the first call in the main function.. (but it didn't solved the problem, as i said)
  • can you explain when I need this call?
  • It should be sufficient to call window.setActive outside the loop inside the render thread, right? If not, why?


Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: threads and windows
« Reply #3 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.
Laurent Gomila - SFML developer

kaesemeister

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: threads and windows
« Reply #4 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?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: threads and windows
« Reply #5 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.
Laurent Gomila - SFML developer

kaesemeister

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: threads and windows
« Reply #6 on: May 30, 2012, 10:31:55 pm »
ah.. good point.. i will read a bit into Xlib...

kaesemeister

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: threads and windows
« Reply #7 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:
  • replaced while condition with a boolean
  • added a sf::sleep to the main loop to limit it at 100Hz

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..

kaesemeister

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: threads and windows
« Reply #8 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..

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: threads and windows
« Reply #9 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.
Laurent Gomila - SFML developer