CA versus CG, et les sublayers

LouLou Membre
octobre 2014 modifié dans API UIKit #1

Salut,


quelle est la différence entre Core Animation et ses "layers", et CoreGraphics, pour gagner en performance? CA utilise des "sublayers" ... et coregraphics dessine dans la vue grâce à  drawRect ? Avez-vous plus de détails pour comprendre la différence sur les performances?


 


Un extrait d'un article :


 



 


 


The first version was constructed with several subviews. One for the gradient, an UIImageView for the image and two UILabels for the text. The second version was constructed out of several sublayers. A CAGradientLayer for the background gradient, a CALayer for the image with itscontents property set to a CGImageRef and two CATextLayers. The last version was drawn as flat texture with Core Graphics.

 


le lien pour les performances entre appareils.


 


Il est aussi question de flat bitmap, notamment pour expliquer l'appli Tweetie, est-ce que vous avez plus de détails pour comprendre la différence avec les autre techniques?


 


Merci ;)


Réponses

  • CéroceCéroce Membre, Modérateur
    octobre 2014 modifié #2
    En pratique, les CALAyers sont basées sur les CGLayers. Mais ce n'est pas le propos de l'article.

    Florian Kugler compare trois techniques pour composer une cellule:
    1) CoreGraphics: on dessine dans -drawRect: (voir le code source)
    2) CALayer tree: chaque partie de la cellule est stockée dans une CALayer différente
    3) UIView tree: chaque partie de la cellule est stockée dans une UIView différente

    Ce que constate Florian, c'est que sur les anciens modèles, la technique n°1 est la plus rapide, parce qu'on ne fais pas de compositing (la cellule est opaque).

    Sur les modèles plus récents, le compositing est plus performant, et par contre, copier une grosse texture à  l'écran est plus lent, parce qu'on est passé au Retina, donc des textures 4 fois plus grosses. Note aussi qu'il utilise une CAGradientLayer, qui ne copie pas de pixels, puisqu'on peut dessiner en remplissant un polygone OpenGL; forcément c'est bien plus rapide que copier une bitmap !

    Enfin, sache que les UIViews utilisent une "backing" CALayer. ça explique que les performances dans les cas 2) et 3) sont voisines.
  • C'est quoi un ancien modèle ? Où est la frontière entre l´ancien et le récent ? iPhone 3, iPhone 4, 4S, 5 ?
  • CéroceCéroce Membre, Modérateur
    Pré-retina.
  • LouLou Membre
    octobre 2014 modifié #5

    Merci, j'avais lu que CoreGraphics et drawRect était ce qu'on devait préférer pour des raisons de performances, et que les uiViews étaient justement lourdes parce-qu'on devait superposer plusieurs vues. Là , l'article semble dire que les UIViews sont plus performantes que la méthode drawRect de CG... Sinon qu'appelles-tu compositing? Tu parles de cellule opaque, donc serait-ce pour parler de la transparence qui semble déconseillée...?


    Sinon, une CALayer a plusieurs layers, mais ça n'a pas le même impact que plusieurs vues avec UIViews?


    Merci ;)


  • CéroceCéroce Membre, Modérateur
    Tout est affiché grâce à  OpenGL. Ses commandes sont simples: créer un polygone à  partir de sommets, le remplir, en utilisant une texture (image bitmap), ou en interpolant entre les couleurs des sommets. Le rendu OpenGL se passe au niveau du GPU; aussi il faut qu'une texture soit présente en mémoire GPU pour être affichée. Or, sur les terminaux iOS, le CPU et la GPU partagent leur mémoire, ce qui évite les gros transferts de données.

    Pour faire simple, une CALayer utilise en général une texture OpenGL. Une fois que la texture est chargée en mémoire GPU, l'afficher est très rapide, il suffit de dire au GPU: affiche tel polygone en le remplissant avec telle texture.

    Quand on dessine dans drawRect:, le dessin est effectué par le CPU, puis affecté à  la "backing" CALayer de la UIView. Une seule grosse bitmap est donc utilisée pour afficher la vue.

    Quand on utilise un arbre de CALayers, il faut faire du compositing: demander à  OpenGL d'afficher plusieurs petites textures. Note que les CALayers peuvent être transparentes par endroit, aussi il faut prendre en compte la couche alpha dans l'affichage (alpha blending), et on est obligé de rendre toutes les CALayers d'en dessous.

    Comme je le disais, les UIViews utilisent toujours une CALayer. Si tu construits un arbre de UIViews, tu auras donc un arbre de CALayers. On peut aussi utiliser les CALayers directement, sans UIViews. Dans ce cas c'est plus rapide " une CALayer est moins complexe qu'une UIView " mais aussi moins de facilités " une CALayer ne peut pas répondre aux événements, par exemple.

    En conclusion, il n'y a pas trop de raisons de ne pas utiliser des UIViews !
  • D'accord, merci, ai-je bien compris la différence entre drawRect de CG et CALayers... :) dans les 2 cas le CPU charge une texture en mémoire qui sera réaffichée par le GPU... mais drawRect va copier tous les pixels de l'écran dans une bitmap, alors que le CALayer va délimiter uniquement ce qu'il veut dessiner ?


     


    En fait, c'était au niveau des tableViews, j'avais lu qu'il valait mieux créer les tableViewCells avec le code et la méthode drawRect, plutôt que des "subviews", pour "améliorer la performance" mais j'ai pas trouvé beaucoup plus de détails là -dessus, à  part l'histoire de la transparence.


Connectez-vous ou Inscrivez-vous pour répondre.