IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

Cairo (GTK+) Vs SDL ?


Sujet :

GTK+ avec C & C++

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Full Stack
    Inscrit en
    Mars 2009
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Mars 2009
    Messages : 94
    Par défaut Cairo (GTK+) Vs SDL ?
    Bonjour,

    (Je détaille mon soucis en début de topic, la problématique principale viens à la fin pour ceux souhaitant aller vite ).

    J'ai créé un programme, d'abord avec la SDL, avant de passer à GTK+ dont la puissance me semblait beaucoup plus intéressante pour la suite de mon développement.

    Cependant, dans mon programme je dois générer un grand nombre de dessin de rectangles (une grille) pouvant soit être blancs ou bleu. Quand je dis un grand nombre, cela se base sur une matrice de 100*100 minimum, 300*300 souhaité, et plus si possible (ce serait à l'utilisateur de choisir) avec une vitesse de 250ms souhaitée entre chaque rafraichissement de la grille entière.

    Bien sûr je ne veux pas aller à l'infini, mais au moins jusqu'à 300*300, cela me semble possible. Avec la SDL, ce but a été atteint. J'ai ensuite voulu reproduire cela avec GTK+ (avant de poursuivre le développement) et j'ai été amené à certaines difficultés de rafraichissement déjà pour une matrice de 100*100, que j'ai pu surmonter notamment grâce à l'aide de gérald (actif aussi sur ce forum) sur le forum GTK+.

    J'arrive ainsi aujourd'hui à assurer des deux côtés ma matrice de 100*100 (mon minimum en terme de performances), en utilisant la bibliothèque Cairo avec GTK+, recommandée pour le dessin.

    Cependant, je n'arrive pas à arriver à des performances très élevées et le 300*300 génère automatiquement un segmentation fault. Pour comprendre le problème j'ai ainsi fait un mini benchmark pour une même portion de code (réalisant les mêmes choses) pour une fenêtre de 500*400 sur un PC équipé d'un processeur dual core AMD Turion 64*2.

    Pour une matrice de 100*100 (en moyenne) :

    SDL : 0.040 - 0.050 s
    Cairo + GTK+ : 0.120 - 0.130 s

    Pour du 300*300 :

    SDL : 0.150 - 0.160 s
    Cairo + GTK+ : segmentation fault (arrive près des 250ms pour du 150*150)

    A cela s'ajoute que Cairo, sur une base de 100*100, prend facilement 20 à 30% de ressources CPU quand la SDL flirte avec le 0. Cette ressource, après quelques tests, est de plus quasiment entièrement demandée par le dessin avec Cairo (dessin qui se fait d'abord en mémoire avant d'être affiché) (et non pas par la fenêtre GTK+).

    Alors mon problème est le suivant : peut-on améliorer les performances de mon dessin avec Cairo ? C'est à dire, est-ce Cairo qui est vraiment très lent en comparaison avec la SDL ? Est-ce une erreur de code (si vous le souhaitez je peux vous donner les sources du programme fait avec la SDL et avec GTK+) de ma part ?
    Cairo semble être utilisé de plus en plus avec GTK+ et de grands logiciels comme Mozilla Firefox se serve de cette librairie, c'est pourquoi je m'interroge sur les performances de cette librairie.

    Je vous remercie d'avance,

    Cordialement,

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur Full Stack
    Inscrit en
    Mars 2009
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Mars 2009
    Messages : 94
    Par défaut
    Personne pour quelques idées ?

  3. #3
    Membre confirmé Avatar de skip78
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 247
    Par défaut
    Salut,

    Malheureusement pas de solution à t'apporter, mais :

    Comme je l'ai dis sur différents topics du forum GTK maintenant () je fais en ce moment du traitement d'image.

    Et bon, même si je n'utilises pas directement Cairo, je trouve GTK très lent dès que le traitement est un peu volumineux. (Typiquement, l'application d'un filtre de Sobel sur une grosse image prend environ 3 fois plus de temps qu'un editeur d'image classique, alors que ca n'est au final que du calcul ...)

    En fait j'ai le sentiment que c'est les fonctions d'appel au pixels qui sont un peu longues à la détente.

    Bref la seule idée que j'ai, encore une fois, est que les allocations mémoires sont mal gérées.

    Sinon, c'est tout simplement que GTK n'est pas optimisé pour faire de traitement d'image / dessin ^^

    Voila désolé de n'apporter que de la tristesse dans ce monde qui a pourtant bien besoin de quelques sourires, mais je suivrais ce topic de près, si il évolue

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Les fonctions d'appel au pixel ? Je comprends pas bien ce que tu veux dire par là Une fois que tu as chargé ton image dans un GdkPixbuf, tu as un accés direct à un buffer contenant toutes les données de ton image. Ensuite leur format n'est peut être pas adapté à ton traitement, mais y a rien que je qualifierais de "fonctions d'appel au pixel" dans tout ça.

    Pour cette histoire de cairo, un truc qui peut avoir une grande influence sur les perfs, c'est de faire bien attention à ce que tes rectangles soient alignés sur des pixels, ça permet à cairo d'aller beaucoup plus vite. Me demande pas comment on fait ça par contre

  5. #5
    Membre confirmé Avatar de skip78
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 247
    Par défaut
    Je pensais aux fonctions du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    guchar *gdk_pixbuf_get_pixels_by_coord (const GdkPixbuf *pixbuf, const gint x, const gint y)
    {
    	// Déclaration des variables :
    	guchar *pixel = NULL;
    	guint32 rowstride = 0;
     
    	// Gestion des erreurs (importante car généralement la fonction getpixel est apellée avant setpixel) :
    	if (!pixbuf){
    		printf("Dans la fonction gdk_pixbuf_get_pixels_by_coord(); pixbuf = NULL!\n");
    		return NULL;
    	}
    	if (x > gdk_pixbuf_get_width(pixbuf)){
    		printf("Dans la fonction gdk_pixbuf_get_pixels_by_coord(); x > à la largeur de pixbuf!\n");
    		return NULL;
    	}
    	if (y > gdk_pixbuf_get_height(pixbuf)){
    		printf("Dans la fonction gdk_pixbuf_get_pixels_by_coord(); y > à la hauteur of pixbuf!\n");
    		return NULL;
    	}
     
    	// Récupération des données :
    	pixel = gdk_pixbuf_get_pixels(pixbuf);
    	rowstride = gdk_pixbuf_get_n_channels(pixbuf)*y*gdk_pixbuf_get_width(pixbuf);
     
    	return &pixel[(gdk_pixbuf_get_n_channels(pixbuf)*x) + rowstride];
    }
    De plus, je travailles en nuances de gris, donc je fais en fait appel à une fonction qui fait appel à cette fonction (et qui convertit ensuite pix[0] = pix[1] = pix[2] = (pix[0] + pix[1] + pix[2]) /3; )

    Et bon, quand je fais appel à ces fonctions dans 6 boucles imbribées, je comprends que mon proc galère un peu, mais on sort du domaine graphique, encore une fois ^^


  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Oui forcément, si tu appelles cette fonction pour itérer sur ton image, ça va être lent...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    guchar pixels = gdk_pixbuf_get_pixels (pixbuf);
    for ( x= 0; x < gdk_pixbuf_get_width (pixbuf); x++) {
        for (y  = 0; y < gdk_pixbuf_get_height (pixbuf); y++) {
            guint cur_pixel_offset = y * gdk_pixbuf_get_rowstride (pixbuf) + x * gdk_pixbuf_get_n_channels (pixbuf);
            g_print ("R: %d G: %d B: %d\n", pixels[cur_pixel_offset], pixels[cur_pixel_offset+1], pixels[cur_pixel_offset+2]);
        }
    }
    (modulo qques petits bugs) te permet d'itérer sur toute ton image... Tu doit même pouvoir éviter le calcul de cur_pixel_offset à chaque passage dans la boucle si tu déplaces le pointeur pixels à chaque tour de boucle.

  7. #7
    Membre confirmé Avatar de skip78
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 247
    Par défaut
    Bah ca me paraissait super logique ce que tu dis au départ, mais en fait, je fais le même nombre de calculs, juste de facon plus propre.

    J'ai fait des test, la méthode que tu préconises ne fait gagner que trés peu de temps au final (au max 10%)

    Enfin, je vais voir de ce pas ce que ca donne sur Sobel, parce que c'est vrai que la dessus, ca peut commencer à valoir le coup.

    Edit : Ouais bon j'arrive jusqu'à 20% sur les algos plus compliqués, ca rend pas aussi bien que ce que j'aurais éspéré, mais c'est dejà pas mal !

    Merki donc

    RE edit : en optimisant un max, j'arrive à diviser par 3 la durée de calcul, ce qui revient à la vitesse observée sur les éditeurs suscités !

    encore donc

  8. #8
    Membre confirmé
    Homme Profil pro
    Développeur Full Stack
    Inscrit en
    Mars 2009
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Mars 2009
    Messages : 94
    Par défaut
    Salut,

    Cairo serait donc plus lent ? Par contre je ne comprends pas trop cette histoire d'alignement aux pixels, ce serait quelque choses du genre ne pas passer de double en paramètre pour Cairo ?

    En tout cas je vois que mon topic a aidé quelqu'un.

  9. #9
    Membre confirmé Avatar de skip78
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 247
    Par défaut
    Bon désolé, je ne fais toujours pas avancer ton schmilblick, mais je voulais vous faire part de ce qui s'est passé, ca me trouble au plus haut point :

    Pour des raisons de linkage, j'ai repassé toutes mes fonctions C dans des fichiers Cpp, bah résultat des courses, l'éxécution est 3 fois plus rapide

    Serieux y'a des trucs VACHEMENT troublants en info

Discussions similaires

  1. flux video audio => socket + gtk+ ou sdl + opencv
    Par quark22 dans le forum Réseau
    Réponses: 3
    Dernier message: 03/09/2010, 17h05
  2. Compilation d'un projet avec du Gtk et SDL
    Par leousch dans le forum C
    Réponses: 1
    Dernier message: 21/05/2009, 19h13
  3. [Free Pascal] [Linux] Path des units GTK et SDL
    Par menthol34 dans le forum Free Pascal
    Réponses: 1
    Dernier message: 29/09/2007, 22h49
  4. besoin d'infos sur GTK et SDL
    Par igor76 dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 19/08/2006, 20h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo