J'ai parcouru le code et même si je n'ai pas tout compris, ça commence à s'éclairer un peu. Je ne vais parler que de la partie graphique, la gestion du port parallèle ne m'intéresse que dans la mesure où je peux la supprimer, en conservant néanmoins le pilotage des lunettes via ce port.

Programmation par IRQ

Visiblement tout ce qui concerne le page flipping et la synchronisation avec le retour vertical se passe dans la fonction qui est appelée à chaque fois que l'interruption reliée à la carte graphique NVIDIA (IRQ 16 par défaut) est déclenchée.

Il faudra faire en sorte que la valeur de cette interruption soit lue directement et pas définie par défaut, probablement en parsant /proc/driver/nvidia/cards/*. Il faudra voir si on a besoin de prendre en compte plusieurs interruptions s'il y a plusieurs cartes, ce serait quand même bien de gérer le SLI. Ce n'est pas le cas sur l'ancien driver NVIDIA et les drivers iZ3D et Tridef, à voir pour le driver NVIDIA 3D Vision.

Initialisation

Dans un premier temps, cette fonction entre dans un mode d'initialisation dans lequel la durée d'une trame est calculée, en mesurant le temps entre un début/fin de retour vertical et le suivant. La fonction passe ensuite en mode synchronisation.

Synchronisation

En mode synchronisation, il y a une évaluation de la différence entre le temps actuel et le temps évalué précédemment pour le prochain retour vertical. Si cette différence est inférieure à -1000 µs, ce n'est pas un retour vertical et on rend la main de suite. Si cette différence est supérieure à 1000 µs, on a sans doute raté un retour vertical et on l'affiche dans le log. Sinon il y a un code assez compliqué à base de compteurs auquel je n'ai rien compris pour l'instant pour les valeurs entre -1000 et -100 µs et 1000 et 100 µs.

Si on a un retour vertical, raté ou pas, on envoie la séquence de page flipping en programmant le CRTC VGA et on envoie le signal adéquat aux lunettes suivant qu'on est sur un retour vertical pair ou impair. La parité de la valeur du retour n'a de valeur qu'en interne, on ne peut pas s'en servir pour garantir une obturation des lunettes toujours dans le bon ordre après activation du module. Il faudra donc bien inclure un code de pilotage direct via le bit SDA du DDC en s'appuyant sur I2C pour les lunettes VGA DDC.

Pilotage du CRTC

Le pilotage du CRTC semble avoir quelques limites, déjà il faut séparer la détection du retour de la gestion du page flipping.

Page flipping

Pour l'instant il y a du code pour faire du page flipping via les registres standards du CRTC VGA. Les cartes NVIDIA disposant de deux CRTCs pour le TwinView, il faudra trouver les adresses du deuxième CRTC en lisant de la doc ou en étudiant nvclock ou les drivers nv et nouveau.

Ça permettrait de pouvoir au moins choisir lequel des deux écrans utiliser, étant donné que pour l'instant le page flipping s'active toujours sur le même, quelles que soient les options sélectionnées dans nvidia-settings ou la valeur choisie pour la variable head dans le code. Il est possible que les adresses pour le deuxième CRTC (choisi selon la valeur de la variable head) soient erronées dans le code après comparaison avec le code de nv. Mais il va falloir pousser un peu plus loin parce que ce n'est pas programmé du tout pareil.

Il faudra voir également si on peut faire du page flipping sur deux écrans, ce qui semble ne pas être possible en lisant les docs NVIDIA. En effet celles-ci indiquent qu'avec XVideo ou OpenGL on ne peut synchroniser sur le retour vertical que pour un seul écran. Il faudra voir si ça concerne le page flipping, la détection du retour vertical ou les deux.

Ça pourrait concerner le page flipping parce que selon les docs il y aurait un unique framebuffer en TwinView sur lequel les deux CRTCs s'appuient et on ne pourrait donc changer l'adresse que de l'un des deux. Ça me paraît bizarre étant donné que le code actuel ne fait du page flipping que sur un seul écran, l'autre affichant toujours la même chose.

Limite de résolution pour le page flipping

Une seconde limite tient à la résolution supportée pour le page flipping. Pour l'instant, la résolution horizontale est fixée à 1024 dans le code, il faudra essayer avec des modes supérieurs à 1024x768 pour voir si ça fonctionne.

Dans le code de page flipping, il est indiqué que le code supporte du 1024 ou inférieur en offset, donc c'est un peu inquiétant. Il est aussi indiqué qu'auparavant le code gérait des offsets supérieurs à 0x40000 (256K, la mémoire maxi en VGA) mais que ça a été supprimé à cause d'un accès à des registres NVIDIA spécifiques qui créent des instabilités.

Donc je ne sais pas du tout ce qui est supporté concernant les modes graphiques. Je ne comprends d'ailleurs pas comment il définit l'offset en ne se basant que sur le nombre de colonnes et le nombre d'octets par pixel. Si on a un framebuffer avec les données alignées, il faudrait aussi utiliser la résolution verticale pour le calcul. Il va falloir relire ce code pour voir ce que ça fait réellement.

Détection du retour vertical

La détection du retour vertical ne me semble pas être très optimale. En regardant un peu la doc sur la programmation des registres VGA, on voit qu'il existe un registre sur lequel on peut lire l'état du retour pour les cartes EGA (ouais, ça nous rajeunit pas :).

@@ 3C2h (R): Input Status #0 Register

        bit 4  Status of the switch selected by the Miscellaneous Output
               Register 3C2h bit 2-3. Switch high if set.
            5  (EGA Only) Pin 19 of the Feature Connector (FEAT0)
                          is high if set
            6  (EGA Only) Pin 17 of the Feature Connector (FEAT1)
                          is high if set
            7  (EGA Only ??) If set IRQ 2 has happened due to Vertical
                     Retrace. Should be cleared by IRQ 2 interrupt routine
                     by clearing port 3d4h index 11h bit 4.@@

Donc on pourrait peut-être se passer des évaluations de la durée d'une trame et juste regarder l'état du bit 7 de ce registre pour savoir si l'interruption est due à un retour vertical. À tester bien évidemment, voir aussi s'il n'existe pas un registre équivalent pour les cartes VGA ou NVIDIA. Ça semblerait logique, sinon c'est assez goret comme façon de détecter les retours verticaux.

Visiblement il n'y a qu'une IRQ, donc est-ce vraiment possible de détecter les retours pour deux écrans ? S'il y a deux CRTC, je ne vois vraiment pas pourquoi on ne pourrait pas. Après tout, OpenGL et XVidéo arrivent bien à tester ce retour pour l'un ou l'autre des écrans et c'est pris en compte immédiatement. Ça semble indiquer qu'il y a juste lecture d'un flag et pas une reprogrammation hard, donc pourquoi pas...

Calculs d'ajustement

Il y a également quelques calculs qui sont faits dans cette fonction indépendamment de l'état de l'application. Ça concerne probablement des ajustements pour la synchronisation des machines distantes, mais je n'ai pas compris comment ça fonctionnait. Ce sera probablement du code à supprimer, mais il faudrait quand même comprendre à quoi ça sert avant.