lundi 28 novembre 2016

Une fractale sur mon téléphone

L'obstination a fini par payer, et j'arrive maintenant à afficher un bout de l'ensemble de Mandelbrot sur mon Ubuntu Touch ! Sans plus attendre, la démonstration en photo :

Les écueils furent nombreux, mais j'ai fini par à peu près comprendre comment approcher le problème. En particulier, le port vers OpenGL ES fut un poil tordu, mais j'ai maintenant une base qui fonctionne.

En termes de performances, mon téléphone calcule une image en 500ms. À comparer avec ma machine de bureau qui fait tourner (presque) le même programme en 1ms, ce qui est plutôt raisonnable si l'on considère que la carte graphique à elle seule coûte 2 fois le prix du téléphone.

Il va donc falloir revoir les performances d'une part (réduction de la précision, rafraîchir l'image le moins possible), et les fonctionnalités d'autre part: afficher l'ensemble de Mandelbrot, c'est bien, mais s'assurer que l'on a pas de déformations, que l'on peut zoomer, et qu'il y a un joli dégradé de couleurs, c'est mieux.

Je compte donc d'abord tenter d'unifier autant que possible mes programmes OpenGL et OpenGL ES, puis de développer sur le bureau, ce qui est quand même rudement plus confortable, avant de revenir sur le téléphone, et peut-être un jour publier l'application...

mardi 22 novembre 2016

Frustration

C'est frustrant, tout ça. J'ai l'impression qu'il y a une logique ésotérique que je n'arrive pas à saisir, et que toute approche un petit peu industrielle au développement d'une application sur mon Ubuntu Phone se solde par un échec.

Côté téléphone, il est vraiment très difficile de charger des bibliothèques tierces, ce qui est particulièrement frustrant lorsque l'on voit que dans les dépôts, tout est déjà compilé pour ARM, mais qu'il ne faut surtout pas l'utiliser, parce que les paquets Click, c'est le futur. OpenSceneGraph fonctionne jusqu'à ce que j'essaie de faire plus qu'afficher un écran blanc, puis plante. Les bibliothèques de chargement de sons dans SDL_mixer ont des tonnes de dépendances, non disponibles sur le téléphone. Argh !

Côté PC, ce n'est guère mieux. J'avais dans l'idée que je pouvais développer un programme en OpenGL ES 2 (la version apparemment présente sur le téléphone) sur PC, histoire de simplifier le déploiement et le débogage, et de le porter simplement ensuite sur le téléphone. Que nenni ! J'arrive bien à faire de l'OpenGL, mais pas de l'OpenGL ES. Ça n'affiche juste rien. Je ne sais pas si ce n'est juste pas possible, si c'est les drivers de ma carte qui sont foireux, ou si je suis juste bête.

Donc, parce qu'il ne manquerait plus que je me laisse abattre, j'essaie de développer un petit programme simple sous un "vrai" OpenGL, et je me battrai ensuite pour le porter sur le téléphone. Que de batailles épiques en perspective !

mardi 8 novembre 2016

Ubuntu Phone et SDL - Magie

Ça marche ! Rhaaaa ! Rhaaaaaaaaa ! Rhaaaaaaaaaaaaaaaaaaa !

Ça n'a pas été sans mal, mais j'ai enfin réussi à faire tourner un mini-programme utilisant la SDL. Quelle plaie ! On va tout reprendre depuis le début, et essayer d'expliquer comment y arriver.

La première épreuve est de télécharger une version de la SDL qui fonctionne avec la version de MIR, le serveur d'affichage de chez Ubuntu, disponible sur le téléphone. Alors c'est bien simple, SDL 2.0.5 a besoin d'une version de MIR trop récente (>= 0.25), et 2.0.4 a besoin d'une version de MIR trop vieille (0.14). Il faut donc aller trouver la bonne révision dans le dépôt SDL, pour aller chercher la SDL juste quand elle marchait avec MIR 0.24. Donc, dans votre répertoire courant, faites:

hg clone http://hg.libsdl.org/SDL -r 10361

Maintenant, ouvrez un shell sur la chroot de cross-compilation ARM (je rappelle pour ceux du fond qui ne suivent pas, dans QtCreator, c'est Tools => Options => Ubuntu => onglet Click => architecture armhf => Maintain). Dans ce shell, nous allons définir quelques variables d'environnement pour s'assurer que la cross-compilation est correctement configurée, en faisant pointer le compilo, l'éditeur de liens, et le PKG_CONFIG (pour MIR) au bon endroit.

export CC=/usr/bin/arm-linux-gnueabihf-gcc
export LD=/usr/bin/arm-linux-gnueabihf-ld
export AS=/usr/bin/arm-linux-gnueabihf-as
export CXX=/usr/bin/arm-linux-gnueabihf-g++
export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig/

Ensuite, on peut lancer la compilation en elle-même.

../SDL/configure --prefix=/usr/ --host=arm-linux-gnueabihf
make -j 4
make install

Tout se passe à peu près bien, et l'on peut vérifier que la bibliothèque est bien générée avec des instructions ARM

/usr/bin/arm-linux-gnueabihf-objdump -x /usr/lib/libSDL2.a | head -n 20

L'on voit de charmantes choses du genre "SDL.o: file format elf32-littlearm", qui sont quand même très bon signe.

Ensuite, construisons un programme SDL proprement dit. J'utilise un exemple tiré de StackOverflow, et j'ajuste l'édition de liens en ajoutant cette ligne au sein du fichier .pro pour lier SDL en statique :

LIBS += -l:libSDL2.a -ldl

Après, on lance, et miracle, j'ai des petits pixels qui s'affichent !

Alors, certes, ce n'est qu'une étape. Il est plaisant de voir que la cross-compile fonctionne, que SDL arrive à papoter avec MIR, et que l'on se trouve enfin en terrain connu.

Reste à compléter l'intégration. Dans mon programme d'exemple, la résolution est codée en dur, il faudrait arriver à récupérer la résolution du téléphone. Peut-on attraper l'événement de mise en arrière plan ? Peut-on attraper l'événement de rotation de l'écran ? Est-ce que les API SDL sont correctement reliées à la machine, et peut-on détecter un doigt, un geste, un geste à plusieurs doigts ? Est-ce que le son et la musique fonctionnent correctement ?

Mais ce sera pour un autre jour. Maintenant, dodo.

dimanche 6 novembre 2016

Développement d'applications avec Ubuntu Phone - Défaite partielle

Eh beh, mes tentatives de faire tourner quelque chose de vaguement 3D sur mon Ubuntu Phone se révèlent plus difficiles que prévu. J'ai compris beaucoup de choses, et réalisé que j'en ignorais encore plus. Petit topo.

Tout d'abord, dès que l'on commence à parler dépendances, il faut commencer par comprendre le système de paquets Ubuntu, appelé "click". C'est une nième réponse au problème des dépendances de paquet, et qui vise à fournir un petit paquet qui ne dépende que de l'installation par défaut. Le paquet doit donc fournir directement toutes les dépendances de l'application. J'ai trouvé les explications sur le sujet plutôt limitées, et le plus simple semble pour l'instant de faire de la compilation statique.

Ce que cela veut dire, c'est que l'on ne peut pas se reposer sur les paquets Ubuntu pour construire son application. En effet, ces paquets ne seront pas disponibles sur le téléphone, et même si vous arriviez à copier les bibliothèques dans le paquet click, elles dépendent certainement elles-mêmes de bibliothèques dynamiques.

Ensuite, parlons de l'environnement de cross-compilation : Le système lxd (voir post précédent) fournit une sorte de chroot, qui représente l'environnement du téléphone. Dans cette chroot, gcc, g++, ld, et tous les autres, sont en mode cross-compilation vers armhf.

Étant donné tout cela, l'approche qui semble fournir des résultats (c'est à dire, quelque chose d'autre qu'un crash immédiat) est de compiler soi-même au sein de la chroot toutes les dépendances nécessaires à l'application, vers des bibliothèques statiques.

Un exemple avec OpenSceneGraph : j'obtiens un shell vers la chroot (Tools => Options => Ubuntu => bouton "Maintain" de la "build target"). Depuis le chroot, l'on voit quand même son /home, j'y ai donc téléchargé le code d'OpenSceneGraph, et j'ai créé un répertoire build comme indiqué dans les instructions de compilation. Ensuite, l'on installe quelques en-têtes manquantes, et l'on compile OpenSceneGraph.

apt-get install libqt5opengl5-dev:armhf
aptitude install libgl1-mesa-dev:armhf
cmake ../OpenSceneGraph -DOPENGL_PROFILE="GLES2" \
-DCMAKE_INSTALL_PREFIX=/usr -DBUILD_OSG_APPLICATIONS:BOOL=OFF \
-DDYNAMIC_OPENSCENEGRAPH=OFF -DDYNAMIC_OPENTHREADS=OFF
make
make install

Une fois arrivé à ce niveau, j'ai ajouté la lignes LIBS += -losgViewer -losgDB -losgManipulator -losgGA -losgUtil -losgText -losg -lOpenThreads -ldl à mon fichier .pro, et j'ai copié un exemple d'intégration QT5 et OpenSceneGraph. Ça compile, youpie !

Et là, j'ai eu un bel écran blanc, soit-disant parce que j'utilisais un composant QT5 non supporté, que l'application osait utiliser un shader, et un peu de baratin additionnel de la même farine.

Conclusion ? Je ne suis pas très sûr. Il faut certainement que je tente une autre approche pour intégrer QT5 et OpenSceneGraph. Mais peut-être est-ce voué à l'échec de faire de la 3D sur un téléphone bas de gamme ? Peut-être que de la 2D, en utilisant directement la SDL et sans passer par QT, serait plus simple ? Ais-je vraiment envie de me taper la compilation de la SDL ? Est-ce que Mir (le serveur graphique de chez Ubuntu) va me causer des soucis ? Est-ce que finalement, je ne suis pas plutôt fait pour la programmation sur desktop ?

jeudi 3 novembre 2016

Développement d'applications sur Ubuntu Phone - Installation de l'environnement

Utilisant maintenant Ubuntu comme système d'exploitation principal, rien de m'empêche d'installer l'environnement de développement Ubuntu Phone ! Youpie !

Dans les faits, ce fut un poil plus compliqué que prévu. Ce qui n'aide pas, c'est que manifestement (mais on s'en doutait un peu), le développement d'applications pour les téléphones Ubuntu reste un marché de niche, et qu'il y a donc très peu de ressources en dehors du site d'Ubuntu lui-même. Donc, si l'on se retrouve confronté à un problème dans leur tutoriel, il faudra lutter pour s'en sortir.

Les explications sont donc ici. Et après, c'est la jungle... Je me suis en particulier beaucoup battu avec lxd. Alors, lxd, je ne connaissais pas, mais il s'agit d'une sorte de chroot, qui semble être utilisé pour faire de la cross compilation. Jusqu'ici, tout va bien, mais la chose refusait de démarrer. Finalement, en bidouillant bien plus que de raison avec les logs de systemd, j'ai fini par comprendre qu'il y avait conflit entre lxd d'une part, et bind9 d'autre part (j'avais bien entendu installé bind9 et mis dnssec en place), lequel conflit peut se résoudre en forçant bind9 à n'écouter qu'en ipv4, sur le loopback, ce qui me convient (mais ne conviendra pas à quelqu'un qui veut fournir du DNS au reste de son réseau local, ou, pire, utiliser IPV6). J'ai donc à la fin de mon /etc/bind/named.conf.options :

listen-on-v6 { none; };
listen-on { 127.0.0.1; };

Une fois cette épreuve surmontée, et lxd démarré (il faut insister, apparemment), qcreator apparait ! Hourra ! Mais un dernier obstacle se dresse devant le développeur amaigri. En effet, il faut créer le "kit", qui permet la cross-compilation. Et si on le créé avant d'avoir connecté le téléphone, on est garanti de se planter, et de se retrouver avec des programmes C++ qui foirent lamentablement. D'ailleurs, n'essayez pas de connecter le téléphone à travers le Wifi, malgré l'impression que QCreator y arrive, utilisez un bon vieux cable USB et le tour est joué. Ensuite, depuis la page "Devices", vous pourrez créer un kit correspondant au téléphone, qui devrait fonctionner tout seul.

Les exemples de projet sont suffisamment complets pour pouvoir démarrer : en particulier, QCreator débarque avec un projet en QML pur, en QML avec un backend C++, et en C++ pur avec injection de QML.

Comme premier projet, j'aimerais bien voir si j'arrive à intégrer OpenSceneGraph à une application Ubuntu Phone.

mercredi 2 novembre 2016

Ubuntu, KVM et Windows

Maintenant que je suis passé à un processeur i5, le monde merveilleux de la virtualisation s'ouvre à moi. L'idée est de se débarrasser enfin du double boot, et de le remplacer par des machines virtuelles, plus flexibles et plus rapides à démarrer en cas de besoin. En particulier, ayant besoin parfois de faire du développement sous Windows, il me faut une machine virtuelle Windows.

La mort de mon précédent PC n'ayant normalement pas d'incidence sur ma license Windows Vista (oui, c'est vieux), j'ai essayé d'installer la chose sur KVM, le système de virtualisation qui vient avec le noyau. Bien que doté d'une interface un peu austère, il est extrêmement puissant. En particulier, il est possible d'obtenir une grosse amélioration des performances en utilisant des pilotes spécifiques pour l'accès au disque et au réseau au sein de l'OS virtualisé. Ça se passe très bien avec Debian, mais c'est un petit peu moins direct avec Windows.

Je vous la fait courte, avec Windows Vista, ça ne marche juste pas. J'ai tout essayé, mais je reste bloqué tout au début de l'écran de chargement.

En revanche, avec Windows 7, c'est nettement mieux. Le truc pour obtenir directement une installation rapide et cohérente, c'est de s'assurer que le disque virtuel est de type "virtio", de monter l'image du disque d'installation de Windows dans un premier lecteur virtuel, et de monter une image spéciale fournie par KVM et qui contient les pilotes dans un deuxième lecteur virtuel (ouf!).

Au démarrage, Windows 7 voit bien un D: contenant l'installation, et un E: contenant des pilotes, mais pas de C:. Il propose alors d'installer les pilotes. Une fois le bon pilote choisi depuis le E: dans la catégorie "virtblo", il voit alors un C:, et peut s'installer dessus tranquillement, et à toute berzingue si vous avez eu la bonne idée de le laisser tourner sur un SSD. Et à partir de là, vous avez un beau Windows qui tourne à une vitesse très proche d'une installation native (modulo les applications demandeuses en terme de graphisme, tels les jeux vidéos, la magie a quand même des limites).

Mais bon (troll inside), avec les pilotes graphiques libres et propriétaires de chez monsieur AMD, tripotée de jeux sur Steam, et un client Citrix qui fonctionne du tonnerre (ne me jugez pas, c'est le boulot!), a-t-on vraiment besoin de Windows?

mardi 1 novembre 2016

Nouveau PC

Mon ordinateur est mort! Après 8 ans de bons et loyaux services, la machine a rendu l'âme dans un dernier soubresaut. Je n'ai pas trop creusé les causes du décès, mais j'étais à peu près sûr que le disque était encore en forme, et mes données saines et sauves. Direction Tottenham Court Road, l'équivalent de notre bonne vieille rue Montgallet, mais en nettement moins impressionnant. Ma nouvelle bête est un i5 avec 8Go de RAM, un SSD de 124 Go et un disque dur de 1 To, et une carte graphique Radeon RX 480.

Je me suis un peu battu avec l'UEFI, et j'ai fini par abandonner l'installation de Debian pour une Ubuntu pour laquelle AMD fournit de beaux drivers propriétaires. Le tout fonctionne particulièrement bien, et le SSD change vraiment la vie. Le démarrage de la machine et des applications est démentiel.

À noter, j'ai décidé de mettre tout le disque sur le SSD, en ne mettant sur le HDD que la partition de swap, le /var/log, et une grosse partition "data" que j'accède via un lien symbolique et sur lequel je peux mettre le bousin un peu lourdingue (collection de photos, principalement).