Page 6 sur 9

Re: raafal - un project de framework d'application 3d

Publié : mer. 28/août/2013 23:38
par graph100
grabiller a écrit :Le système est conçu pour que soit le viewport 'root' gère un CanvasGadget, auquel cas les descendants (y compris les widgets et contrôles car c'est transparent pour eux) dessinent dans ce même Gadget, soit que chaque viewport ait son propre CanvasGadget (je verrai par la suite le plus efficace, notamment quand je ferai intervenir l'OpenGL).
Il me semble avoir lu un post de fred disant qu'il vaut mieux plusieurs canvas qu'un seul gros.
Et j'ai retrouvé un post dans lequel il confirme qu'il vaut mieux de pas faire plusieurs appel de canvasoutput() : ici

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 2:13
par G-Rom
graph100 a écrit :
grabiller a écrit :Le système est conçu pour que soit le viewport 'root' gère un CanvasGadget, auquel cas les descendants (y compris les widgets et contrôles car c'est transparent pour eux) dessinent dans ce même Gadget, soit que chaque viewport ait son propre CanvasGadget (je verrai par la suite le plus efficace, notamment quand je ferai intervenir l'OpenGL).
Il me semble avoir lu un post de fred disant qu'il vaut mieux plusieurs canvas qu'un seul gros.
Et j'ai retrouvé un post dans lequel il confirme qu'il vaut mieux de pas faire plusieurs appel de canvasoutput() : ici

Pour quelques widget perso , plusieurs canvas ne vont pas faire boité le programme , dans le cadre d'une gui complète , mieux vaut un canvas , screen , etc...
et autant de surface ( image ) que de widgets & avec un update de ton canvas principal avec un timer de 50ms , le programme ne boitera pas non plus.

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 5:49
par grabiller
@graph100
Du coup c'est un peu contradictoire, en fait, si il vaut mieux plusieurs canvas qu'un gros, mais qu'en même temps l'appel à CanvasOutput() est coûteux.

En pratique, il y a deux situations majeures:

1) Mise à jour de l'interface par l'utilisateur en fonction du mouvement de la souris et des clicks
C'est à dire 'highlighter' les parties de l'interface quand la souris passe dessus, changer l'état d'un bouton quand on click, etc..
Dans ce cas, en tous cas avec mon interface, je pense qu'un seul Canvas ou plusieurs ne change pas grand chose car je ne redessine que ce qui a besoin d'être redessiné et cela n'implique qu'un seul CanvasOutput() de toutes façons.

2) Mise à jour de l'interface par l'application (feedback,timer,etc..)
Dans ce cas, plusieurs zones de l'interface peuvent être redessinées en même temps (un compteur ici, un texte là, une barre de progression là-bas, etc..).
Et là, on pourrai penser qu'avoir un seul gros Canvas est plus efficace car on utilise un seul CanvasOutput() pour tout redessiner à chaque fois.

Il y a une exception au cas 1), en tous cas avec un système de layout splittable et resizable comme le mien: Quand l'utilisateur redimensionne un viewport cela peut engendrer un redimensionnement de tous les autres viewports visibles dans la fenètre, et là je pense qu'avoir un seul Canvas est beaucoup plus efficace, sinon il faudrait individuellement repositionner et redimensionner chacun des 'petits' Canvas enfants à chaque fois et donc autant d'appels à CanvasOutput() à chaque fois.

@G-Rom
Pour l'instant je n'utilise pas d'image pour chaque widget/control, je redessine directement quand il y a besoin, mais je me suis posé la question effectivement. Dans le cas d'un repositionnement de widgets/controls c'est sans doute plus efficace de simplement déplacer l'image en la redessinant au bon endroit plutôt que de tout redessiner. Mais en même temps ce cas est relativement rare car la pupart du temps les widgets/controls sont en même temps déplacés et redimensionnés, et dans ce cas on a besoin de les redessiner de toutes façons.

Ceci dit pour les viewports OpenGL c'est certainement une option que je vais tester, car je veux pouvoir avoir le retour d'un Canvas (souris,clavier) tout en utilisant l'OpenGL dedans. Et je ne peux utiliser la fenètre du Canvas directement pour l'OpenGL car cela induirait un conflit avec le système de redessin automatique du Canvas. Ce à quoi je pense pour l'instant serait donc d'utiliser l'OpenGL en offscreen et donc d'affecter une image à l'OpenGL pour qu'il dessine dedans, et ensuite je recopie cette image à la taille et à l'endroit voulu dans le Canvas unique de l'UI. En gros, cela revient à faire soit-même le double buffering.

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 6:56
par graph100
pour la contradiction, c'est que je voulais dire, (et je ne fais que citer de mémoire, mes tests n'ont jamais montrer des impacts lourds sur la vitesse de mon projet) c'est que mettons que la fenêtre fasse 1900x1080 pixels, c'est plus long dessiner sur cette surface que de ne mettre à jour que de petits canvas.

C'est comme ça que j'interprète ce qu'a dis Fred.

Ensuite pour les appel de canvasOutput(), c'est qu'il ne faut l'utiliser idéalement qu'une seule fois par canvas, image ou autre surface de dessin. En gros éviter les fonctions de dessin qui rappellent xxxOutput() à chaque fois (mais ça c'est la base).

Par contre il faudrait effectivement faire un test pour vérifier si l'impact plus important en faisant plusieurs appel de dessin sur de petites surfaces ou un appel sur une grande surface.

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 8:20
par grabiller
graph100 a écrit :pour la contradiction, c'est que je voulais dire, (et je ne fais que citer de mémoire, mes tests n'ont jamais montrer des impacts lourds sur la vitesse de mon projet) c'est que mettons que la fenêtre fasse 1900x1080 pixels, c'est plus long dessiner sur cette surface que de ne mettre à jour que de petits canvas../..
Justement c'est là où je m'interroge. Dans le cas où une seule petite zone doit être redessinée (l'équivalent d'un seul petit Canvas) à mon sens la différence doit être relativement négligeable, même si il doit bien sûr en avoir une, car la zone de dessin reste la même, la différence ne reste plus que dans le blit interne de l'image du Canvas.

Par contre quand il faut redessiner toute l'interface (ou une grande partie), cela me semble logique qu'un seul Canvas soit plus efficace qu'une multitude de petits Canvas. Mais bon, comme tu dis, il faut tester, on verra bien :wink:

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 11:33
par Fred
Personnellement, je ferais un canvas par gadget, ce sera plus simple à gerer et bien plus rapide à rafraichir (StartDrawing() lock toute la surface, donc si la resolution de ton ecran est 4K par exemple, ton PC va morfler à chaque modif, meme mineure (genre un cursor qui clignote dans un champ d'entrée). A mon avis, la conso memoire etc ne sera pas bien differente, si tu liberes les gadgets non utilisés entre temps.

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 11:43
par Ar-S
Fred a écrit :Personnellement, je ferais un canvas par gadget, ce sera plus simple à gerer et bien plus rapide à rafraichir (StartDrawing() lock toute la surface, donc si la resolution de ton ecran est 4K par exemple, ton PC va morfler à chaque modif, meme mineure (genre un cursor qui clignote dans un champ d'entrée). A mon avis, la conso memoire etc ne sera pas bien differente, si tu liberes les gadgets non utilisés entre temps.
Une question me taraude. Il faut limiter l'appel de StartDrawing(), mais comment faire si tu as plein de Canvas par rapport à un seul qui contient tout les pseudo gadgets ?

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 13:34
par blendman
Vos informations sur les canvas m'intéressent grandement, car à l'époque où j'avais commencé mon logiciel de dessin (animatoon, on en trouve une version dans application, mais ce n'est pas la dernière), j'ai remarqué que ça ramait effectivement beaucoup, notamment à cause des multiples appels aux outputs (image, canvas, etc..).

Dans le cadre d'un logiciel de dessin, il y a bien sûr plein de façons de traiter l'information (un tableau qui stocke les pixels, une image, un canvas, etc..).
On m'avait expliqué que photoshop découpait sans doute l'image en plusieurs "sous-images", plus petites et n'affichait et ne travaillait que ce qu'il y avait à l'écran et ce sur quoi on travaillait.

[edit] voici un petit exemple de ce système de "dalle", je ne sais pas ce que ça vaut, ni même si c'est intéressant, mais je poste au cas où :
http://www.purebasic.fr/french/viewtopi ... =6&t=13903
[/edit]

En tout cas, j'ai hâte d'avoir un petit exemple de code d'utilisation du canvas avec cette gui, pour voir ^^

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 16:11
par Fred
Ar-S a écrit :
Fred a écrit :Personnellement, je ferais un canvas par gadget, ce sera plus simple à gerer et bien plus rapide à rafraichir (StartDrawing() lock toute la surface, donc si la resolution de ton ecran est 4K par exemple, ton PC va morfler à chaque modif, meme mineure (genre un cursor qui clignote dans un champ d'entrée). A mon avis, la conso memoire etc ne sera pas bien differente, si tu liberes les gadgets non utilisés entre temps.
Une question me taraude. Il faut limiter l'appel de StartDrawing(), mais comment faire si tu as plein de Canvas par rapport à un seul qui contient tout les pseudo gadgets ?
Il faut limiter à un par refresh complet du canvasgadget(). Meme si t'en as une centaine ca ne devrait pas poser de soucis, vu que la surface à locker est petite. De plus t'auras forcement des gadgets qui ne vont pas avoir besoin d'etre modifiés en permance.

Dans le thread mentionné (http://www.purebasic.fr/french/viewtopi ... 15#p149115) tu remplissais deja le fond, pour ensuite mettre du texte dessus, avec 2 startdrawing, là c'est pas optimisé.

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 19:15
par grabiller
Fred a écrit :../..Personnellement, je ferais un canvas par gadget, ce sera plus simple à gerer../..
De ce côté là, dans mon implémentation en tous cas, cela revient au même car chaque 'viewport' est concu pour être autonome, même si il reçoit les events de son 'parent' au lieu de son canvas (si il en a un). Donc la complexité est identique en terme de code.
Fred a écrit :../.. et bien plus rapide à rafraichir (StartDrawing() lock toute la surface, donc si la resolution de ton ecran est 4K par exemple, ton PC va morfler à chaque modif, meme mineure (genre un cursor qui clignote dans un champ d'entrée)../..
C'est ça que j'ai du mal à comprendre. D'après mes essais, même avec un Canvas qui rempli tout un écran en 1920x1200 (ou presque, moins les bord de la fenêtre), cela reste très rapide et je n'ai aucun problème de curseur clignotant ou autre. Mais il y a sans doute un truc qui m'échappe.

D'un autre côté, je n'arrive pas à m'enlever de l'idée que si chaque 'viewport' a son propre Canvas, lors d'un resize global de la fenètre ou du déplacement d'un des splitter de plus haut niveau, un seul Canvas me semble beaucoup plus efficace.

Voici un exécutable du projet en cours: raafal.gui.20130829.rar

Vous pouvez vous amuser à splitter et re-splitter les viewports (en cliquant sur les V,H,Q) et les redimensionner et observer le vitesse. De mon côté cela me semble correct, dites-moi ce que vous en pensez.

(en cliquant sur M on maximise, X pour fermer, ALT+M on crée un groupe de maximisation, il faut alors splitter ce viewport et maximiser un viewport fils pour comprendre l'effet. En cliquant sur le 'o' en haut à gauche de chaque viewport on toggle le header. Lorsque qu'il n'est pas visible il suffit d’amener la souris en haut à gauche ou en haut à droite pour le faire apparaître. Les 'tabs' ne sont pas opérationnels pour l'instant).

Ne vous attardez pas trop sur les 'fonctionnalités' en elles-mêmes mais plutôt sur la rapidité du redimensionnement des viewports, votre avis m'intéresse beaucoup.

Dans cette exemple, il n'y a donc qu'un seul Canvas, et un seul StartDrawing() par update (c'est le viewport 'root' qui le déclenche et demande ensuite à tous ses 'fils' de redessiner, si besoin, car un viewport peu 'Invalider' sa zone, ce qui déclenche le StrartDrawing() du root, mais seul le viewport ayant appelé le invalidate est redessiné dans ce cas).

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 19:55
par grabiller
blendman a écrit :Vos informations sur les canvas m'intéressent grandement, car à l'époque où j'avais commencé mon logiciel de dessin (animatoon, on en trouve une version dans application, mais ce n'est pas la dernière), j'ai remarqué que ça ramait effectivement beaucoup, notamment à cause des multiples appels aux outputs (image, canvas, etc..).

Dans le cadre d'un logiciel de dessin, il y a bien sûr plein de façons de traiter l'information (un tableau qui stocke les pixels, une image, un canvas, etc..).
On m'avait expliqué que photoshop découpait sans doute l'image en plusieurs "sous-images", plus petites et n'affichait et ne travaillait que ce qu'il y avait à l'écran et ce sur quoi on travaillait.

[edit] voici un petit exemple de ce système de "dalle", je ne sais pas ce que ça vaut, ni même si c'est intéressant, mais je poste au cas où :
http://www.purebasic.fr/french/viewtopi ... =6&t=13903
[/edit]

En tout cas, j'ai hâte d'avoir un petit exemple de code d'utilisation du canvas avec cette gui, pour voir ^^
C'est très intéressant ton système de dalles.
De ce que j'en comprends, tu n'utilises aussi qu'un seul Canvas.
Petite question, pourquoi dessiner sur une image que tu re-dessine dans le canvas, alors qu'en dessinant dans le Canvas directement cela revient au même ?
Je veux dire par là, pourquoi ne pas utiliser un système de dalles virtuelles ? Cela reviendrai à ne dessiner dans le Canvas que dans la zone d'une 'dalle' à chaque fois.
(mais je n'ai peut-être pas compris toutes les subtilités de ton code, ceci dit).
Autre alternative si on va dans le sens de Fred, pourquoi pas un Canvas par dalle ? (mais c'est peut-être aventureux, là :wink: )
En tout cas très sympa comme idée, je trouve.

Re: raafal - un project de framework d'application 3d

Publié : jeu. 29/août/2013 23:28
par Fred
Ca marche bien tant que tu ne sollites pas le rafraichissement du canvas. Essaie de creer un champ de saisie (comme un StringGadget()), rentre du texte assez vite et tu vas voir que ton CPU passe à 100% sur un core car il faut que tu modifies tout le canvas a chaque lettre et que tu le redessine. Ca marche, mais pour moi c'est pas normal qu'un programme prenne autant de resource juste pour ca. Après c'est que mon avis ;). Ce qu'on pourrait imaginer, c'est que StartDrawing() prenne une zone rectangulaire en parametre pour pouvoir travailler sur une portion reduite d'une image ou d'un canvas et optimiser ce genre d'operation (pour l'instant ce n'est pas prévu).

Re: raafal - un project de framework d'application 3d

Publié : ven. 30/août/2013 5:42
par grabiller
Fred a écrit :Ca marche bien tant que tu ne sollites pas le rafraichissement du canvas. Essaie de creer un champ de saisie (comme un StringGadget()), rentre du texte assez vite et tu vas voir que ton CPU passe à 100% sur un core car il faut que tu modifies tout le canvas a chaque lettre et que tu le redessine.../..
Je comprends ce que tu veux dire, oui, mais dans mon cas, et dans le cas que tu décris, je ne redessine pas tout le Canvas, mais juste la petite portion où le texte est modifié car je n'ai aucun 'overlap' inter-viewport ou inter-controls. Après oui, en interne la Canvas doit re-blitter toute l'image mais cela doit être relativement rapide, non ?
Fred a écrit :../.. Ca marche, mais pour moi c'est pas normal qu'un programme prenne autant de resource juste pour ca. Après c'est que mon avis ;)../..
Oui ok, je vois ce que tu veux dire maintenant, la réserve que tu as concerne les ressources utilisées.

En fait le choix se résume à combien de ressources on veut utiliser pour une GUI.

Du coup, ne pourrait-on pas imaginer une accélération hardware pour le Canvas ? C'est vrai que je pourrai envisager d'utiliser un OpenWindowedScreen() (voire une surface OpenGL, carrément) et m'en servir pour toute l'UI. En même temps cela change considérablement la manière dont les Events sont gérés et dans ce cas on est obligé d'updater l'UI constamment, comme dans un jeu, ce qui n'est peut-être pas le plus efficace non plus pour une application 'normale' (les ressources risquent d'en prendre un coup, du coup).

Pas facile comme choix.
Fred a écrit :../.. Ce qu'on pourrait imaginer, c'est que StartDrawing() prenne une zone rectangulaire en parametre pour pouvoir travailler sur une portion reduite d'une image ou d'un canvas et optimiser ce genre d'operation (pour l'instant ce n'est pas prévu).
Ce serait effectivement très efficace d'avoir cette fonctionnalité, ce serait même sans doute la solution idéale (et cela permettrai de clipper les Draw du même coup, ce qui manque à PB je trouve).

Re: raafal - un project de framework d'application 3d

Publié : ven. 30/août/2013 6:22
par grabiller
Je viens de regarder plus en détails au niveau des ressources.

Quand j'ai ma fenêtre en plein écran (1920x1200), avec pleins de Viewports splittés (en tout 24 Viewports affichés à l'écran):

- Quand je bouge le splitter de plus haut niveau, ce qui oblige un redimensionnement/redessin des 24 viewports à la fois en plein écran, sur ma config (i7 x980 @ 3.2GHz/GForce Titan), mon CPU prend ~10% (ce qui est beaucoup pour cette config j'en conviens, mais si j'avais à updater 24 Canvas en même temps, je ne suis pas sûr qu'on utiliserai beaucoup moins de ressources, à tester).

- Quand je bouge rapidement et constamment la souris sur un groupe de V H Q M X pour les highlighter rapidement (ce qui revient à n'updater qu'une petit portion de l'UI malgré le blit plein écran de l'image interne du Canvas, le CPU ne prend plus que ~1/~2%.

Cela tend à conforter l'idée que même avec une grande surface de Canvas, quand on n'en redessine qu'une petite portion et malgré le blit plein écran de l'image interne du Canvas, cela reste assez efficace.

Qu'en penses-tu ?

Re: raafal - un project de framework d'application 3d

Publié : ven. 30/août/2013 10:32
par Fred
Les perfs de ta GUI vont dependre de la carte graphique, mais pourquoi pas vu que c'est un soft 3D.