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

Auteur Sujet: sf::RenderTexture prends énormément de ressource CPU.  (Lu 8267 fois)

0 Membres et 1 Invité sur ce sujet

gaulois94

  • Sr. Member
  • ****
  • Messages: 259
    • Voir le profil
sf::RenderTexture prends énormément de ressource CPU.
« le: Juin 27, 2012, 01:04:12 am »
Bonsoirs,

voila j'écris ce message pour signaller que plus une RenderTexture est grande, plus les ressources CPU utiliser le sont aussi. Pour vous le montrer, voici deux screens :
renderTexture petite (100/50)

 sa me prends 10% de mon CPU.

et maintenant le même code, avec comme renderTexture de taille (800/600).

et là ben sa me prends 41% de mon CPU !!! WTF :o J'utilises pourtant le même algorithme je vous le rassure ;) .

Sachez que si je créer un Button, je n'ai que 2% de mon CPU qui est utilisé (il y a tout une surcouche derrière), alors que pour ma Frame, sa me prends quand même jusqu'à 41% !!!

Bon c'est sympa les chiffres, mais on aimerai bien savoir d'où sa vient ce petit monde, et comme je suis gentil, voici comment est fait la gestion de la Frame :

main.cpp
#include "Widget.h"
#include "Button.h"
#include "Window.h"
#include "Frame.h"
#include "equation.h"
#include <iostream>

int main()
{
guiml::Window window(sf::VideoMode(800, 600), "teste");
guiml::Frame frame(&window, sf::FloatRect(0, 0, 800, 600), sf::Color::Blue, guiml::Image(), guiml::Label(NULL, std::string("teste")), sf::Color::Red); //création de la Frame, ayant pour parent window, de position(0, 0) et de taille(800, 600), de fond Bleu sans image derrière de titre "teste" à fond rouge.
while(window.isOpen())
{
window.update(); //là on update la fenêtre, et donc par la même occasion la Frame.
}
return 0;
}

Frame.cpp (Frame hérite de Widget et de RenderTexture).
void Frame::update(std::list<sf::Drawable*> &drawable)
{
if(m_isDrawing) //si on veut dessiner la Frame
{
if(isMoving() && getEventManager()) //si le bouton rouge est sélectionner et que le parent racine est une fenêtre (en gros si Frame est dans une WIndow)
{
sf::Vector2f newMousePosition = getEventManager()->getMousePosition();
setPosition((newMousePosition.x/m_multiplicateMousePos.x)-m_mousePos.x, (newMousePosition.y/m_multiplicateMousePos.y)-m_mousePos.y); //m_multiplicateMousePos est là pour gérer les redimensionnement de la fenêtre (si la fenêtre passe de 800/600 à 1200/1000 par exemple, la souris sera a des positions différentes. Le multiplicate est là pour pallier au problème).
}
for(std::list<Widget*>::iterator it = m_child.begin(); it != m_child.end(); ++it) //On bouge tout les fils en arrière. Normale, quand on donne une position, on le donne relativement à la Frame, mais pour les évènements de la souris, la position doit être relatifs à la fenêtre.
(*it)->move(m_virtualPos.x, m_virtualPos.y);

clear(m_backgroundColor);
std::list<sf::Drawable*> drawableForFrame; //List qui contiendra les drawable que la Frame déssinera (ici c'est le trucs rouge + le titre).
Widget::update(drawableForFrame); //on update le Button (dans le screen, il n'y a qu'un Button : c'est le trucs rouge en haut qui permet de déplacer la Frame).
show(drawableForFrame);
drawable.push_back(&m_spriteFrame); //drawable est la list de Drawable que Window déssinera.

for(std::list<Widget*>::iterator it = m_child.begin(); it != m_child.end(); ++it) //on remet tout le monde en place.
(*it)->move(-m_virtualPos.x, -m_virtualPos.y);
}
}

void Frame::show(std::list<sf::Drawable*> &drawable)
{
for(std::list<sf::Drawable*>::iterator it = drawable.begin(); it != drawable.end(); ++it) //on dessiner ce que contient drawable.
draw(*(*it));
display();
m_spriteFrame.setTexture(getTexture()); //n'oubliez pas que Frame hérites de RenderTexture.
m_spriteFrame.setPosition(sf::Vector2f(m_virtualPos.x, m_virtualPos.y)); Et on place tout à la bonne position.
        }

Bon ben voila, je crois que j'ai suffisamment documenté le code pour que vous le compreniez rapidement ;) . J'aimerai donc savoir pourquoi plus la taille de la Frame augmente, plus les ressources CPU sont élevées.

Merci d'avance ;) .

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #1 le: Juin 27, 2012, 08:13:14 am »
Ca dépend de ton matos et de tes drivers.

Mais avant de chercher plus en détail la raison, tu devrais isoler ça dans un code complet minimal (avec juste une RenderTexture et des sprites), parce que pour moi le problème pourrait tout aussi bien venir de ton propre code ;)
Laurent Gomila - SFML developer

gaulois94

  • Sr. Member
  • ****
  • Messages: 259
    • Voir le profil
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #2 le: Juin 27, 2012, 10:03:48 am »
Je suis sous linux avec un dual core 2.4 GHz, je pense que sa devrait suffire ;) . Je vais isoler le code pour voir si sa peut venir de moi ;) .

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #3 le: Juin 27, 2012, 10:13:03 am »
Citer
Je suis sous linux avec un dual core 2.4 GHz
Ce qui compte c'est plutôt la carte graphique et son driver.
Laurent Gomila - SFML developer

gaulois94

  • Sr. Member
  • ****
  • Messages: 259
    • Voir le profil
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #4 le: Juin 27, 2012, 10:49:47 am »
Nvidia 6150 SE avec le dernier driver propriétaire disponible sous archlinux.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #5 le: Juin 27, 2012, 11:11:08 am »
Citer
Nvidia 6150 SE
Ca n'a pas l'air très costaud.

Enfin bref, fais déjà des tests sur des codes simples de façon à identifier le problème clairement.
Laurent Gomila - SFML developer

gaulois94

  • Sr. Member
  • ****
  • Messages: 259
    • Voir le profil
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #6 le: Juin 27, 2012, 11:16:43 am »
C'est pas du tout costaud c'est vrai, mais de là à que mon CPU va à 40% pour une Frame en fullscreen... Sa aurait été de la 3D, j'aurai été d'accord, mais de la 2D, en plus avec opengl... M'enfin, je vais testé tout sa ;) .

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #7 le: Juin 27, 2012, 11:23:56 am »
Oui effectivement, je n'ai pas non plus dit que c'était normal ;)

Mais ce genre de puces graphiques a généralement des problèmes avec la classe RenderTexture.
Laurent Gomila - SFML developer

gaulois94

  • Sr. Member
  • ****
  • Messages: 259
    • Voir le profil
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #8 le: Juin 27, 2012, 12:01:24 pm »
Voila, j'ai refait un code pour la Texture, et voila ce que j'obtient :

#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
        sf::RenderWindow window(sf::VideoMode(800, 600, 32), std::string("teste"));
        sf::RenderTexture renderTexture;
        renderTexture.create(100, 50);
        sf::Texture texture;
        texture.loadFromFile("rectangle.jpg"); //rectangle jaune.
        sf::Sprite sprite(texture);
        window.setFramerateLimit(60);  

        while(window.isOpen())
        {
                window.clear();
                renderTexture.clear(sf::Color::Blue);
                renderTexture.draw(sprite);
                renderTexture.display();
                sf::Sprite renderSprite(renderTexture.getTexture());
                window.draw(renderSprite);
                window.display();
        }
}

Résultat : 10% du CPU. Maintenant, pour une texture de 800/600, sa me prends 37% du CPU (on est relativement proche du gros code de ma GUI). Je pense donc dire que c'est les RenderTexture qui prennent énormément de ressources CPU.
« Modifié: Juin 27, 2012, 12:18:37 pm par Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #9 le: Juin 27, 2012, 12:20:55 pm »
Ca me semble clair, oui. Ca craint ;D
Laurent Gomila - SFML developer

gaulois94

  • Sr. Member
  • ****
  • Messages: 259
    • Voir le profil
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #10 le: Juin 27, 2012, 12:24:40 pm »
Arf, il n'y a pas moyens que les calcules soient faites sur le GPU ? Parce que 40%, c'est pas pour dire, mais la totalité de mes programmes utilisent moins de ressources que ça x) .

En espérant que ceci soit corrigé dans une prochaine version de la SFML ;) (ou que je m'achète une vrai carte graphique :p ).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #11 le: Juin 27, 2012, 12:33:54 pm »
Tout est fait sur le GPU, justement. Si tu commentes "renderTexture.display();" (le réstulat sera choucrouté mais on s'en fout), ça donne quoi au niveau du % CPU ?
Laurent Gomila - SFML developer

gaulois94

  • Sr. Member
  • ****
  • Messages: 259
    • Voir le profil
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #12 le: Juin 27, 2012, 12:37:02 pm »
Toujours le même pourcentage au niveau du CPU (aux alentours de 38%) à la différence près où mon rectangle se situe en bas à gauche x) .

D'ailleurs sa m'ettone que je peux récupérer la texture de la RenderTexture sans faire de display() (moi qui pensait que c'était indispensable).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #13 le: Juin 27, 2012, 12:46:39 pm »
C'est indispensable pour avoir le résultat correct, pas pour avoir le résultat tout court. En fait lorsque tu dessines sur la render-texture, ça dessine directement sur la texture finale. il n'y a pas d'étape supplémentaire comme avec RenderWindow (buffer interne vers écran). Le display() n'est là que pour remettre la texture à l'endroit.

Bon, du coup ce n'est pas du tout ce que je pensais. Essaye de virer le dessin du sprite sur la RenderTexture ? Ou encore le dessin de la RenderTexture sur la fenêtre ? Il faut trouver l'appel qui prend tout le CPU.
Laurent Gomila - SFML developer

gaulois94

  • Sr. Member
  • ****
  • Messages: 259
    • Voir le profil
Re : sf::RenderTexture prends énormément de ressource CPU.
« Réponse #14 le: Juin 27, 2012, 12:57:26 pm »
Le window.draw() me prends environ 4% du CPU (sur les 38 de bases). La création du sprite c'est environ 2% . Sinon les autres ben sa ne bouge pas trop.

Après un petit teste perso, créer une texture prends énormément de temps (j'ai tenté une copie de la texture de la sf::RenderTexture pour un petit teste : la consommation du proço a presque doublé). Sa peut peut venir de là, non ?

Je pense donc que le simple fait que je fasse renderTexture.clear() ou renderTexture.draw() (un des deux suffisent), prends énormément de ressource (la création de la Texture est très longues).
« Modifié: Juin 27, 2012, 12:59:43 pm par gaulois94 »