Nom et coordonnées
- nom : Tarek Yasser
- site web : github, linkedin
- nom d’utilisateur GitLab : knockerpulsar
- fuseau horaire : UTC+3
Titre
Remplacer OpenGL par une bibliothèque de rendu multi-API
Brève description du travail réalisé
-
Portage de Splash sur le Raspberry Pi 4 au moyen d’OpenGL ES, en quelques phases :
- Conversion des appels OpenGL 4.5 vers leurs équivalents OpenGL ES 3.2,
- Adaptation des shaders pour OpenGL ES 3.2 (directives de version et de précision des flottants, divers correctifs mineurs),
- Retrait des initialisations d’uniformes dans les shaders, non prises en charge par OpenGL ES 3.2,
- Fusion des chemins de code OpenGL 4.5 et OpenGL ES 3.2 existants,
- Extraction du code graphique vers des classes distinctes pour permettre d’autres extensions,
- Nombreux nettoyages de code et corrections de bogues
-
Extension du code de tests unitaires de Splash pour permettre la comparaison d’images : cela m’a semblé un bon point de départ pour me familiariser avec le code de test de Splash. C’est toujours une bonne idée d’entamer un refactoring par quelques tests, afin de s’assurer que la sortie reste la même. Ce mécanisme est encore peu utilisé, mais il peut servir de base à d’autres tests graphiques.
-
Étude de diverses bibliothèques de rendu (magnum, Granite, bgfx, entre autres) : l’une de nos premières idées était de remplacer purement et simplement le code de rendu existant par quelque chose qui gérerait toute la complexité à notre place. Or, même si toutes ces bibliothèques suffisent amplement aux besoins de Splash, elles ajoutaient elles aussi de la complexité — certaines du côté des shaders, par exemple. Nous avons alors décidé d’explorer d’autres pistes, comme Vulkan et OpenGL ES.
-
Évaluation de la viabilité de Vulkan (pour une réécriture) et d’OpenGL ES (en remplacement direct) avec le code de rendu existant : le Raspberry Pi (Rpi) prend en charge les deux. Vulkan convient mieux aux appareils modestes comme le Rpi, car sa surcharge côté CPU est plus faible, tandis qu’OpenGL ES a surtout été envisagé parce qu’il est proche du code existant et compatible avec le Rpi. Son implémentation et sa maintenance seraient également moins complexes que celles de Vulkan.
-
Tests de la plupart des fonctionnalités graphiques afin de détecter les bogues qui ne sautent pas aux yeux.
-
Recherche de moyens de profiler la performance du GPU du Pi, et quelques passes de profilage rudimentaires.
Code intégré
- MR #595 : ma première contribution au projet, un simple correctif dans la documentation, où un lien ne pointait pas au bon endroit.
- MR #600 : extraction du code dupliqué de récupération d’erreurs vers des fonctions distinctes. Utilise aussi des fonctionnalités C++ plus récentes au lieu de code de style C.
- MR #602 : deuxième tentative pour faire fonctionner Splash sur le Pi avec OpenGL ES, plus propre, avec une meilleure séparation des commits et davantage de bogues corrigés que la MR #598 (la première version).
- MR #618
- Fusionne le nouveau chemin de code OpenGL ES avec le chemin de code OpenGL existant
- Tente de créer automatiquement un renderer lorsqu’il n’est pas fourni en ligne de commande.
- Fournit une API pour créer et utiliser des objets OpenGL selon le renderer sélectionné.
- Corrige de nombreux bogues nouvellement découverts.
- MR #621 : corrige un bogue où les objets Image n’utilisaient pas la spécification transmise, ce qui produisait une image de taille incorrecte et des accès hors limites.
- MR #623 : corrige un bogue où les callbacks de débogage OpenGL plantaient à cause d’un cast et du passage d’un objet du mauvais type.
- MR #628 : sort le code graphique des classes existantes pour faciliter l’implémentation d’autres API au besoin, et refactorise du code graphique jusque-là intouché.
Code non intégré
- MR #596 : il s’est avéré que tester Splash manuellement n’était pas si long, alors cette piste est restée en plan pendant que j’étais occupé à porter Splash sur le Rpi. La MR contient toutefois du code prototype pour les tests graphiques, qui pourrait être intégré ou réutilisé plus tard.
- MR #598 : première tentative d’utiliser OpenGL ES au lieu d’OpenGL pour faire fonctionner Splash sur le Rpi. Globalement une réussite, mais la branche était un peu désordonnée et a été remplacée par la MR #602.
- MR #601 : simple test pour me familiariser avec le cadre de tests unitaires de Splash. Pour les mêmes raisons que la MR #596, elle n’a pas reçu beaucoup d’attention.
- MR #622 : déjà incluse dans la MR #628. Remplace du code dupliqué et de bas niveau servant à lire une texture depuis le GPU par une implémentation RAII de plus haut niveau.
Ce qu’il reste à faire
Certains objectifs du projet n’ont pas été pleinement atteints, en raison de limites (surtout) techniques. Par exemple :
- Profilage de la performance GPU sur le Rpi : nous avons opté pour OpenGL ES, mais la spécification n’exige aucune fonctionnalité de profilage. Le Rpi n’offre donc aucune option de profilage native ou portable. Une autre possibilité aurait été l’extension
GL_AMD_PERFORMANCE_MONITOR, mais elle demandait du travail à mettre en place et encore davantage à utiliser correctement. Rien ne garantissait non plus sa portabilité d’un GPU à l’autre. Nous avons finalement jugé que cela représentait trop de travail pour une seule plateforme et avons renoncé complètement au profilage de la performance GPU. - Optimisation graphique : faute de pouvoir déterminer précisément où se situaient les goulots d’étranglement, la seule option pour optimiser le code graphique était d’optimiser à l’aveugle les parties dont nous pensions qu’elles amélioreraient la performance sur le Pi. Cela aurait évidemment demandé trop de temps, et a donc aussi été écarté pour l’instant.
Pour aller plus loin
Billet de blogue détaillant d’autres étapes du parcours.