Фикс DPI на Linux + nVidia

24 декабря 2022 64 Linux Desktop

Проблема

Несколько лет назад приобрел монитор с IPS матрицей и обычным DPI (Benq BL2411PT). Но сразу после его подключения шрифты и графические элементы мне казались слегка замыленными при включенном сглаживании. Особенно было заметно в Хроме и приложениях на электроне (там они харкодят свои настройки рендеринга шрифтов). Перековырял все настройки шрифтов, настройки монитора, подобрал идеальные шрифты, даже кабеля пробовал другие. Подобрал вроде бы как оптимальные значения. Но все равно ощущение мыла не покидало меня. Причем другие люди не замечали этого «мыла», для них было все отлично. В итоге забил и списал это на мое восприятие IPS матрицы с обычным DPI (на IPS немного другая структура пикселей, до этого у меня были только TN матрицы). Уже начал подумывать о приобретении другого монитора с HiDPI. Но потом как-то глаза привыкли и не вытекали. Только сейчас решил докопаться до истины 🙂

P.S.:

  • пост актуален для одномониторной конфигурации (в многомониторной конфигурации будут некоторые отличия);
  • используется X-сервер;
  • используются проприетарные драйвера nVidia;
  • фиксил на Debian 11 + xfce4.

Поиск проблемы

Теоретически «мыло» может создаваться при несоответствии пиксельной сетки монитора тому, что выдает X-сервер.

Находим спецификации монитора:

Видим, что DPI 94, а диагональ 24″.

Проверяем, какой DPI установлен в X-сервере:

$ xrdb -q | grep dpi

В выхлопе пусто, значит DPI не задан жестко в базе.

Посмотрим информацию X-сервера через xdpyinfo (нас интересует dimensions и resolution):

$ xdpyinfo | grep 'dimensions\|resolution'
  dimensions:    1920x1200 pixels (524x321 millimeters)
  resolution:    93x95 dots per inch

Тут видим, что разрешение нормальное, но DPI почему-то уже не 94×94, а 93×95.

Теперь посмотрим через xrandr, в каком режиме подключен и работает монитор:

$ xrandr -q | grep -w connected
DP-0 connected primary 1920x1200+0+0 (normal left inverted right x axis y axis) 518mm x 324mm

Тут видим, что физические размеры экрана (518x324mm) отличаются от тех, что получили от xdpyinfo (524x321mm). Т.е. монитор работает с одним DPI, а X-сервер выдает картинку в другом. Кто же у нас врет? 🙂

WTF?

Копаем глубже. Беглый гуглеж нашел матрицу монитора — LM240WU8-SLD1.

Тут видим реальные размеры рабочей области матрицы — 518.4x324mm. Значит X-сервер выдает картинку с неверным DPI. Получается изображение выводится на матрицу монитора не пиксель в пиксель.

Параметры изображения X-серверу передает драйвер видеокарты. А драйвер расчитывает DPI сам, либо берет данные с EDID монитора (паспорта монитора). Найдем упоминание DPI в логе X-сервера:

$ grep DPI /var/log/Xorg.0.log<br>[ 43769.535] (--) NVIDIA(0): DPI set to (93, 95); computed from "UseEdidDpi" X config

Здесь мы видим, что драйвер видеокарты запрашивает значение DPI из EDID монитора.

Посмотрим, что у нас прописано в EDID. Нас интересует DTD (Detailed Timing Descriptors). Проще говоря, это параметры работы матрицы, рекомендуемые производителем. Для этого поставим edid-decode (есть в репозиториях дистрибутивов) для вывода EDID в человекочитаемом виде и проверяем:

$ xrandr --props | edid-decode -c -s | grep DTD
    DTD 1:  1920x1200   59.950 Hz   8:5    74.038 kHz 154.000 MHz (518 mm x 324 mm)
    DTD 2:   720x480    59.940 Hz   3:2    31.469 kHz  27.000 MHz (518 mm x 324 mm)
    DTD 3:  1280x720    60.000 Hz  16:9    45.000 kHz  74.250 MHz (518 mm x 324 mm)
    DTD 4:   720x480    59.940 Hz   3:2    31.469 kHz  27.000 MHz (518 mm x 324 mm)
    DTD 5:   720x576    50.000 Hz   5:4    31.250 kHz  27.000 MHz (518 mm x 324 mm)

Рекомендуемые режимы расположены в порядке приоритета. Тут видим, что первый режим соответствуют параметрам матрицы в спецификации. Значит виноват драйвер. Могу только предположить, что он обращается к EDID монитора, игнорирует рекомендуемые параметры, берет другую информацию о дисплее. На основе этих данных расчитывает другие размеры матрицы и по ним неверно расчитывает DPI.

Решение проблемы

Чтобы это пофиксить, нужно везде принудительно указать правильный DPI.

Передаем правильный DPI в базу X-сервера:

$ echo "Xft.dpi: 94" >> ~/.Xresources
$ xrdb -merge ~/.Xresources

Заставим все приложения использовать нужный DPI после запуска X-сервера:

echo "xrandr --dpi 94" >> ~/.xsessionrc

Если в DE есть возможность указания кастомного DPI, то меняем значение на корректное или вообще отключаем. Например, в xfce4 DPI указывается в настройках шрифтов:

Теперь заставим драйвер использовать наш DPI. Для этого установим nvidia-xconfig (если еще не стоит). И с помощью него сгенерируем конфиг X-сервера, который будем править:

$ sudo nvidia-xconfig

Он создаст базовый конфиг в /etc/X11/xorg.conf. Скопируем этот конфиг в конфиги X-сервера:

$ sudo cp /etc/X11/xorg.conf /usr/share/X11/xorg.conf.d/20-nvidia.conf

Теперь открываем скопированный файл любимым текстовым редактором и вставляем в секцию Device такие строчки:

Option "UseEdidDpi" "False"
Option "DPI" "94 x 94"

Должно получится примерно так:

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    Option         "UseEdidDpi" "False"
    Option         "DPI" "94 x 94"
EndSection

Теперь выходим из сессии, авторизуемся и проверяем:

$ xdpyinfo | grep 'dimensions\|resolution'
  dimensions:    1920x1200 pixels (518x324 millimeters)
  resolution:    94x94 dots per inch
$ xrandr -q | grep -iw 'screen\|connected'
Screen 0: minimum 8 x 8, current 1920 x 1200, maximum 32767 x 32767
DP-0 connected primary 1920x1200+0+0 (normal left inverted right x axis y axis) 518mm x 324mm
$ grep DPI /var/log/Xorg.0.log
[ 46562.124] (**) NVIDIA(0): Option "DPI" "94 x 94"
[ 46562.539] (**) NVIDIA(0): DPI set to (94, 94); computed from "DPI" X config option

Все чётко, везде правильные размеры и DPI, а драйвер берет значение из конфига, а не EDID.

После авторизации сразу заметил, что все стало четче и меньше стала заметна радуга в шрифтах, которая актуальна при включении сглаживания шрифтов. В хромобраузерах и проложениях на электроне мыло тоже пропало.

Комментарии (0)

5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии