Optimiser l'affichage graphique d'une vue

UniXUniX Membre
04:48 modifié dans API AppKit #1
Salut.

Voilà  une question importante pour moi.
Mon appli a une customView principale dans laquelle beaucoup d'informations sont affichées ... :o
Globalement, voilà  la description de cette vue :
- en fond, il y a une image qui occupe toute la surface
- par dessus je dessine plusieurs éléments en grande quantité : petites images, beziers, texte, ...

Les opérations pouvant être effectuées dans cette vue sont au nombre de 2 :
- zoom / dézoom
- manipulation de tous les éléments ajoutés (ajout, suppression, déplacement)

Aujourd'hui, j'utilise la méthode bourrine en demandant la mise à  jour complète de la vue setNeedsDisplay:YES à  chaque fois que je modifie un quelconque élément ou le zoom (hé oui, mais je suis en apprentissage Cocoa ...  :P). Evidemment, au bout d'un moment c'est pas très performant ....!

Aujourd'hui, je souhaite reprendre un peu le "moteur d'affichage" de ma vue pour optimiser tout ça ...! Mais je ne sais pas trop quelles directions sont les bonnes, et lesquelles sont mauvaises ...

CoreGraphics est l'API d'affichage. Faut-il que je plonge là -dedans ?

Réponses

  • BruBru Membre
    04:48 modifié #2
    1. Déjà , au lieu du setNeedsDisplay:, tu peux "affiner" la zone à  réafficher avec un setNeedsDisplayInRect: en passant le rectangle à  redessiner.

    2. Dans la méthode drawRect:, utilise l'argument NSRect. Ce rectangle indique la zone qui demande à  être redessinée.
    Pour l'image de fond, la méthode drawInRect:fromRect:operation:fraction: de NSImage te permet de n'afficher qu'une portion de l'image de fond dans le rectangle que tu veux (celui à  redessiner).
    Ensuite, il te suffit de tester la liste des éléments que tu y dessines pour savoir lequel a un point commun avec le rectangle pour ensuite le réafficher.

    .
  • UniXUniX Membre
    04:48 modifié #3
    Oui, j'avais repéré cette piste de ne mettre à  jour que la zone modifié de ma vue.

    Mais, à  repartir dans le code d'affichage de la vue, je pensais qu'il y avait des choses plus radicales à  faire pour optimiser tout ça ....
  • AntilogAntilog Membre
    04:48 modifié #4
    C'est bien ça !

    C'est à  priori la méthode la plus efficace et la plus radicale à  faire:
    Ne mettre à  jour que le minimum de ce qu'il y a à  afficher  :o

    Et en général, passé le premier tour évident, c'est pas facile, facile.

    QuartzDebug te montrera le chemin.  :brule:
  • UniXUniX Membre
    04:48 modifié #5
    QuartzDebug sert à  quoi ?
  • Eddy58Eddy58 Membre
    04:48 modifié #6
    C'est un long sujet, je ne saurais trop te conseiller de lire les Drawing Performance Guidelines, qui te montreront entre autre l'usage de QuartzDebug. :)
  • UniXUniX Membre
    04:48 modifié #7
    Très bonne lecture Eddy, merci pour le lien ...!
    :)
  • UniXUniX Membre
    04:48 modifié #8
    En revanche, comment optimiser l'affichage des NSBezierPaths ?
    En ne redessinnant qu'une partie de la vue avec setNeedsDisplayInRect, comment je gère les beziers ? il faut que je teste si il y en a un qui passe dans la zone ....

    De même, il n'est pas possible de redessiner qu'une partie d'un bezier, non ?
  • fouffouf Membre
    04:48 modifié #9
    Oui, tu peux tester voir si un bezier path donné passe dans la zone à  redessiner, grâce à  la méthode bounds de NSBezierPath et à  la fonction NSIntersectsRect.
    Par contre, je ne pense pas que tu puisses dessiner seulement une partie du bezier path. Pour ceux qui sont des concatenations de bezier path, tu pourrais peut-être essayer de tester chaque partie du path avec les methodes elementAtIndex: ou elementAtIndex:associatedPoints: ; mais je trouve que c'est se donner beaucoup de mal pour rien.
Connectez-vous ou Inscrivez-vous pour répondre.