À la sortie de Qt 5.0 et de Qt Quick 2, en 2012, l’un des grands changements du côté du rendu était l’utilisation exclusive d’OpenGL 2.0 : OpenGL était vu, à l’époque, comme l’API de choix pour le rendu matériel, peu importe la plateforme (Windows, Linux, macOS, mais aussi sur mobile et dans l’embarqué, avec sa déclinaison OpenGL ES). Cependant, depuis lors, le paysage s’est fortement complexifié.
La solution actuelle ne fonctionne plus
D’un côté, les API de dernières génération ont des concepts radicalement différents (et l’OpenGL nouveau a même changé de nom : Vulkan). De plus, côté embarqué, les processeurs sans GPU OpenGL sont légion, ce qui interdit le déploiement d’applications Qt Quick (à moins d’utiliser une extension autrefois payante, Qt Quick 2D Renderer, compatible avec Qt 5.4 et plus récents). Sur Windows en particulier, l’état des pilotes OpenGL n’était pas toujours excellent (surtout sur les machines où les pilotes graphiques ne sont pas à jour), ce qui impactait directement les applications Qt Quick : dès Qt 5.4, il était possible de choisir, à l’exécution, d’utiliser ANGLE (une implémentation d’OpenGL par-dessus DirectX) ou llvmpipe (une implémentation purement logicielle d’OpenGL).
Ces solutions ne sont en réalité que des emplâtres sur une jambe de bois : un rendu purement logiciel n’est pas envisageable dans bon nombre de situations où la puissance de calcul n’est pas suffisante ; Qt Quick ne peut pas exploiter des API natives, mieux gérées sur chaque plateforme… surtout que le nombre d’API disponibles a fortement augmenté. En effet, le choix ne se porte plus entre Direct3D et OpenGL, notamment puisque les API modernes, de plus bas niveau, sont au nombre de trois : celle d’Apple (Metal), celle de Microsoft (Direct3D 12) et la seule norme multiplateforme (Vulkan). De plus, pour l’ingénierie logicielle, Qt Quick 2D Renderer ne s’intègre pas bien au reste de Qt Quick (il s’agit d’un module séparé).
Une nouvelle génération plus modulaire
Un des objectifs de Qt 5.8 est de refactoriser le code de rendu côté Qt Quick, c’est-à -dire de le découpler d’OpenGL… de le modulariser (c’était le mot clé lors du développement de Qt 5). Ainsi, il devient possible d’utiliser de nouvelles API pour le rendu des scènes Qt Quick, en implémentant une extension qui effectuera la traduction entre le graphe de scène et l’API de rendu. Tout comme il était possible, sous Windows, de passer d’OpenGL à ANGLE à l’exécution, il sera possible de changer d’API à l’exécution. Grâce à l’utilisation d’une représentation assez abstraite de la scène à afficher, chaque extension n’a pas beaucoup de contraintes à respecter dans son implémentation, ce qui permettra de l’utiliser à son plein potentiel.
Cette étape ne fait pas que déplacer des monceaux de code d’un bout à l’autre : des parties de l’implémentation du graphe de scène étaient extrêmement liées à OpenGL. Cela a forcé les développeurs à marquer certaines parties de l’interface publique de Qt comme désapprouvées dès Qt 5.8, de nouvelles API sans ces gênantes dépendances envers OpenGL sont en cours de développement pour les remplacer. Sont notamment concernés les systèmes des matériaux et des particules… mais aussi bon nombre de fichiers d’en-tête dans l’implémentation de Qt Quick : le code C++ incluait ceux d’OpenGL, même si le module Qt Quick 2D Renderer s’occupait de l’affichage (la solution était de définir des fichiers d’en-tête minimaux pour que le code compile — ce qui faisait planter l’application à toute tentative d’appel à OpenGL, forcément impossible).
Direct3D 12 sera le premier concerné par cette refactorisation en profondeur : une extension expérimentale sera livrée avec Qt 5.8 (à côté de celle pour OpenGL, qui garantit la compatibilité avec le code existant), utilisable tant pour les applications traditionnelles (Win32) qu’universelles (UWP). Même si deux gros développeurs derrière Qt (la Qt Company et KDAB) sont membres du consortium Khronos « pour promouvoir Vulkan », il n’y aura pas d’extension pour le moment.
Un moteur de rendu logiciel aux vitamines
Par la même occasion, le moteur de rendu logiciel (ex-Qt Quick 2D Renderer) est retravaillé, notamment au niveau de la performance. Le point principal qui arrivera avec Qt 5.8 est la possibilité de mettre à jour partiellement chaque image affichée, selon les parties qui ont réellement changé dans la scène. Ainsi, une animation qui était autrefois très coûteuse en CPU (une partie pour l’animation elle-même, une plus grosse encore pour redessiner entièrement l’écran à chaque image) deviendra accessible.
L’intégration avec des interfaces à base de widgets avec QQuickWidget sera aussi possible : des applications comme Qt Creator (qui utilisent la classe QQuickWidget) ne pouvaient donc pas utiliser ce moteur de rendu logiciel. Maintenant que le rendu est implémenté au plus près de Qt Quick, le transfert des images entre Qt Quick et les widgets devient possible.
Source : The Qt Quick Graphics Stack in Qt 5.8.
Merci à Claude Leloup pour ses corrections.