Hardening consulting

Buffers partagés dans wayland

waylandUn petit post à propos des buffers partagés dans wayland, l'implémentation wl_shm.

Quand un client fait une mise à jour de l'affichage, la nouvelle image pourrait être envoyé à travers la socket entre le client et le compositor, mais ce serait extrêmement lent: des appels à read() / write() passant par la case kernel sans parler des coûts de copie mémoire associés.

Dans wayland, il a été choisi de partager ces informations de surfaces en utilisant des mémoires partagées. Le design est le même que l'extension SHM de X11, sauf que dans wayland ce n'est pas une extension mais le seul moyen pour envoyer des surfaces au compositor.

Petite note: une des différences entre mir et wayland, c'est que les buffers sont gérés par le serveur dans un cas et par les clients dans l'autre.

Donc tout roule comme sur des roulettes, le client fait ses mises à jour de l'affichage dans la zone de mémoire partagée, et il prévient le compositor en envoyant des ordres de mises à jours dans la socket qui le relie au compositor.

Problème: si on se contente de ça, on va avoir des accès concurrents sur le buffer partagé: le client et le serveur vivent leur vie chacun de leur coté, et il y a fort à parier que le client va vouloir faire d'autres modifications graphiques pendant que le serveur sera en train de fabriquer l'image globale du desktop. Pour régler ce problème, le client est prié de ne plus utiliser le buffer tant que le serveur ne l'aura pas notifié. Le serveur notifie les clients quand il a utilisé un buffer pour faire la mise à jour de l'affichage, ce qui permet au client de libérer ou de réutiliser ce buffer.

double-buffering Le client ne va pas rester à se tourner les pouces en attendant que le serveur ai fini ses opération, on a une implémentation assez classique de double-buffering:

  • le client alloue 2 buffers;
  • il dessine dans le premier;
  • il notifie le compositor de la mise à jour de la surface;
  • il dessine dans le second;

Entre temps le compositor devrait avoir notifié de la libération du premier, ce qui permettra de s'en resservir.

triple-bufferingOn peut aussi faire une implémentations de triple-buffering:

  1. un buffer envoyé au compositor;
  2. un buffer qu'on a préparé et qu'on attend d'envoyer;
  3. un buffer qui sert pour les modifications courantes

Quand on recevra un avis de libération du buffer 1, on shifte les buffers:

  • le buffer 2 est envoyé;
  • le buffer 3 devient celui qui est en attente d'envoi;
  • et le buffer 1 qui vient d'être libéré devient celui qui sert pour les modifications courantes

Wayland ne fige pas comment est implémenté tout ceci, il ne fourni qu'un service de pool de buffer, le client l'utilise comme il lui semble le plus efficace ("wayland is all about choices").

Sources

Les éléments cités dans cet article:

  • le fichier qui décrit le protocole wayland avec la partie wl_shm. Le code de parsing est généré à partir de ce fichier;
  • l'article de wikipedia sur le multiple-buffering, d'où sont extrait les schémas.

Commentaires