Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: [Résolu] Créer une sf::Texture dans un std::thread  (Lu 1991 fois)

0 Membres et 2 Invités sur ce sujet

Eho

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
    • E-mail
[Résolu] Créer une sf::Texture dans un std::thread
« le: Juin 29, 2014, 02:16:58 pm »
Bonjour

En cherchant à faire de la sérialisation bête et méchante, j'ai voulu créer une sf::Texture dans un thread (std::thread).

J'obtiens l'erreur suivante (Debian GNU/Linux, SFML 2.1)
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
main_sfml: ../../src/xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
Abandon

J'ai suivi ce que le message d'erreur suggére (cela corrige bien l'erreur) mais je ne souhaite pas avoir une solution pour X11 uniquement.

J'ai placé un mutex pour créer la texture et le rendu d'une frame :
// g++ -Wall -Wextra -Wconversion -Wsign-conversion -std=c++11 -pedantic -fopenmp -lsfml-window -lsfml-graphics -lsfml-system main_sfml.cpp -o main_sfml && ./main_sfml
// g++ -Wall -Wextra -Wconversion -Wsign-conversion -std=c++98 -pedantic -fopenmp -lsfml-window -lsfml-graphics -lsfml-system main_sfml.cpp -o main_sfml && ./main_sfml


#include <vector>
#include <thread>
#include <mutex>

#include <SFML/Graphics.hpp>

//#include <X11/Xlib.h>


int main()
{
        //XInitThreads();
       
        sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
       
        sf::Image image; image.create(200, 200, sf::Color::White);
       
        std::vector<sf::Sprite> sprites;
       
        std::mutex mutex;
       
        std::thread t
        (
                [&]() -> void
                {
                        std::this_thread::sleep_for(std::chrono::seconds(1));
                       
                        mutex.lock();
                        sf::Texture texture_thread;
                        mutex.unlock();
                       
                        texture_thread.loadFromImage(image);
                       
                        sprites.emplace_back(texture_thread);
                }
        );
       
        while (window.isOpen())
        {
                mutex.lock();
               
                {
                        sf::Event event;
                       
                        while (window.pollEvent(event))
                        {
                                if (event.type == sf::Event::Closed) { window.close(); }
                        }
                }
               
                window.clear();
               
                for (auto const & sprite : sprites)
                {
                        window.draw(sprite);
                }
               
                window.display();
               
                mutex.unlock();
        }
       
        t.join();
       
        return 0;
}
 

Est-ce une bonne solution (je n'ai pas encore testé sous Windows et OS X) ?
Qu'elles sont les autres solutions possibles (à part «ne pas utiliser de thread» et «créer les textures à l'avance») ?

Merci d'avance.
« Modifié: Juin 29, 2014, 10:30:39 pm par Eho »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Créer une sf::Texture dans un std::thread
« Réponse #1 le: Juin 29, 2014, 08:42:03 pm »
Ton mutex ne sert strictement à rien. La seule bonne solution est d'appeler XInitThreads, puisque c'est un problème propre à X.
Laurent Gomila - SFML developer

Eho

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
    • E-mail
Re : Créer une sf::Texture dans un std::thread
« Réponse #2 le: Juin 29, 2014, 10:28:42 pm »
Pourtant avec le mutex, le problème n'apparaît pas, même si je mets ce code dans le thread (compilé en -O0)
while (1)
{
        mutex.lock();
        sf::Texture texture_thread;
        mutex.unlock();
}

Si c'est un problème uniquement lié à X11, je vais appeler la fonction XInitThreads(); sur cette plate-forme.

Merci :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [Résolu] Créer une sf::Texture dans un std::thread
« Réponse #3 le: Juin 30, 2014, 07:33:26 am »
C'est normal. Puisque tu bloques tout ce qui se trouve dans le thread principal avec le mutex, tu annules la quasi totalité du parallèlisme et donc c'est comme si tu n'avais pas de thread.
Laurent Gomila - SFML developer