Приложение A - Срывая мистику c графики Linux
Содержание
Данное приложение является переводом презентации Мартина Файдлера KMS UXA DRM OMG WTF BBQ? Linux Graphics Demystified. (2 мая 2014, на Chemnitz Linux Days)
Когда Linux был создан вначале:
-
консоль Linux использовала оборудование VGA напрямую
-
... конечно, в текстовом режиме ☺
-
первые графические приложения привносили свои собственные драйверы
-
появились первые графические библиотеки, т.е. SVGALib
-
приложения отвечали за поддержку состояния имеющегося графического оборудования
-
при запуске: состояние графического оборудования сохраняется
-
при останове: состояние графического оборудования восстанавливается
-
всё ещё выполняется для X Server и по сей день
-
Первые в ряду инфраструктуры графического ядра: устройства буфера кадра (Framebuffer Devices, fbdev)
|
|
Наиболее широко применяемая графическая система в Linux: Система X Window (X11, X)
|
|
X клиенты не реализуют напрямую сам протокол X11, а применяют библиотеки:
-
обычную Xlib
-
более новую, более экономичную альтернативу XCB (X11 C Bindings)
-
наборы инструментов (
Motif
,Gtk
,Qt
, ...), которые внутри себя используют такжеXlib
илиXCB
диспетчер окон: особый X клиент, который уравляет положениями окон верхнего уровня и прорисовывает рамки окон ("декорации")
X сервер управляет вводом (клавиатура, мышь, ...) и выводом (только графика)
-
общая часть: DIX ("Device Independent X" - независящее от X устройство)
-
специфичная для оборудования часть: DDX ("Device Dependent X" - зависящее от X устройство)
-
содержит драйверы для устройств ввода и вывода
-
Наиболее популярная реализация X сервера: XFree86, на сегодняшний день, X.Org
-
часть DDX является модульной: драйверы являются отдельными модулями
-
интерфейс DDX может изменяться с каждой версией сервера
Общепринятый X протокол может быть расширен новой функциональностью через Extensions. Примеры:
-
XSHM (X Shared Memory): более быстрый локальный дисплей с растровой графикой
-
Xv (X Video): видео дисплей с аппаратным ускорением
-
GLX: OpenGL в X
-
Xinerama: поддержка множества мониторов
-
XRandR (X Resize and Rotate): установки графического режима без перезапуска самого X сервера
-
XRender: современная 2D графика со сглаживанием, альфа- смешением
-
на сегодняшний день применяется для (практически) всех приложений 2D графики
-
В XFree86/ X.Org имеется множество подходов для аппаратного ускорения 2D графики:
-
XAA (XFree86 Acceleration Architecture, 1996):
-
простое ускорение прорисовки линий и операций заполнения
-
-
EXA (2005): выросшая из KAA (Kdrive Acceleration Architecture, 2004)
-
посвящена ускорению XRender
-
-
UXA (Unified Memory Acceleration Architecture, 2008)
-
разработана Intel, определяется последователями EXA
-
не приспособлена для не- Intel драйверов
-
SNA (Sandy Bridge New Acceleration, 2011)
-
очень специфичная для Intel, но также очень быстрая
-
Glamor(2015)
-
реализует всё 2D ускорение через OpenGL
-
как результат: аппаратно независима
-
-
-
OpenGL (Open Graphics Language) является самым стандартным API для 3D графики.
-
стандарт в отрасли, патронируемый консорцикмом "Khronos Group"
-
функциональность: аппаратно ускоряемая прорисовка треугольников с текстурами
-
OpenGL ES
= "OpenGL for Embedded Systems" (OpenGL для встраиваемых систем)-
(в основном) подмножество OpenGL, примерно на 90% совместимо
-
-
OpenGL (ES) 2.0
и новые свойства программируемых shaders (шейдеров - построителей теней)-
C- подобный язык GLSL (OpenGL Shading Language)
-
-
механизм расширений (схожий с X11)
-
дополнительный API, требующийся в качестве "клея" для заключаемых в окна систем:
-
GLX для самой системы X Window
-
WGL (Windows), AGL (Mac OS X)
-
EGL для OpenGL ES (встраиваемых Linux, Android, iOS, ...)
Доступен во всех системах, со временем заместит GLX и проч.
-
Как выглядит OpenGL в Linux c X.Org на практике?
|
|
Имеются два вида реализации OpenGL в Linux:
-
поставляемые nVidia и AMD проприетарные драйверы
-
или Mesa
Mesa является реализацией OpenGL с открытым исходным кодом
-
... включая
GLX
,EGL
иOpenGL ES
-
изначально построение изображений только программным обеспечением
-
на сегодняшний день это основа для всех 3D драйверов с открытым исходным кодом
Gallium3D является инфраструктурой для реализации драйверов GPU независимыми от какой- бы то ни было операционной системы образом.
-
частично зависит от Mesa
-
это не только 3D графика - также осуществляет вычисления GPU и аппаратное видео- декодирование
-
три основные части:
-
State Tracker: реализация API клиента
т.е. OpenGL (через Mesa), OpenCL для вычислений, VDPAU и OpenMAX для видео
-
WinSys Driver: реализацию определённого уровня GLX или EGL
-
Pipe Driver: серверная основа для применения GPU в научных расчётах
т.е.
llvmpipe
(относительно быстрый программный рендеринг)nv30, nv50, nvc0, nve0 (GPU nVidia); r300, r600, radeonsi (GPU AMD)
-
-
применяет шейдерное представление TGSI (Tungsten Graphics Shader Infrastructure)
некоторые решения также применяют внутренним образом
LLVM
В целом, имеются четыре возможных стека драйвера для OpenGL:
|
|
Современные GPU хороши не только для графики
-
содержат от десятков до тысяч блоков быстрых вычислений с плавающей точкой
-
GPGPU (General Purpose GPU) или вычислительные приложения
Стандартный API для вычислений: OpenCL (Open Compute Language)
-
также патронируется Khronos Group
-
Linux поддерживает работы аналогичным образом для OpenGL:
-
драйверы с закрытым исходным кодом привносят свои собственные реализации
-
Gallium3D: блок отслеживания состояний Clover
-
Beignetдля GPU Intel
-
-
Другой популярный API вычислений: CUDA
проприетарный, применим только для nVidia, доступен только в драйверах с закрытым исходным кодом
Драйвер OpenGL работает в пространстве пользователя как часть определённого процесса пользователя
Доступ к графическому оборудованию руководится драйвером ядра
-
также осуществляет управление одновременным доступом от множества параллельных процессов
Проприетарные графические драйверы имеют свои собственные проприетарные API драйвера ядра
Для драйверов с открытым исходным кодом существует общая схема: DRI (Direct Rendering Infrastructure, Инфраструктура прямого построения изображений)
множество уровней:
-
аппаратно независимая библиотека пространства пользователя (
libdrm.so
) -
библиотека пространства пользователя, зависимая от оборудования (например,
libdrm_intel.so
) -
модуль ядра сам по себе: DRM (Direct Rendering Manager, Диспетчер прямого построения изображений)
DRM экспортирует узлы устройства: /dev/dri/cardX
-
однако: взаимодействие между
libdrm_XXX.so
и DRM частично является зависящим от драйвера
Имеются три основных поколения DRI:
-
DRI 1 (1998)
первая, ограниченная реализация
достаточно неэффективная в случае, когда более одного приложения желает применять имеющееся оборудование DRI
-
DRI 2 (2007)
решило большую часть основных проблем DRI 1
текущая, наиболее широко проработанная версия
-
DRI 3 (2014?)
множество улучшений деталей
в настоящее время разрабатывается
Если это не оговаривается особым образом, все последующие слайды относятся к DRI 2.
Клиенты DRM не эквивалентны- имеется некий Хозяин DRM (DRM Master)
обычно это X сервер
работает с правами root
управляет GPU по отдельности
-
всегда имеется только один Хозяин DRM для GPU
может выполнять авторизацию прочих процессов для применения GPU
Проблема: не может применять это GPU без некоего X сервера
-
это выступает раздражающим фактором для вычислительных приложений
Решение: Узел построения изображений (Render Nodes) в DRI 3
-
/dev/dri/renderDXX
-
ограниченная функциональность - никакого графического вывода
-
нет необходимости в авторизации со стороны Хозяина DRM
Основная задача DRI состоит в управлении видео памятью
-
Драйверы Intel применяют для этого GEM (Graphics Execution Manager)
-
Большинство прочих драйверов применяют имеющийся API GEM, однако под некоторой отличной реализацией: TTM (Translation Table Manager)
-
наиболее важная функциональность: передача и совместное использование графических буферов за границы процесса
-
это существенно для составных объектов ("рабочие места 3D" такие как Compiz)
-
-
при применении GEM: API flink
-
глобальная нумерация идентификаторами совместно используемых буферов
-
проблема безопасности: о значении идентификатора можно легко догадываться
-
-
новый, более безопасный API совместного использования, начиная с Linux 3.3 DMA-Buf:
-
буферы определяются файловыми дескрипторами
-
обмен файловыми дескрипторами может осуществляться неким безопасным образом через Сокеты межпроцессного взаимодействия (Unix Domain Sockets)
-
Классические установки графических режимов ("User Mode-Setting") имеют проблемы:
-
оборудование инициализируется множество раз
-
в первый раз собственно BIOS для его загрузочных сообщений ...
-
... затем определённым драйвером буфера кадра (framebufer) для основной консоли загрузки ...
-
... и, наконец, самими X сервером
-
-
мелькание в процессе загрузки
-
мелькание при сменой между виртуальными консолями и экземплярами X сервера
-
дублирование кода драйвера
-
драйвер буфера кадра и DDX в основном делают одни и те же вещи
-
-
проблемы с приостановкой и продолжением
-
драйвер буфера кадра VESA не может надёжно определять имеющееся разрешение дисплея
-
использует некоторые произвольные разрешающие способности по умолчанию
-
как результат: загрузочные сообщения выглядят расплывчатыми ☺
-
Решение: KMS (Kernel Mode Setting, Установки режима ядра)
|
|
xf86-video-modesetting: аппаратно независимый драйвер DDX для X.org на основе KMS и Glamor.
KMSCON: замена имеющегося уровня буфера кадра консоли ядра Linux на надлежащую, снабжённую всей функциональностью эмуляцию терминала в пространстве пользователя.
-
аппаратное ускорение, множество мониторов, полная поддержка Unicode, сглаживание, ...
Дальнейшая разработка KMS: ADF ("Atomic Display Framework", Инфраструктура атомарного дисплея)
-
полезна для оборудования со множеством перекрывающихся плоскостей
-
стандартные свойства во встроенных и мобильных устройствах
-
-
установки всех перекрытий могут изменяться синхронно ("атомарно")
-
предотвращает мерцание и разрывы
-
|
|
Составные операции представляют особый интерес при их объединении с OpenGL для "рабочих мест 3D", таких как Compiz.
-
однако: OpenGL "не знает" о пиксельных картах X11, а только о текстурах и кадровых буферах
-
1 проблема: наборщик должен осуществлять доступ к картам пикселей, как к текстурам OpenGL для отображения
-
Решение: расширение GLX_EXT_texture_from_pixmap
-
-
2 проблема: наборщику необходим доступ к кадровым буферам контекстов прочих процессов OpenGL
|
|
Ранняя попытка решения для проблемы наборщика OpenGL: Xgl
|
|
Другой начальный подход к проблеме наборщика OpenGL: AIGLX ("Косвенный GLX с ускорением")
|
|
Драйверы для DRI, X.Org (DDX), Mesa и Gallium3D обычно имеют различные названия
В ряде случаев возможны смешение и подгонка
Для неподдерживаемого оборудования
-
Применяется встроенное программное обеспечение (firmware) VESA BIOS или UEFI для установки режима
-
Программное построение OpenGL
-
Раньше: Программное построение
Mesa
- очень медленно -
Сейчас:
Gallium3D llvmpipe
- вырабатывает машинный код, что существенно быстрее
-
Встроенная графика Intel
-
Исключительная поддержка драйвера, целиком открытый код
-
устаревшее - без
Gallium3D
-
экспериментальный драйвер конвейера
ILO
-
официальными драйверами являются
классические Mesa
-
GPU ATI/ AMD (интегрированные и в отдельном слоте)
-
проприетарный драйвер с закрытым исходным кодом: fglrx
-
Общедоступная документация AMD на их оборудование влечёт за собой хорошую поддержку драйвера с открытым исходным кодом
-
Семейство драйверов radeon: Mesa для Radeon 7000 – 9250, Gallium3D начиная с Radeon 9500
-
Семейство драйверов radeonhd: Mesa для Radeon X1000 – HD4000, более не разрабатывается
GPU nVidia
-
проприетарный драйвер с закрытым исходным кодом: nvidia
-
Документация на их оборудование отсутствует, следовательно драйверы с открытым исходным кодом полагаются только на обратную инженерию
-
Драйвер nv: очень старый 2D драйвер с открытым исходным кодом для Riva 128 и более ранние GeForces
-
Семейство драйверов nouveau: Gallium3D начиная с GeForce FX
-
Семейство драйверов nouveau_vieux: Mesa, Riva TNT до GeForce 4
Драйвер | Переход на нижний уровень | Intel | AMD | nVidia | ||
---|---|---|---|---|---|---|
Framebuffer |
|
|
|
|
|
|
DRM/ Kernel |
|
|
|
|
|
|
X.Org DDX |
|
|
|
|
|
|
2D ускор. |
|
|
|
|
|
|
OpenGL |
|
|
|
|
|
|
Mesa |
|
|
|
|
|
|
Gallium3D |
|
|
|
|
|
|
OpenCL |
|
|
|
|
|
|
Ситуация с драйверами для GPU в смартфонах, планшетах и т.п. намного более сложная
-
Производители GPU-, SoC- и устройств предоставляют исключительно драйверы с закрытым исходным кодом
-
обычно отталкивающее качество, множество ошибок
-
иногда даже нет драйверов ядра доступных в виде исходного кода
-
порой запрещёно даже распространение исполняемых blob
-
-
Исключение: Broadcom VideoCore IV (т.е. Raspberry Pi)
-
документация и открытый исходный код драйвера опубликован в феврале 2014
-
Некоторые подходы для разработки драйверов с открытым исходным кодом методом обратного инжениринга:
-
Qualcomm Adreno – Freedreno
-
ARM Mali – Lima
-
Vivante – Etna_viv
-
nVidia Tegra – Grate
-
Imagination Technologies PowerVR – ???
До сих пор мы обсуждали только систему окон X, однако существуют и иные системы.
однако, базовые принципы всегда схожи.
пример: DirectFB
-
разработан для встроенных систем (приставки) в 1997
цель: графическая система с отпечатком меньших ресурсов чем X
-
основывается на устройствах кадрового буфера Linux
дополнительные аппаратные драйверы для ускорения
-
центральная библиотека:
libdirectfb
управляет выводом графики и звука, а также вводом
-
собственный диспетчер окон, порты общего набора инструментов, совместимость X (с применением специального сервера X), ...
|
|
До сих пор наиболее многообещающий кандидат для замены системы X Window: Wayland
|
|
Как приложения X могут работать в какой- то системе Wayland?
-
XWayland = видоизменённый сервер X.Org "без корня", который вращает все окна X верхнего уровня в клиентах Wayland
-
всё ещё нуждается в привязанных к оборудованию драйверах DDX, исключения:
xf86-video-wlshm
(аппаратно независимая, но без ускорения)xf86-video-wlglamor
(с 2D ускорением через Glamor)
Wayland может работать в графических драйверах Android с помощью libhybris:
-
libhybris "выступает посредником" между миром GNU libc и миром Bionic
-
приложения
libc
могут применять библиотеки Bionicв частности, они могут использовать
libGLESv2.so
, определённый драйвер OpenGL ES -
кроме того некие прочие особенности Android (например, gralloc, отличия EGL)
Конкурент для Wayland: Mir от Canonical
-
Графическая система для грядущих версий Ubuntu
ещё нет в 14.04, но может появиться в 14.10
-
в отношении концептульного построения очень близка к Wayland, однако полностью отлична и не совместима в реализации
-
применяет большую часть Android, например, подсистему ввода
-
в основном сосредоточен на обмене данных между приложениями
-
графические буферы выделяются в самом сервере, однако прорисовка выполняется на стороне клиента
-
XMir = XWayland для Mir
-
также реализует libhybris для поддержки графического драйвера Android
-
большое сопротивление в сообществе
имеются сомнения нужна ли другая система
Имеется множество подходов для аппаратного ускорения видео в X:
-
Xv (расширение X, 1991)
-
только для вывода видео, не выполняет декодирование
-
Функциональность: масштабирование, преобразование пространства цветов
-
два обычных вида реализации:
Overlay: непосредственно перекрывает само видео в текущем выводе отображения
Textured Video: прорисовывает получаемое видео в имеющемся кадровом буфере с применением оборудования 3D
-
-
XvMC (расширение X, 2000)
-
ускоряет две специфичные стороны декодирования MPEG-2 Компенсацию движения ("MC", Motion Compensation) и IDCT (преобразование блока 8x8)
-
устаревший
специфичный для MPEG-2, никогда не адаптировался для более новых стандартов
поддерживается только небольшим числом драйверов
-
GPU наших дней содержат аппаратные декодеры для распространённых стандартов (например, H.264).
|
|
Многие современные ноутбуки имеют два GPU:
-
интегрированная в процессор графика - медленная, однако экономящая мощность
-
дополнительный ("выделенный ") GPU nVidia или AMD - быстрый, но не эффективный
vga_switcheroo: отключает один из имеющихся GPU
-
переключение GPU требует перезапуска X сервера
-
работает только в системах с "Video Mux" (мультиплексированием видео), при котором оба GPU могут отображать на все дисплеи
-
проблема: наиболее новые модели обычно "muxless" - не поддерживают мультиплексирование
на текущий момент частные драйверы AMD и nVidia иеют свои собственные переключатели
-
базируются на XRandR 1.4 (
xrandr --setprovideroutputsource
) -
работают также и в системах "muxless"
-
однако: весь вывод выделенного GPU копируется через второй интегрированный GPU
это не приводит к экономии энергопотребления (наоборот - активны оба GPU)
Для гибридных систем на основе nVidia ("Optimus"), при наличии соответствующего драйвера, имеется некое "действительное" гибридное графическое решение - Bumblebee
-
изначально работают только интегрированные GPU
-
если некое приложение исполняется с применением какой- то особой обёртки (
optirun
):-
активируется выделенный GPU
-
запускается второй (невидимый) сервер X, исполняемый поверх данного драйвера nVidia
-
все команды прорисовки OpenGL перенаправляются в этот второй сервер X через primus
-
после кадого кадра получаемое окончательное изображение копируется обратно в этот интегрированный в GPU сервер X
-
решение с открытым исходным кодам: PRIME:
-
в настоящее время в стадии разработки
-
распространяет API DMA-Buf на совместное использование буфера cross-GPU
-
полностью динамчная "разгрузка" операций построения изображения (rendering)
-
активируется с помощью
xrandr --setprovideroffloadsink