Embedded

Аппаратное ускорение видео и графики на Raspberry Pi (EGLFS, VC4)

Введение

Для интерфейсов с анимациями (QML, основной цикл статей про QML-анимации) и видео производительность напрямую зависит от того, использует ли Qt аппаратное ускорение GPU Raspberry Pi, а не программный рендеринг на CPU. В статье разберём настройку графического стека для аппаратного ускорения — платформенный плагин EGLFS для безоконного рендеринга и GPU-драйвер VC4/V3D для современных моделей Raspberry Pi.

Концепция

EGLFS — платформенный плагин Qt, позволяющий Qt-приложению рисовать непосредственно во фреймбуфер устройства через EGL/OpenGL ES, без полноценного оконного менеджера X11/Wayland — это типичный выбор для embedded kiosk-приложений (статья 348), где не нужна многооконность десктопной среды. Драйверы VC4 (для более старых моделей) и V3D (для Pi 4/5) дают доступ к аппаратному GPU-ускорению OpenGL ES — без правильно настроенного драйвера Qt откатывается на программный рендеринг software-рендерером (например, llvmpipe), что заметно медленнее для любых сколько-нибудь сложных графических сцен.

Пример кода: Аппаратное ускорение видео

# Проверка, что аппаратный GPU-драйвер активен (а не software-рендеринг)
glxinfo | grep "OpenGL renderer"  # под X11: ожидается "V3D" или "VC4", а не "llvmpipe"

# Для безоконного режима — проверка через eglinfo
eglinfo
# Настройка переменных окружения для запуска Qt-приложения через EGLFS
export QT_QPA_PLATFORM=eglfs
export QT_QPA_EGLFS_INTEGRATION=eglfs_kms  # прямой доступ к GPU через KMS, без X11/Wayland

./MyKioskApp
// main.cpp — явная настройка платформенного плагина программно (альтернатива переменным окружения)
#include <QGuiApplication>
#include <QQuickView>

int main(int argc, char *argv[])
{
    // Если переменная окружения QT_QPA_PLATFORM не задана извне,
    // можно явно зафиксировать платформу прямо в коде приложения
    qputenv("QT_QPA_PLATFORM", "eglfs");

    QGuiApplication app(argc, argv);

    QQuickView view;
    view.setSource(QUrl("qrc:/main.qml"));
    view.showFullScreen(); // в EGLFS-режиме приложение всегда работает в полноэкранном режиме —
                            // концепции "окна" в привычном смысле здесь не существует

    return app.exec();
}
; /etc/X11/xorg.conf.d/99-v3d.conf — явная настройка GPU-драйвера, если используется X11
; (актуально, только если EGLFS/безоконный режим не выбран и используется обычная X11-сессия)
Section "Device"
    Identifier "VC4"
    Driver "vc4"
EndSection

Пояснения к коду

QT_QPA_PLATFORM=eglfs с QT_QPA_EGLFS_INTEGRATION=eglfs_kms направляет Qt рисовать напрямую через KMS (Kernel Mode Setting) интерфейс ядра Linux, минуя X11/Wayland полностью — это самый прямой путь к GPU без накладных расходов промежуточного оконного менеджера, типичный для kiosk-приложений (статья 348), где приложение единственное на экране и не нуждается в многооконности. view.showFullScreen() в QML-приложении отражает фундаментальную особенность EGLFS-режима — здесь нет привычной концепции отдельных, перемещаемых окон, и приложение всегда занимает весь экран целиком, что нужно явно учитывать при проектировании UI, изначально не рассчитанного на оконный режим.

Подводные камни

  • Запуск Qt-приложения без явной настройки QT_QPA_PLATFORM и без проверки, какая платформа выбрана автоматически по умолчанию — в зависимости от наличия X11/Wayland сессии и доступных переменных окружения, Qt может автоматически выбрать неоптимальную платформу для конкретного сценария использования; для kiosk-приложений, рассчитанных именно на EGLFS, эту переменную окружения стоит устанавливать явно, а не надеяться на автоматический выбор.
  • Попытка запустить два разных Qt-приложения одновременно через EGLFS-режим прямого доступа к KMS — в отличие от обычной многооконной среды, EGLFS/KMS обычно подразумевает единственное приложение, владеющее прямым доступом к GPU/дисплею в любой момент времени, и попытка запустить второе такое приложение параллельно с первым обычно завершается ошибкой захвата устройства, уже занятого первым приложением.
  • Игнорирование проверки реального аппаратного ускорения через glxinfo/eglinfo перед тем, как приступать к оптимизации производительности кода приложения — если рендеринг происходит на software-рендерере (llvmpipe) из-за неправильно настроенного драйвера, любые оптимизации самого кода QML/C++ дадут значительно меньший эффект, чем исправление корневой причины — отсутствия реального аппаратного ускорения; диагностику стоит начинать именно с проверки активного графического бэкенда.
  • Жёсткая привязка кода приложения к конкретной графической платформе (EGLFS) без возможности легко переключиться на обычный X11/Wayland режим для отладки на десктопе разработчика — для удобства разработки и отладки (например, в комбинации с подходами из основного цикла статей про автотесты UI) стоит проектировать приложение так, чтобы платформенный плагин можно было переключить через переменную окружения без изменения кода самого приложения, что и демонстрирует пример с qputenv(), допускающий переопределение снаружи до запуска приложения.