Performances d'affichage

olivier555olivier555 Membre
22:02 modifié dans API AppKit #1
Bonjour,
Je réalise le portage sur Mac (Cocoa, Project Builder) d'une application PC développée sous Delphi qui génère des grandes images en 2D. La grande image est en fait découpée en imagettes (images mémoires), et suivant où en est le scroller, on affiche juste les bonnes imagettes. Le but de cette méthode est d'alléger la mémoire vidéo. Le fait de positionner ces imagettes à  l'écran ne pose pas de problème, en revanche lorsqu'on resize la fenêtre, le programme doit redessiner les imagettes en fonction de la nouvelle taille de la fenêtre. Mon problème est que pour un code relativement similaire entre les deux plates-formes, l'affichage est fluide sur PC (Delphi) mais sur Mac c'est le fait de redessiner ces imagettes qui prend un temps fou (on resize, ca redessine toutes les imagettes, puis ca affiche). Du coup le resizage prend quelques secondes et surtout le scrolling est saccadé la 1ere fois qu'on passe sur une imagette (une fois qu'elle est calculée une première fois et qu'on ne resize pas à  nouveau, on ne la redessine pas, par contre, il faut attendre que l'utilise scrolle sur elle pour que le programme la dessine une première fois). J'ai pourtant fait appel à  des fonctions de dessin basique genre drawAtPoint, moveTo, lineTo, des NSBezierPath etc... Est-ce que les performances d'un Mac son inférieures pour ce genre de chose? Faut-il procéder différemment entre un PC et un Mac? Est-il préférable de dessiner directement la grande image directement dans la vue et pas sur les images mémoire? Merci par avance de me donner quelques pistes ou idées si vous en avez, et si vous n'avez pas tout compris, demandez moi des infos, c'est peut être pas très clair ce que j'ai écrit ;)
Merci d'avance!!
olivier

Réponses

  • Eddy58Eddy58 Membre
    22:02 modifié #2
    Je pense que c'est un problème technique, mais effectivement il faudrait en savoir plus sur tes techniques utilisées. OS X se sert d'un flushing par défaut, mais il propose des méthodes pour optimiser le tracé. Quelles méthodes emploies tu exactement pour remplir ta view ? :)
  • 22:02 modifié #3
    Si tu découpes ton image en plusieurs imagettes, la première chose à  faire est d'utiliser correctement le drawRect. Beaucoup de gens pensent que le drawRect doit générer l'affichage de l'ensemble de la vue, ce qui est en fait une erreur. Cette méthode prend en fait un argument NSRect, qui est en fait la portion de vue pour laquelle il faut gérer l'affichage. Par exemple, quand tu scrolles de 10 pixels vers le bas, la seule chose que drawRect demande (s'il a plus "tant mieux", mais ce n'est pas nécessaire) c'est d'avoir une bande de 10 pixels de haut et de la largeur de la fenêtre, rien de plus. Le reste est conservé dans un cache, donc tu ne dois pas t'en soucier.

    Donc dans ton cas, il faut calculer quelles imagettes doivent être redessinées en fonction l'argument placé, et ne redessiner que celles là .
  • olivier555olivier555 Membre
    22:02 modifié #4
    J'affiche une partition musicale en fait. Les méthodes que j'utilise sont beaucoup de lectures de variables en mémoires (selon leur état on appelle différentes fonctions de dessins etc), beaucoup de calculs matheux pour trouver les coordonnées, des if et des boucles for a tirlarigo, puis des dessins de lignes et des plaquages de caractères (énormément).
    En résumé, j'ai des trucs comme ça :
    <br />NSDictionary 	*dict = [NSDictionary dictionaryWithObjectsAndKeys:<br />                                [NSFont fontWithName:@&quot;Arial Bold&quot; size:11],<br />                                NSFontAttributeName,<br />                                [NSColor blackColor],<br />                                NSForegroundColorAttributeName,<br />                                nil];<br />NSImage *Bmp;&nbsp; //C&#39;est l&#39;imagette en cours, sur laquelle on dessine<br /><br />[Bmp lockFocus];<br />NSEraseRect(NSMakeRect(0, 0, [Bmp size].width, [Bmp size].height));<br />//...<br />[path moveToPoint:NSMakePoint(X1 + 0.5, Bande-&gt;HB - Y + 0.5)];<br />[path lineToPoint:NSMakePoint(X2 + 0.5, Bande-&gt;HB - Y + 0.5)];<br />[[NSColor darkGrayColor] set];<br />[path stroke];<br />//...<br />txtW = [txt sizeWithAttributes:dict].width;<br />txtH = [txt sizeWithAttributes:dict].height;<br />[txt drawAtPoint:NSMakePoint(XB + round(MP-&gt;Mesure-&gt;PosXAff) + DecalageX - round(txtW/2), Bande-&gt;HB - Y) withAttributes:dict];<br />//...<br />rectangle = NSMakeRect(X - 1, Bande-&gt;HB - (YR2s - 1) - 4, 4, 4);<br />path = [NSBezierPath bezierPathWithOvalInRect:rectangle];<br />[path fill];<br />//...<br />[Bmp lockFocus];<br />
    

    Je te donne juste en vrac un apercu de quelques lignes, mais il y en a beaucoup, beaucoup plus! (Pas mal de fonctions en fait affichage assez complexe)

    Renaud-> Ce que tu dis est intéressant, mais je ne suis pas sur que ça me concerne dans le sens où dès qu'on resize la vue, il faut calculer l'intégralité des imagettes, et c'est ce calcul qui prend du temps. Le drawRect se contente d'afficher au bon endroit les bonnes imagettes. Et lorsque les imagettes sont précalculées, le drawRect réalise un scrolling très fluide.
  • Eddy58Eddy58 Membre
    22:02 modifié #5
    Tu peux déjà  aller voir ce qu'ils racontent ici, ils parlent de méthodes pouvant êtres appliquées lors de redimensionnements de fenêtres : :)
    http://developer.apple.com/documentation/performance/Conceptual/Drawing/index.html
  • olivier555olivier555 Membre
    22:02 modifié #6
    Yes merci j'ai un peu lu et ça a commencé à  me donner quelques idées!
Connectez-vous ou Inscrivez-vous pour répondre.