Haute densité (HiDPI) avec deux écrans 4K sous Linux

Vincent Bernat

J’utilise un portable Lenovo ThinkPad X1 Carbon (210 PPP) depuis quatre ans ainsi qu’un téléphone Nokia 8 (550 PPP) depuis un an. J’apprécie la haute densité de leurs écrans respectifs : le rendu du texte est excellent. Pour obtenir des résultats similaires avec ma station de travail, j’ai acheté une paire d’écrans Dell P2415Q :

Deux Dell P2415Q
Configuration en écrans doubles avec deux moniteurs Dell P2415Q

Écrans#

Le Dell P2415Q est un écran 24″ doté d’un panneau IPS d’une résolution de 3840×2160 (185 PPP) et une couverture complète de l’espace de couleurs sRGB. Il est sorti en 2015 et son prix est désormais sous la barre des 400 €. Il a reçu des critiques positives.

L’une des unités est arrivé avec un pixel mort. Je pensais qu’il s’agissait d’un problème du passé, mais la politique de Dell concernant les pixels morts stipule :

Lors du processus de fabrication des écrans LCD, un ou plusieurs pixels se figent parfois dans un état immuable. Un écran comportant de 1 à 5 sous-pixels figés est considéré comme normal et conforme aux normes industrielles.

Mise à jour (12.2018)

Trois nouveaux pixels morts sont apparus. Aussi, je vous recommande d’éviter ces écrans.

Un deuxième problème est la présence de lignes grises horizontales (difficilement) visibles sur fond blanc. Le problème ne semble pas être rare, mais Dell est peu enthousiaste à ce sujet. Si je m’assois correctement, les lignes deviennent invisibles.

Mise à jour (06.2020)

Cela ne se produit que lorsque l’écran est branché en HDMI. Dans ce cas, le format des pixels est YCbCr au lieu de RGB. J’ai corrigé ce problème en bidouillant l’EDID de l’écran pour forcer le pilote à utiliser RGB.

Je suis un peu déçu par ces aspects, mais je pense qu’ils restent supportables et que c’est l’occasion de corriger mon obsession pour ces détails.

Carte graphique#

Pour piloter un écran 4K à 60 Hz, il faut au moins un connecteur HDMI 2.0 ou DisplayPort 1.2. Le Dell P2415Q a été mis à niveau vers HDMI 2.0 en 2016 et dispose également d’une entrée DP 1.2. Il y a un port pour chaîner un second écran, mais en l’absence de prise en charge de DP 1.3, le taux de rafraîchissement tomberait à 30 Hz.

Il n’y a actuellement aucune carte Radeon disponible autour de 100 € et capable de piloter deux écrans 4K. Côté NVIDIA, la GeForce GT 1030 convient avec une consommation de 20 W pour la version DDR4. J’ai opté pour un modèle à refroidissement passif de MSI. Sous Linux, le résultat est assez décevant :

  • Le pilote nouveau n’a encore qu’une prise en charge rudimentaire pour cette génération de puces NVIDIA. Le résultat est excessivement lent et le port HDMI 2.0 n’est pas géré correctement.

  • Le pilote propriétaire NVIDIA présente d’importants problèmes de performance. Il est difficile de savoir si ceci est dû à la carte elle-même1 ou aux pilotes. J’ai testé les versions 390, 396, 410, 415 et 418 sans grand changements. De plus, la suspension en mémoire ne fonctionne pas.

Mise à jour (05.2019)

J’ai finalement opté pour une ASUS Phoenix Radeon RX 550. Avec une telle carte, tout tourne comme une horloge en utilisant le pilote libre amdgpu. La carte est équipée d’un ventilateur mais il est possible de contrôler sa vitesse. Le wiki de ArchLinux contient davantage de détails. En mode automatique, lorsque /sys/class/drm/card0/device/hwmon/hwmon1/pwm1_enable est placé à 2, il tourne à 1050 tours par minute :

$ sensors amdgpu-pci-0100
amdgpu-pci-0100
Adapter: PCI adapter
vddgfx:       +0.88 V
fan1:        1047 RPM
temp1:        +51.0°C  (crit = +94.0°C, hyst = -273.1°C)
power1:       17.20 W  (cap =  35.00 W)

Prise en charge de la haute densité avec X11#

GNOME et KDE prennent désormais en charge les affichages à haute densité (HiDPI) sans configuration particulière sous X11. Pour les autres environnements, le paramétrage est assez simple, grâce à xsettingsd. Le code suivant doit être invoqué à partir de ~/.xsession ou lorsque la densité change :

# Densité cible
dpi=192

# Pour les applications supportant XSettings, `Xft/DPI' indique
# l'échelle pour les fontes (et parfois pour le reste de l'interface),
# `Gdk/WindowScalingFactor' indique l'échelle pour l'interface avec
# GTK 3 et `Gdk/UnscaledDPI' annule l'échelle choisie pour les fontes
# pour les applications GTK 3.
> ~/.xsettingsd cat <<EOF
Xft/DPI $(( $dpi*1024 ))
Gdk/WindowScalingFactor $(( $dpi/96 ))
Gdk/UnscaledDPI $(( $dpi*1024/($dpi/96) ))
EOF
pkill -HUP xsettingsd || xsettingsd &

# Pour les applications Qt.
export QT_AUTO_SCREEN_SCALE_FACTOR=1
export QT_SCALE_FACTOR_ROUNDING_POLICY=PassThrough

# Pour certaines autres applications.
echo Xft.dpi: $dpi | xrdb -merge

Ensuite, c’est à chaque application de savoir comment effectuer le rendu à la densité choisie. Le tableau ci-dessous donne un aperçu de la prise en charge pour certaines d’entre elles, en utilisant les paramètres ci-dessus. « Échelle du texte » indique si une application est capable d’adapter la taille du texte. C’est généralement la fonctionnalité la plus essentielle. « Échelle de l’interface » indique si elle est capable de mettre à l’échelle l’ensemble de l’interface, y compris les icônes. Idéalement, les applications devraient également être en mesure de changer dynamiquement leurs paramètres lorsqu’elles sont notifiées via XSettings, ce qui est utile lors du passage sur un écran externe.

Application Échelle du texte Échelle de l’interface Sans redémarrer ?
Applications Qt 5
Chromium2
Firefox (GTK 3)
Applications Electron3
Emacs 26.1 (GTK 3) 😐
Emacs 27.1 (GTK 3 avec Cairo) 😐
Terminaux VTE (GTK 3) 😐
Blender4
Gimp (GTK 2)
Inkscape (GTK 2)
Applications GTK 2
Applications GTK 3 😐
Applications Java5 🙄 🙄
xterm and rxvt (avec Xft) n/a
Autres applications

Les applications Qt 5 offrent une excellente prise en charge. Les applications GTK 3 ne peuvent utiliser qu’un coefficient multiplicateur entier pour mettre à l’échelle leurs interfaces, ce qui est ennuyeux quand on a besoin d’un facteur 1.5×. Les applications GTK 2 ne savent adapter que la taille du texte. Elles sont toujours assez nombreuses, avec notamment Gimp. Pour plus de détails, jetez un œil sur la page dédiée au sujet sur ArchWiki. Au-delà de X11, Wayland permet d’utiliser une densité différente pour chaque écran6 et de mettre à l’échelle les applications qui ne savent pas prendre en charge les densités élevées.

En conclusion, la situation actuelle dépend énormément des applications utilisées. Mes principales applications étant Firefox, Emacs et un terminal basé sur VTE, le résultat me satisfait.


  1. Par rapport à ma configuration précédente, le nombre de pixels est quadruplé. La carte utilise 4 voies sur PCI 3.0, ce qui correspond à une bande passante de 25 Gbits/s. Cela permet à peine le transfert de 7680×2160 pixels à 60 Hz en 24 bits. De plus, l’utilisation de mémoire DDR4 plutôt que GDDR5 est considéré comme une très mauvaise option↩︎

  2. Pour détecter les changements, Chromium surveille les évènements RandR. Ils peuvent être capturés avant d’avoir pu mettre à jour les variables XSettings↩︎

  3. Si cela ne fonctionne pas, essayez avec le drapeau --force-device-scale-factor=2↩︎

  4. Blender se base sur la valeur de la ressource Xft.dpi↩︎

  5. Les applications Java doivent être invoquées avec la variable d’environnement GDK_SCALE=2, sans quoi, aucune mise à l’échelle n’est effectuée. ↩︎

  6. Qt sait gérer les écrans de densités différentes avec QT_AUTO_SCREEN_SCALE_FACTOR=1 et QT_SCALE_FACTOR_ROUNDING_POLICY=PassThrough. GTK ne le permet pas mais les écrans avec un DPI plus faibles peuvent opter pour une résolution plus élevée et mis à l’échelle vers leur résolution d’origine avec l’option --scale de xrandr. L’article « Mixed DPI and the X Window System » aborde le sujet en détails tandis que « Configuring mixed DPI monitors with xrandr » se concentre sur l’usage de xrandr↩︎