このページでは

組み込みLinux向けQt

組み込みLinuxデバイス向けプラットフォームプラグイン

組み込みLinuxシステムでは、EGLFS、VkKhrDisplay、LinuxFB、Waylandなど、複数のプラットフォームプラグインを利用できます。これらのプラグインの利用可否は、Qtの設定方法によって異なります。 このうち、Waylandはコンポジターの存在を必要とし、X11やWindowsと同様に、複数のウィンドウをサポートする完全なウィンドウシステムを提供します。その他のプラグインはウィンドウシステムを必要とせず、Qtアプリケーションがレンダリングと出力を完全に制御します。これらは通常、画面ごとに1つのフルスクリーンQt「ウィンドウ」をサポートします。

EGLFSは多くのボードでデフォルトのプラグインとして設定されています。これが適さない場合は、環境変数QT_QPA_PLATFORM を設定して別のプラグインを指定してください。あるいは、簡単なテストを行う場合は、同じ構文でコマンドライン引数-platform を使用することもできます。

注: Qt 5.0以降 、Qt には独自のウィンドウシステム (QWS) 実装はなくなりました。シングルプロセスのユースケースでは、Qt Platform Abstractionが優れたソリューションとなります。マルチプロセスのユースケースはWayland を通じてサポートされています。

組み込みLinuxツールチェーンを使用したクロスコンパイル向けのQt設定の概要については、「組み込みLinuxデバイスの設定」を参照してください。

EGLFS

EGL は、OpenGL とネイティブのウィンドウシステム間のインターフェースです。 Qt はコンテキストやサーフェスの管理に EGL を使用できますが、その API にはプラットフォーム固有の機能は含まれていません。ネイティブウィンドウ(必ずしも画面上の実際のウィンドウであるとは限りません)の作成は、依然としてプラットフォーム固有の手段で行う必要があります。これが、ボードや GPU 固有の適応コードが必要となる理由です。通常、これらの適応コードは次のように提供されます:

  • EGLFSフック— プラットフォームプラグインにコンパイルされる単一のソースファイル
  • EGLデバイス統合— 動的に読み込まれるプラグイン

EGLFSは、X11やWaylandのような実際のウィンドウシステムを使用せずに、EGLおよびOpenGL ES 2.0上でQtアプリケーションを実行するためのプラットフォームプラグインです。これは、GPUを搭載した最新の組み込みLinuxデバイスに推奨されるプラグインです。

Qt Quick やネイティブのOpenGLアプリケーションに加え、EGLFSはQWidget のようなソフトウェアレンダリングによるウィンドウもサポートしています。QWidget の場合、ウィジェットの内容はCPUを使用して画像としてレンダリングされ、その画像はテクスチャにアップロードされた後、プラグインによって合成されます。

EGLFSは、最初のトップレベルウィンドウ(QWidget またはQQuickViewのいずれか)を強制的にフルスクリーンにします。このウィンドウは、他のすべてのトップレベルウィジェットが合成されるルートウィジェットウィンドウとしても選択されます。 たとえば、ダイアログ、ポップアップメニュー、コンボボックスなどです。EGLFS では、ネイティブウィンドウと EGL ウィンドウサーフェスが常にそれぞれ 1 つずつしか存在しないため、この動作は不可欠です。これらは、最初に作成されたウィジェットまたはウィンドウに属します。 このアプローチは、アプリケーションの存続期間を通じてメインウィンドウが存在し、他のすべてのウィジェットがトップレベルではないか、あるいはメインウィンドウが表示された後に作成される場合にうまく機能します。

OpenGL ベースのウィンドウには、さらに制限があります。EGLFS は、(Qt 5.3 の時点で)OpenGL ベースの `QWindow`、`QQuickView`、または `QOpenGLWidget` のような、単一のフルスクリーン GL ウィンドウをサポートしています。追加の OpenGL ウィンドウを開いたり、そのようなウィンドウを `QWidget` ベースのコンテンツと混在させたりすることはサポートされておらず、Qt はエラーメッセージを表示してアプリケーションを終了させます。

さらに、ドラッグ&ドロップなど、デスクトッププラットフォームやウィンドウシステムを備えた環境向けに設計されたAPIは、EGLFSではサポートされていません。

EGLFS で使用される環境変数

必要に応じて、eglfs は以下の環境変数を使用して設定できます:

環境変数説明
QT_QPA_EGLFS_INTEGRATIONコンパイル時に組み込まれたフックに加え、動的に読み込まれるプラグインを使用して、デバイスやベンダー固有の適応を行うことも可能です。この環境変数は、特定のプラグインを強制的に使用させます。例えば、これをeglfs_kmsに設定すると、KMS/DRM バックエンドが使用されます。 これは、デバイスの makespecs で静的またはコンパイル済みフックが指定されていない場合にのみ利用可能なオプションです。実際には、従来のコンパイル済みフックが使用されることはほとんどなく、現在ではほぼすべてのバックエンドがプラグインに移行されています。デバイスの makespecs には、オプションではありますが、依然として関連するEGLFS_DEVICE_INTEGRATION エントリが含まれています。これは、その特定のデバイスで推奨されるバックエンドの名前です。 ターゲットシステム上に複数のプラグインが存在する場合は、この環境変数の設定を避けてください。デスクトップ環境では、DISPLAY 環境変数の有無に応じて、KMSまたはX11バックエンドが優先されます。

注: 一部のボードでは 、実際のプラグインの代わりにnone の特別な値が使用されます。これは、フレームバッファでEGLを使用するために特別な統合が不要であることを示しており、プラグインをロードする必要はありません。

QT_QPA_EGLFS_PHYSICAL_WIDTH およびQT_QPA_EGLFS_PHYSICAL_HEIGHT物理的な画面の幅と高さをミリメートル単位で指定します。Qt 6 以降、論理 DPI の決定に物理的な画面サイズは使用されなくなったことに注意してください。
QT_QPA_EGLFS_ROTATIONQWidget ベースのアプリケーションにおいて、ソフトウェアレンダリングされたコンテンツに適用される回転を指定します。サポートされる値は 180、90、および -90 です。この変数は、Qt Quick を含む OpenGL ベースのウィンドウには適用されません。Qt Quick アプリケーションでは、代わりに QML シーン内で変換を適用できます。 標準のeglfs マウスカーソルは、アプリケーションの種類にかかわらず、常にこの値を考慮し、適切に配置・回転されたポインタ画像を表示します。ただし、KMS/DRMバックエンドのハードウェアカーソルなどの特殊なカーソル実装では、回転がサポートされていない場合があります。この設定は、タッチ入力を含め、その他の機能には一切影響しません。 タッチ入力バックエンドであるevdevtouch およびlibinput は、それぞれ独自の回転設定メカニズムを持っています。タッチ入力の設定に関する詳細については、「組み込みLinuxデバイスでの入力」を参照してください。
QT_QPA_EGLFS_FORCEVSYNCこの設定が有効になっている場合、eglfs は、eglSwapBuffers()が呼び出されるたびに、フレームバッファデバイスに対してFBIO_WAITFORVSYNC を要求します。この変数は、レガシーなLinuxのfbdev サブシステムに依存するバックエンドでのみ関連します。 通常、デフォルトのスワップ間隔が 1 の場合、Qt は eglSwapBuffers() の呼び出しによって vsync が処理されると想定します。もし処理されない場合(たとえば、ドライバのバグによる場合など)、QT_QPA_EGLFS_FORCEVSYNC を 0 以外の値に設定してみてください。
QT_QPA_EGLFS_FORCE888この変数が設定されている場合、eglfs が新しいコンテキスト、ウィンドウ、またはオフスクリーンサーフェスを作成する際、赤、緑、青の各カラーチャネルのサイズは無視されます。 その代わりに、プラグインはチャンネルあたり 8 ビットの構成を要求します。これは、バンディング効果などの理由から、ピクセルあたり 32 ビットまたは 24 ビット未満の構成(たとえば 5-6-5 や 4-4-4)が、理想的ではないとわかっていてもデフォルトで選択されるデバイスで役立ちます。 アプリケーションのコードを変更する代わりに、この変数を使用することで、24 または 32 bpp の設定を強制的に適用する近道となります。

さらに、以下のようにあまり一般的ではない変数も利用可能です:

環境変数説明
QT_QPA_EGLFS_FBフレームバッファデバイスを上書きします。デフォルトは `/dev/fb0` です。ほとんどの組み込みプラットフォームでは、フレームバッファはディスプレイの解像度などの設定を照会するためにのみ使用されるため、この変数はあまり重要ではありません。しかし、特定のデバイスでは、LinuxFBの `fb ` パラメータと同様に、この変数を使用することで、複数のディスプレイが設定されている環境でどのディスプレイを使用するかを指定することができます。
QT_QPA_EGLFS_WIDTH およびQT_QPA_EGLFS_HEIGHT画面の幅と高さをピクセル単位で指定します。eglfs はフレームバッファデバイス/dev/fb0 から解像度を判別しようとしますが、これが常に成功するとは限りません。サイズを手動で指定する必要がある場合があります。
QT_QPA_EGLFS_DEPTH画面の色深度を上書きします。フレームバッファデバイス/dev/fb0が利用できない、またはクエリが失敗したプラットフォームでは、デフォルト値として32 が使用されます。この変数を使用して、そのようなデフォルト値を上書きしてください。

注:この変数は 、QScreen によって報告される色深度の値にのみ影響します。EGLの設定や、OpenGLレンダリングに使用される色深度とは一切関係ありません。

QT_QPA_EGLFS_SWAPINTERVALデフォルトでは、1 のスワップ間隔が要求されます。この変数を使用すると、ディスプレイの垂直リフレッシュレートとの同期が可能になります。スワップ間隔の値を上書きするには、この変数を使用してください。たとえば、0 を指定するとスワップ時のブロックが無効になり、同期を行わずに可能な限り高速に実行されます。
QT_QPA_EGLFS_DEBUGこの変数を設定すると、デバッグ出力に一部のデバッグ情報が表示されます。たとえば、新しいコンテキストの作成時に、入力値QSurfaceFormat や、選択されたEGL設定のプロパティが表示されます。Qt Quick のQSG_INFO 変数と併用することで、EGL設定に関連する問題のトラブルシューティングに役立つ情報を得ることができます。

ロギング

QT_QPA_EGLFS_DEBUG に加え、eglfs は Qt の最新のカテゴリ別ロギングシステムもサポートしています。利用可能なロギングカテゴリは以下の通りです:

  • qt.qpa.egldeviceintegration – 動的に読み込まれたバックエンドのロギングを有効にします。どのバックエンドが使用されているかを確認するには、このカテゴリを使用してください。
  • qt.qpa.input –evdev およびlibinput の両方の入力ハンドラからのデバッグ出力を有効にします。このカテゴリを使用して、指定された入力デバイスが認識され、開かれたかどうかを確認します。
  • qt.qpa.eglfs.kms – KMS/DRM バックエンドでの詳細なロギングを有効にします。

configure を実行した後は、必ずその出力を確認してください。これは、必要な EGLFS バックエンド、libudev、または libinput が有効になっているかどうかを特定するための、最も簡単で迅速な方法です。要するに、configure の出力に望ましくない「no」が含まれている場合は、次のコマンドを実行してください:

./configure -v

を実行して詳細出力を有効にし、各 configure テストにおけるコンパイラおよびリンカーの呼び出しを確認できるようにします。

注: ヘッダーやライブラリの欠落に関するエラー、あるいは一見不可解なリンカーのエラーが発生した場合 、多くの場合、それらは sysroot が不完全または破損していることを示す兆候であり、Qt とは関係ありません。

例えば、Broadcomの独自グラフィックスドライバを搭載したRaspberry Piをターゲットとする場合、出力には次のような内容が含まれるはずです:

QPA backends:
EGLFS ................................ yes
EGLFS details:
  EGLFS i.Mx6 ........................ no
  EGLFS i.Mx6 Wayland ................ no
  EGLFS EGLDevice .................... no
  EGLFS GBM .......................... no
  EGLFS Mali ......................... no
  EGLFS Raspberry Pi ................. yes
  EGL on X11 ......................... no

もしそうではない場合、たとえQtの他の部分が正常にコンパイルされたとしても、Raspberry Pi専用のバックエンドがなければグラフィックスアクセラレーションは機能しないため、ビルドをこれ以上進めることはお勧めできません。

VkKhrDisplay

EGLFSはOpenGL (ES) のみをサポートしていますが、VkKhrDisplayはVulkanAPIによるレンダリングをサポートする実験的なプラットフォームプラグインです。ディスプレイの列挙やレンダリングの設定には、VK_KHR_display拡張機能ファミリーに依存しています。 なお、グラフィックススタック内のVulkan実装がこの機能をサポートしているとは限りません。現在、このプラットフォームプラグインは、Raspberry Pi 4上で動作するMesaおよびV3DVを用いて検証およびテストされています。

このプラットフォームプラグインは、OpenGLやソフトウェアレンダリングをサポートしていません。したがって、QWidget ベースのユーザーインターフェースを表示しようとすると失敗します。サポートされるQWindow サーフェスタイプは、QSurface::VulkanSurface のみです。Qt Quick アプリケーションの場合、これは、QQuickWindow またはQQuickView を作成する前の早い段階で、環境変数にQSG_RHI_BACKEND=vulkan を設定するか、QQuickWindow::setGraphicsApi(QSGRendererInterface::Vulkan)を呼び出すことで、Vulkanベースのレンダリングを強制する必要があることを意味します。

このプラットフォームプラグインを使用するには、-platform vkkhrdisplay でアプリケーションを実行するか、QT_QPA_PLATFORM をvkkhrdisplay に設定してください。このプラグインは、QtがVulkanサポート付きで構成されている場合にのみビルドされます。

EGLFS 形式の高度な設定(JSON 設定ファイルなど)や、同一アプリケーションからの複数画面への出力は、現時点では実装されていません。ただし、アプリケーションは環境変数を通じて使用する画面を選択することは可能です。

インデックス値を特定するには、プラグインによってデバッグ出力に出力されるログを確認してください。現在、これらのログは分類されていません(qDebug を通じて出力されます)。これは、プラグインが適切なディスプレイとモードを選択していることを確認するために、ほとんどの場合、これらのログを確認することが不可欠であるためです。

  • QT_VK_DISPLAY_INDEX - 設定すると、指定されたインデックスのディスプレイが使用されます。
  • QT_VK_MODE_INDEX - 設定されている場合、指定されたインデックスのディスプレイが使用されます。
  • QT_VK_PHYSICAL_DEVICE_INDEX - 設定されている場合、指定されたインデックスのVulkan物理デバイスが使用されます。組み込み環境では、ほとんどの場合、これは関係ありません。なお、この変数はQtグラフィックススタックの他の部分でも使用されていることに注意してください。

入力(キーボード、マウス、タッチ)の処理はEGLFSと同様で、evdev 、libinput 、およびtslib をサポートしています。ただし、マウスカーソルのレンダリングは実装されていません。 これは、この環境にはハードウェアカーソルの概念が存在しないこと、また、EGLFSがOpenGLで行うのと同様に、プラットフォームプラグイン内でVulkanを使用してカーソルをレンダリングすることは、いくつかの理由から問題があるためです。したがって、現時点では、このプラットフォームプラグインはマウスベースの入力にはあまり適していません。

関連する環境変数は以下の通りです:

  • QT_QPA_DISABLE_INPUT - キーボード/マウス/タッチ入力を無効にします。
  • QT_QPA_NO_LIBINPUT -libinput が利用可能な場合でも、evdev ベースの入力ハンドラを優先します。
  • QT_QPA_TSLIB - レガシーなtslibライブラリの使用を要求します。

LinuxFB

このプラグインは、Linuxのfbdevサブシステムを介してフレームバッファに直接書き込みを行います。ソフトウェアレンダリングされたコンテンツのみがサポートされています。 一部の環境では、表示パフォーマンスが制限される可能性がある点に注意してください。このプラットフォームプラグインでQt Quick アプリケーションを使用するには、software シーングラフバックエンドを使用する必要があります。これを行うには、環境変数QT_QUICK_BACKEND=software を設定するか、QSGRendererInterface::Software を指定してsetGraphicsApi()を呼び出します。QWidget アプリケーション、またはサーフェスタイプがQSurface::RasterSurface のQWindow はサポートされていますが、QOpenGLWidget などの特殊なウィジェットは含まれません。

Linux カーネルでは fbdev が非推奨となっているため、DRM ダムバッファのサポートも利用可能です。これを使用するには、環境変数 `QT_QPA_FB_DRM ` を 0 以外の値に設定してください。 この変数が設定されている場合、システムがダムバッファをサポートしていれば、/dev/fb0 のようなレガシーなフレームバッファデバイスにはアクセスされません。その代わりに、EGLFSのeglfs_kms バックエンドと同様に、DRM APIを介してレンダリングが設定されます。出力はダブルバッファリングされ、ページフリップが行われるため、ソフトウェアレンダリングされたコンテンツに対しても適切なvsyncが提供されます。

注: ダムバッファが使用されている場合 、物理および論理画面サイズなどのプロパティはすべて自動的に取得されるため、以下に説明するオプションはいずれも適用されません。

追加設定の指定

linuxfb プラグインでは、環境変数QT_QPA_PLATFORM またはコマンドラインオプション-platform を使用して、追加の設定を指定することができます。たとえば、QT_QPA_PLATFORM=linuxfb:fb=/dev/fb1 と指定すると、デフォルトのfb0 の代わりに、フレームバッファデバイス/dev/fb1 を使用するよう指定されます。複数の設定を指定する場合は、各設定をコロン(:)で区切ります。

設定説明
fb=/dev/fbNフレームバッファデバイスを指定します。マルチディスプレイ環境では、この設定により、異なるディスプレイ上でアプリケーションを実行することができます。現在、1つのQtアプリケーションから複数のフレームバッファを使用する方法はありません。
size=<width>x<height>画面サイズをピクセル単位で指定します。プラグインは、フレームバッファデバイスから物理的および論理的なディスプレイの寸法を問い合わせようとします。ただし、この問い合わせが常に正しい結果をもたらすとは限らないため、値を明示的に指定する必要がある場合があります。
mmsize=<width>x<height>物理的な幅と高さをミリメートル単位で指定します。
offset=<width>x<height>画面の左上隅からのオフセットをピクセル単位で指定します。デフォルトの位置は(0, 0) です。
nographicsmodeswitch仮想端末をグラフィックスモード(KD_GRAPHICS )に切り替えないように指定します。通常、グラフィックスモードを有効にすると、カーソルの点滅と画面のブランキングは無効になります。ただし、このパラメータが設定されている場合は、これら 2 つの機能もスキップされます。
tty=/dev/ttyN仮想コンソールを上書きします。nographicsmodeswitch が設定されていない場合にのみ使用されます。

Qt 5.9 以降、ウィンドウのサイズ変更ポリシーに関して、EGLFS と LinuxFB の動作が統一されました。どちらのプラットフォームプラグインでも、最初のトップレベルウィンドウは画面全体を覆うように強制されます。これを望まない場合は、環境変数 `QT_QPA_FB_FORCE_FULLSCREEN ` を `0 ` に設定することで、以前の Qt バージョンの動作に戻すことができます。

表示出力

単一の Qt アプリケーションから 1 つまたは複数のディスプレイをターゲットとするサポートの程度は、プラットフォームプラグインによって異なります。サポートの有無は、多くの場合、デバイスとそのグラフィックススタックに依存します。

eglfs_kms バックエンドを備えた EGLFS

KMS/DRMバックエンドが使用されている場合、EGLFSはQGuiApplication::screens() を通じて利用可能なすべての画面を報告します。アプリケーションは、QWindow::setScreen() を通じて、異なるウィンドウを異なる画面に割り当てることができます。

注: 1つのスクリーンにつきフルスクリーンウィンドウは1つという制限は 引き続き適用されます。また、QWindow を可視化した後のスクリーン変更もサポートされていません。したがって、組み込みアプリケーションでは、QWindow::show()を呼び出す前に、必要なQWindow::setScreen()の呼び出しをすべて完了しておくことが不可欠です。

特定の組み込みデバイスでの開発を開始する際、デバイスやドライバの動作、および接続されたディスプレイが正常に機能していることを確認する必要がある場合がよくあります。そのための簡単な方法の1つが、hellowindowサンプルを使用することです。-platform eglfs --multiscreen --timeout 引数を指定してこれを起動すると、接続された各画面に数秒間、回転するQtロゴが表示されます。

カスタム設定

KMS/DRMバックエンドは、JSONファイルによるカスタム設定もサポートしています。これを有効にするには、QT_QPA_EGLFS_KMS_CONFIG 環境変数をそのファイル名に設定してください。また、Qtリソースシステムを介して、このファイルをアプリケーションに組み込むこともできます。

これらの設定オプションのほとんどは、バッファ管理技術(GBM または EGLStreams)に関係なく、すべての KMS/DRM ベースのバックエンドに適用されます。

注:設定 ファイルは 、デバイスまたはプラットフォームの作成者によって完全に制御および管理される「信頼できるコンテンツ」とみなされます。いかなる形式でもエンドユーザーに公開されることは想定されていません。

以下に設定例を示します:

{
  "device": "/dev/dri/card1",
  "hwcursor": false,
  "pbuffers": true,
  "outputs": [
    {
      "name": "VGA1",
      "mode": "off"
    },
    {
      "name": "HDMI1",
      "mode": "1024x768"
    }
  ]
}

ここでは、指定されたデバイスを次のように設定します:

  • ハードウェアカーソルを使用しない(OpenGL 経由でマウスカーソルをレンダリングするようにフォールバックします。デフォルトでは、効率が高いためハードウェアカーソルが有効になっています)。
  • QOffscreenSurface を標準のEGL pbufferサーフェスでサポートする(デフォルトではこれは無効になっており、代わりにgbmサーフェスが使用される)。
  • VGAコネクタへの出力は無効にされ、HDMIは解像度1024x768で有効になります。

さらに、このような設定では、libudev によるデバイスの検索も無効になり、代わりに指定されたデバイスが使用されます。

mode が定義されていない場合、システムの優先モードが選択されます。mode で指定可能な値は、off 、current 、preferred 、skip 、widthxheight、widthxheight@vrefresh、またはモデルライン文字列です。

current を指定すると、現在の解像度と一致するモードが選択されます。モード設定は、希望するモードがアクティブなモードと実際に異なる場合にのみ行われるため(QT_QPA_EGLFS_ALWAYS_SET_MODE 環境変数によって強制されない限り)、この値は現在のモードや、Qtによって変更されていないプレーン内のコンテンツを保持するのに役立ちます。

skip これにより、出力用コネクタが切断されているかのように無視されます。off も同様ですが、こちらはモードを変更し、表示をオフにします。

デフォルトの動作

デフォルトでは、DRMレイヤーから報告されるすべての画面は、1つの大きな仮想デスクトップとして扱われます。マウスカーソルの実装はこの点を考慮しており、期待どおりに画面間を移動します。推奨はされませんが、設定でseparateScreens をfalse に設定することで、仮想デスクトップを無効にすることができます。

デフォルトでは、仮想デスクトップは、システムから報告されるコネクタの順序に基づいて、左から右へと形成されます。これを変更するには、virtualIndex を 0 から始まる値に設定してください。

たとえば、以下の設定では、優先解像度を使用しつつ、仮想デスクトップの左側をHDMIポートに接続されたディスプレイ、右側をDisplayPortに接続されたディスプレイとするよう指定しています:

{
  "device": "drm-nvdc",
  "outputs": [
    {
      "name": "HDMI1",
      "virtualIndex": 0
    },
    {
      "name": "DP1",
      "virtualIndex": 1
    }
  ]
}

配列内の要素の順序は関係ありません。仮想インデックスが指定されていない出力は、他の出力の後に配置され、DRMコネクタリストの元の順序が維持されます。

縦方向のデスクトップスペースを作成するには(つまり、左右ではなく上下に積み重ねる場合)、`device ` の後に `virtualDesktopLayout ` プロパティを追加し、その値を `vertical` に設定します。

警告: 仮想デスクトップ内のすべての画面で同じ解像度を使用することを推奨します 。そうしないと、特定の画面にのみ存在する領域に入った際、マウスカーソルなどの要素が予期しない動作をする可能性があります。

virtualIndex だけでは不十分な場合、virtualPos プロパティを使用して、対象の画面の左上位置を明示的に指定できます。前の例を基に、HDMI1の解像度を1080pと仮定すると、次のコードスニペットにより、2つ目のHDMIベースの画面を1つ目の画面の下に配置できます:

{
   ...
  "outputs": [
    ...
    {
      "name": "HDMI2",
      "virtualPos": "0, 1080"
    }
  ]
}

注: マウス操作が必要な場合は、このような構成は避けてください 。非線形レイアウトでは、マウスカーソルの動作が予期しないものになる可能性があります。タッチ操作については問題が生じないはずです。

物理画面サイズの自動検出

場合によっては、DRM による物理的な画面サイズの自動取得が失敗することがあります。通常、不足している値は環境変数 `QT_QPA_EGLFS_PHYSICAL_WIDTH ` および `QT_QPA_EGLFS_PHYSICAL_HEIGHT ` を使用して指定します。しかし、複数の画面が存在する場合、この方法はもはや適していません。代わりに、outputs リスト内の `physicalWidth ` および `physicalHeight ` プロパティを使用して、サイズをミリメートル単位で指定してください。

注: 物理的なサイズが異なり 、その結果、論理 DPI が異なる設定は推奨されません。これは、一部のグラフィックス・スタック・コンポーネントがマルチスクリーンを認識せず、最初の画面の値のみに依存しているため、予期しない問題が発生する可能性があるからです。

アクティブな出力と QScreen インスタンス

outputs 配列の各アクティブな出力は、QGuiApplication::screens()から報告されるQScreen インスタンスの1つに対応します。デフォルトでは、QGuiApplication::primaryScreen()が報告するプライマリ画面は、最初に登録された画面です。virtualIndex を使用していない場合、これはDRMコネクタの順序に基づいて決定されることを意味します。これを上書きするには、outputs リスト内の対象となるエントリに対して、primary プロパティをtrue に設定してください。

たとえば、システムがたまたまHDMI出力を先に報告した場合でも、VGA出力に対応する画面がプライマリになるようにするには、次のように設定します。

{
  "device": "/dev/dri/card0",
  "outputs": [
      { "name": "HDMI1" },
      { "name": "VGA1", "mode": "1280x720", "primary": true },
      { "name": "LVDS1", "mode": "off" }
  ]
}

トラブルシューティングの際、KMS/DRMバックエンドからのデバッグログを有効にすると役立つ場合があります。これを行うには、「qt.qpa.eglfs.kms 」カテゴリのロギングルールを有効にしてください。

注: 組み込み環境では 、仮想デスクトップの機能は完全なウィンドウシステムに比べて制限されます。複数の画面にまたがるウィンドウ、非全画面表示のウィンドウ、および画面間のウィンドウ移動は避けるべきであり、期待どおりに機能しない可能性があります。

一般的なユースケース

マルチスクリーン構成において最も一般的で、最もサポートが充実したユースケースは、画面ごとに専用のQQuickWindow またはQQuickView を開くことです。Qt Quick シーングラフのデフォルトのthreaded レンダリングループでは、これらの各ウィンドウに専用のレンダリングスレッドが割り当てられます。これは、スレッドをvsyncに基づいて個別にスロットリングでき、互いに干渉しないため、有益です。 一方、basic ループを使用すると、これが問題となり、アニメーションの品質が低下する原因となる可能性があります。

たとえば、接続されているすべての画面を検出し、それぞれに対してQQuickView を作成するには、次のように行います:

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);

    QVector<QQuickView *> views;
    for (QScreen *screen : app.screens()) {
        QQuickView *view = new QQuickView;
        view->setScreen(screen);
        view->setResizeMode(QQuickView::SizeRootObjectToView);
        view->setSource(QUrl("qrc:/main.qml"));
        QObject::connect(view->engine(), &QQmlEngine::quit, qGuiApp, &QCoreApplication::quit);
        views.append(view);
        view->showFullScreen();
    }

    int result = app.exec();

    qDeleteAll(views);
    return result;
}

eglfs_kmsの高度な機能

クローン(ミラーリング)

画面のクローン(ミラーリング)がサポートされています。これは `clones ` プロパティを介して有効化されます:

{
  "device": "/dev/dri/card0",
  "outputs": [
      { "name": "HDMI1", "mode": "1920x1080" },
      { "name": "DP1", "mode": "1920x1080", "clones": "HDMI1" }
 ]
}

この場合、DisplayPort経由で接続されたディスプレイ上のコンテンツは、HDMI経由のディスプレイ上のコンテンツと同じになります。これは、両方のディスプレイで同じバッファを出力することで実現されます。

ただし、この機能は、解像度が同じであり、受け入れられるバッファ形式に互換性の問題がなく、かつアプリケーションがクローン先として指定されたQScreen への出力を行っていない場合にのみ動作します。 実際には、後者の条件は、当該のQScreen (この例ではDP1)に関連付けられたQWindow が、決してQOpenGLContext::swapBuffers()操作を実行してはならないことを意味します。これらを確実に満たすかどうかは、設定およびアプリケーション次第です。

DRM レンダリングを使用したヘッドレスモード

DRMレンダリングノードを介したヘッドレスモードがサポートされています。これにより、DRMマスター権限を必要とせずに、GPU演算(OpenGLコンピュートシェーダー、OpenCL)やオフスクリーンOpenGLレンダリングを実行できます。このモードでは、すでに別のプロセスが画面に出力している場合でも、アプリケーションは動作可能です。

device を/dev/dri/card0 から/dev/dri/renderD128 に変更するだけでは不十分です。ヘッドレスモードでは実行できない操作がいくつかあるためです。したがって、これをheadless プロパティと組み合わせる必要があります。例:

{
    "device": "/dev/dri/renderD128",
    "headless": "1024x768"
}

ウィンドウのサイズは、依然として(現在は仮想となった)画面サイズに合わせて調整されるため、headless プロパティでサイズを指定する必要がある点に留意してください。また、vsyncに基づくスロットリング機能もありません。

有効化されると、ヘッドレスモードでオフスクリーンレンダリングを実行するために、アプリケーションには主に 2 つの選択肢があります:

QOpenGLWindow のサブクラスなどの通常のウィンドウを使用し、ウィンドウのデフォルトのフレームバッファ(実際にはgbm_surface )をターゲットとする方法:

MyOpenGLWindow w;
w.show(); // will not actually show up on screen
w.grabFramebuffer().save("output.png");

あるいは、追加のFBOを用いた一般的なオフスクリーン手法:

QOffscreenSurface s;
s.setFormat(ctx.format());
s.create();
ctx.makeCurrent(&s);
QOpenGLFramebufferObject fbo(1024, 768);
fbo.bind();
ctx.functions()->glClearColor(1, 0, 0, 1);
ctx.functions()->glClear(GL_COLOR_BUFFER_BIT);
fbo.toImage().save("output.png");
ctx.doneCurrent();

DRM APIの選択

KMS/DRM は、レガシー とアトミックの 2 種類の DRM API と組み合わせて使用できます。DRM アトミック API の主な利点は、同じレンダリングループ内で複数の DRM プレーン更新を許可できる点にあります。一方、レガシー API では、vsync ごとに 1 回のプレーン更新が必要となります。

アトミックAPIは、アプリケーションがコンテンツをオーバーレイにブレンドする際、すべての更新を同じvsync内に収める必要がある場合に役立ちます。ただし、すべてのデバイスがこのAPIをサポートしているわけではなく、一部の古いデバイスでは利用できない可能性があります。KMSバックエンドはデフォルトでレガシーAPIを使用しますが、環境変数QT_QPA_EGLFS_KMS_ATOMIC を1に設定することで、DRMアトミックAPIを有効にできます。

画面解像度よりも小さいフレームバッファを使用することも有用な場合があります。これは、JSONファイル内のsize パラメータを使用することで、DRMアトミックで実現可能です。以下の例では、3840x2160のビデオモードで1280x720のフレームバッファを使用しています:

{
  "device": "/dev/dri/card0",
  "outputs": [
    { "name": "HDMI1", "mode": "3840x2160", "size": "1280x720", "format": "argb8888" }
  ]
}

EGLFSのホットプラグおよびホットリロード

QT_QPA_EGLFS_KMS_CONFIG を通じて KMS 設定ファイルが指定されている場合、参照されたファイルはQFileSystemWatcher によって監視されます。このファイルに変更が加わると、ファイルが再読み込みされ、適切な更新が行われます。例:レイアウトの変更、モードの変更、画面のオン/オフなど。

同様の仕組みですが、厳密にオプトイン方式として、QT_QPA_EGLFS_HOTPLUG_ENABLED を設定することで、QDeviceDiscoveryがKMSデバイスを監視し、画面の接続・切断などの変更を検知できるようになります。

これらの機能は両方とも並行して使用することができ、また実際に並行して使用されることもよくあります。

ホットプラグやホットリロードによって引き起こされる動的な変更を適切に処理するには、表示されたり消えたりする画面に応じてウィンドウを作成・破棄することが重要です。

コード例:

#include <QGuiApplication>
#include <QQuickView>
#include <QQuickItem>
#include <QScreen>
#include <QQmlContext>

QHash<QString, QQuickView*> screenNameToViewMap;

int main(int argc, char* argv[])
{
    QGuiApplication app(argc,argv);
    app.setQuitOnLastWindowClosed(false);

    auto lRemove = [&](QScreen *screen) {
        if (screen->name().compare(QStringLiteral("qt_Headless")) == 0)
            return;

        if (!screenNameToViewMap.contains(screen->name()))
            return;

        QQuickView *view = screenNameToViewMap.take(screen->name());
        delete view;
    };

    auto lAdd = [&](QScreen *screen) {
        if (screen->handle() == nullptr)
            return;

        if (screen->name().compare(QStringLiteral("qt_Headless")) == 0)
            return;

        if (screenNameToViewMap.contains(screen->name()))
            return;

        QQuickView *view = new QQuickView;

        view->setSource(QUrl(QStringLiteral("qrc:/main.qml")));
        view->setScreen(screen);                    // This is not as important as the next line, but good practice
        view->setGeometry(screen->geometry());      // This is vital! Otherwise QWindow::show (/QWindowPrivate::create) will change the screen!
        view->show();

        screenNameToViewMap.insert(screen->name(), view);
    };

    QObject::connect(&app, &QGuiApplication::screenAdded, &app, lAdd, Qt::QueuedConnection);
    QObject::connect(&app, &QGuiApplication::screenRemoved, &app, lRemove);

    for (QScreen *screen : app.screens())
        lAdd(screen);

    return app.exec();
}

上記の例にある `QWindow::setGeometry` に関する行にご注目ください。これは、ウィンドウが意図した画面に正しく表示されるために不可欠です!

QMLにも同様のシグナルが存在するため、QMLでも同等のコードを記述できます。

特にQT_QPA_EGLFS_HOTPLUG_ENABLED については、コードを適切に調整することが不可欠です。なぜなら、一部の画面は電源が切れると接続が切断されたかのように振る舞うためです。この機能を有効にしないと、Qtもアプリケーションレベルのコードも、接続切断について通知を受け取ることができません。通常、すべてのバックエンドリソースはそのまま残ったままになるため、画面は何も起こらなかったかのように再表示されてしまいます。QT_QPA_EGLFS_HOTPLUG_ENABLED を有効にすると、画面上のQtリソース(例:QScreen 、QPlatformScreen、backing-storeなど)は破棄され、接続時(例:画面の再起動)に再作成されます。そのため、アプリケーションレベルのリソース(例:QWindow )も同様に再作成する必要があります。

「qt_Headless」と呼ばれるフォールバック画面は、画面なし構成への切り替えやそこから復帰する際の処理を容易にするために存在します。アプリケーションレベルのウィンドウについては、この画面は無視しても問題ありませんし、ほとんどの場合、無視すべきです。

eglfs_kms_egldevice バックエンドを使用した EGLFS

このバックエンドは、通常Tegraデバイスで使用され、前述のKMS/DRMバックエンドと似ていますが、GBMの代わりにEGLDeviceおよびEGLStream拡張機能に依存している点が異なります。

このアプローチに関する技術的な詳細については、こちらのプレゼンテーションを参照してください。

Qt 5.7 以降、このバックエンドは GBM ベースのバックエンドと内部実装の多くを共有しています。つまり、マルチスクリーンや `QT_QPA_EGLFS_KMS_CONFIG ` による高度な設定がサポートされています。ただし、hwcursor やpbuffers などの一部の設定は適用されません。

デフォルトでは、バックエンドは各出力のデフォルトプレーンに適したEGLレイヤーを自動的に選択します。必要に応じて、QT_QPA_EGLFS_LAYER_INDEX 環境変数を目的のレイヤーのインデックスに設定することで、この動作を上書きできます。この方法は現在、複数の出力をサポートしていないため、使用は単一の画面を持つシステムに限定すべきです。 利用可能なレイヤーを確認したり、起動時の問題をデバッグしたりするには、qt.qpa.eglfs.kms というログカテゴリを有効にしてください。

場合によっては、画面が希望の解像度がすでに設定されていると報告している場合でも、アプリケーションの起動時にビデオモードの設定を行う必要があることがあります。通常、これは最適化によって省略されますが、画面の電源が入らない場合は、環境変数 `QT_QPA_EGLFS_ALWAYS_SET_MODE ` を 0 以外の値に設定して、アプリケーションを再起動してみてください。

バックエンドで使用される EGLStream オブジェクトの動作を設定するには、QT_QPA_EGLFS_STREAM_FIFO_LENGTH 環境変数を使用します。これは、ターゲットシステムがKHR_stream_fifo をサポートしていることを前提としています。デフォルトでは、ストリームはメールボックスモードで動作します。FIFO モードに切り替えるには、1 以上の値を設定します。この値は、ストリームが保持できるフレームの最大数を指定します。

一部のシステムでは、事前定義されたコネクタを介して特定のオーバーレイプレーンを指定する必要が生じる場合があります。QT_QPA_EGLFS_LAYER_INDEX を使用してレイヤーインデックスを強制するだけではプレーンの設定が行われないため、それだけでは不適切です。代わりに、このような特殊なシナリオでは、QT_QPA_EGLFS_KMS_CONNECTOR_INDEX およびQT_QPA_EGLFS_KMS_PLANE_INDEX 環境変数を使用してください。これらを設定すると、指定されたコネクタとプレーネのみが使用され、その他の出力はすべて無視されます。 バックエンドが、目的のプレーンに対応するEGLレイヤーの選択と、プレーンの設定を自動的に行います。

KMS/DRM 上のマルチスクリーンシステムにおけるタッチ入力

マルチディスプレイシステムでは、タッチイベントを正しい仮想スクリーンにルーティングする必要があり、これにはタッチスクリーンとディスプレイ出力間の正確なマッピングが求められるため、タッチスクリーンについては追加の考慮事項が必要です。

このマッピングは、QT_QPA_EGLFS_KMS_CONFIG で指定され、前のセクションで説明したJSON設定ファイルを介して行われます。outputs 配列の要素にtouchDevice プロパティが存在する場合、その値はデバイスノードとして扱われ、タッチデバイスは該当するディスプレイ出力に関連付けられます。

たとえば、タッチスクリーンのデバイスノードが /dev/input/event5 であり、HDMI 経由でセカンダリスクリーンとして接続されたモニターに組み込まれたタッチスクリーンであると仮定すると、次の設定により、正しいタッチ(および合成マウス)イベントの変換が保証されます:

 {
    "device": "drm-nvdc",
    "outputs": [
      {
        "name": "HDMI1",
        "touchDevice": "/dev/input/event5",
        "virtualIndex": 1
      },
      {
        "name": "DP1",
        "virtualIndex": 0
      }
    ]
}

注: 不明な点がある場合は 、アプリケーションを起動する前に環境変数 `QT_LOGGING_RULES=qt.qpa.*=true ` を設定して、グラフィックスサブシステムと入力サブシステムの両方のロギングを有効にしてください。これにより、正しい入力デバイスノードを特定しやすくなるほか、そうでなければデバッグが困難な出力設定の問題を発見できる可能性があります。

注: Qt 5.14の時点で 、上記はevdevtouchおよびlibinputバックエンドでのみサポートされています。その他のバックエンドでは、引き続きイベントがプライマリ画面にルーティングされます。複数の入力バックエンドが利用可能なシステムでevdevtouchの使用を強制するには、環境変数QT_QPA_EGLFS_NO_LIBINPUT を1 に設定してください。

他のバックエンドでの EGLFS

他のバックエンドは、通常、ベンダーの EGL 実装を介してフレームバッファやコンポジション API を直接ターゲットとする方式を採用しており、マルチディスプレイに対するサポートは限定的であるか、あるいは全くサポートされていないのが一般的です。 Vivante GPUを搭載したi.MX6ベースのボードでは、linuxfbと同様に、QT_QPA_EGLFS_FB 環境変数を使用してターゲットとするフレームバッファを指定できます。Raspberry Piでは、QT_QPA_EGLFS_DISPMANX_ID 環境変数を使用して出力先の画面を指定できます。この値はDISPMANX_ID_ 定数のいずれかに対応しており、Dispmanxのドキュメントを参照してください。 なお、KMS/DRMとは異なり、これらの方法では通常、同じアプリケーションから複数の画面への出力はできません。あるいは、使用するフレームバッファを制御するために、ドライバ固有の環境変数やカーネルパラメータが利用可能な場合もあります。組み込みボードのドキュメントを参照してください。

ビデオメモリ

固定容量の専用ビデオメモリを搭載したシステムでは、Qt Quick やQOpenGLWidget などのクラスに基づく Qt アプリケーションを実行する前に、特別な注意が必要です。特に高解像度(例:フル HD)の画面で表示する場合、デフォルトの設定ではこれらのアプリケーションにとって不十分な場合があります。 この場合、予期せぬ不具合が発生する可能性があります。少なくとも 128 MB の GPU メモリが利用可能であることを確認することを推奨します。GPU 用に予約されたメモリ量が固定されていないシステムでは、この問題は発生しません。

linuxfb

fb プラグインパラメータを使用して、使用するフレームバッファデバイスを指定します。

Unix シグナルハンドラとコンソールの状態

eglfs や linuxfb などのコンソール指向のプラットフォームプラグインは、デフォルトで、割り込み (SIGINT)、一時停止および再開 (SIGTSTP 、SIGCONT)、および終了 (SIGTERM) を捕捉するためのシグナルハンドラをインストールします。 これにより、アプリケーションが終了したり、kill 、Ctrl+C 、またはCtrl+Z によってサスペンドされたりした場合でも、キーボード、ターミナルカーソル、および場合によってはその他のグラフィックス状態を復元できます(ただし、キーボードによる終了やサスペンドは、QT_QPA_ENABLE_TERMINAL_KEYBOARD が設定されている場合にのみ可能です。詳細は「組み込みLinuxデバイスにおける入力」を参照してください)。 ただし、場合によっては、SIGINT の捕捉が望ましくないこともあります。例えば、リモートデバッグと競合する可能性があるためです。そのため、すべての組み込みシグナル処理を無効にするために、環境変数QT_QPA_NO_SIGNAL_HANDLER が用意されています。

ハンドラはプラットフォームプラグインの初期化時にインストールされ、それ以前にアプリケーションが設定した処理をすべて上書きします。

警告: SIGINT およびSIGTERM では、 コンソールの状態が復元された後、プロセスは_exit() を介して終了します。atexit() ハンドラ、静的デストラクタ、Qtのシャットダウンコードは実行されず、バッファされたデータもフラッシュされません。したがって、systemctl stop または単純なkill を実行すると、アプリケーションは直ちに終了します。SIGTERM で状態を永続化する必要があるアプリケーションは、QT_QPA_NO_SIGNAL_HANDLER を設定し、独自のハンドラを実装して、コンソールの状態復元も引き継ぐ必要があります。

コンソールの状態は、これらのパスおよび通常のシャットダウン時のみ復元されます。SIGSEGV 、SIGABRT 、またはstd::terminate() によってプロセスが終了した場合は復元されません。仮想ターミナルをグラフィックスモードに切り替えるlinuxfbを使用している場合、異常終了したアプリケーションにより、デバイスが再起動されるまでローカルコンソールが空白のままになり、キーボード入力にも反応しなくなる可能性があります。 そのコンソールが唯一のローカル復旧手段であるデバイスでは、シリアルコンソールやデバイスを再起動するウォッチドッグなど、代替手段を用意してください。QT_QPA_PRESERVE_CONSOLE_STATE を使用して、ターミナルカーソルと画面消去の設定を変更しないようにし、linuxfbのnographicsmodeswitch を使用してグラフィックスモードへの切り替えをスキップしてください。

セキュリティ上の考慮事項

このページで説明するプラットフォームプラグインはウィンドウシステムなしで動作するため、通常はコンポジターやディスプレイサーバーが担う役割を引き受けます。このセクションでは、これらのプラグインが何を信頼し、デバイス作成者が何を制御すべきかについて説明します。Qt 共有セキュリティモデルも参照してください。

設定は信頼されるコンテンツである

組み込みプラットフォームプラグインの動作(どのデバイスノードが開かれるか、どのデバイス統合プラグインがプロセスに読み込まれるか、タッチ座標が画面にどのようにマッピングされるかなど)は、環境変数、KMS/DRM JSON 設定ファイル、およびオプションのキーマップファイルとカーソルアトラスファイルによって決定されます。 これらはすべて信頼されるコンテンツです。つまり、デバイスイメージのビルド時に固定され、その後はデバイスメーカーによって管理されることが想定されています。Qtはこれらが正しい形式であるかを確認しますが、それ以上の検証は行いません。また、これらはいかなる形式でもデバイスのエンドユーザーに公開されることを意図したものではありません。

特に注目すべきエントリが2つあります:

  • QT_QPA_EGLFS_INTEGRATION は、読み込まれる可能性のあるプラグインを制限するものではありません。要求されたバックエンドは、候補リストの先頭に移動されるだけであり、初期化に失敗した場合でも、残りのバックエンドは順に試行されます。 複数のデバイス統合プラグインが存在するシステムでは、デプロイメントで指定されなかったバックエンドが読み込まれ、ハードウェアの初期化を行ってしまう可能性があります。デバイスに必要なバックエンドのみを同梱してください。
  • タッチのキャリブレーションと回転は、QT_QPA_LIBINPUT_TOUCH_MATRIX 、evdev 、rotate 、invertx 、inverty パラメータ、あるいはJSON設定ファイル内のtouchDevice マッピングを通じて設定されるかに関わらず、押下がどこに報告されるかを決定します。 設定が誤っていると、ユーザーが触れたものとは異なる制御が作動してしまいますが、これはヒューマン・マシン・インターフェースにおいて安全上の特性となります。これらを、現場で調整可能な設定ではなく、デバイスの検証済み構成の一部として扱ってください。

入力デバイスはフィルタリングされません

Qtのデバイス検出機能は、検索対象の機能クラスに一致するすべての/dev/input/event* ノードを開き、libudev のサポートが利用可能な場合は、アプリケーションの実行中に後から出現するデバイスも同様に開きます。 許可リストも、ベンダーや製品のフィルタも、想定されるデバイスのセットという概念も存在しません。受け入れられたすべてのデバイスからのイベントは、あたかも意図したデバイスから送信されたかのようにアプリケーションに配信され、アプリケーションはそれらを区別することができません。

したがって、どのデバイスが存在するか、および誰がそれらを読み取ることができるかを制限することは、デバイス作成者の責務であり、アプリケーション内ではなく、カーネル、udev 、およびファイルシステムの権限レベルで行われます。/dev/input/* の読み取りが許可されていないQtアプリケーションは、入力を一切読み取りません。さらに:

  • QT_QPA_EVDEV_MOUSE_PARAMETERS 、QT_QPA_EVDEV_KEYBOARD_PARAMETERS 、およびQT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS でデバイスを明示的に指定すると、自動検出がバイパスされ、アプリケーションが使用するデバイスセットが固定されます。
  • grab=1 を指定すると、アプリケーションはそのデバイスへの排他的なアクセス権を取得します。これは、単一のアプリケーションのみを実行するデバイスでは検討する価値があります。
  • disable-zap について検討してください。「組み込み Linux デバイスでの入力」を参照してください。

ディスプレイは信頼できない入力です

ディスプレイがコネクタを介してアサートする EDID ブロックは、モニター、アダプタ、KVM スイッチ、キャプチャデバイスなど、接続されているデバイスによって提供され、ホットプラグイベントが発生するたびに再解析されます。 KMS/DRM バックエンドを持つ eglfs では、そこに含まれる値は、QScreen::manufacturer()、QScreen::model()、QScreen::serialNumber()、および報告された物理サイズを通じてアプリケーションに伝達されます。 これらは外部の影響を受けるものとして扱ってください。識別子として使用せず、ログに記録される可能性があることに注意してください。物理サイズは、QT_QPA_EGLFS_PHYSICAL_WIDTH およびQT_QPA_EGLFS_PHYSICAL_HEIGHT を使用するか、JSON 設定ファイルの各出力ごとに上書きすることができます。

実行時の依存関係

組み込みプラットフォーム用プラグインは、Qt ではなくボードサポートパッケージまたはディストリビューションによって提供されるライブラリ上の薄いアダプタであり、アプリケーションのプロセス内で実行されます。設定に応じて、これらは以下の通りです:

  • eglfs: EGL、およびバックエンドに応じて、GBM、Mesa、GPUドライバ、あるいはベンダー独自のEGL実装。KMS/DRMバックエンド用のlibdrm 。
  • vkkhrdisplay: Vulkanローダーおよびインストール済みのVulkanドライバー。
  • linuxfb: カーネルのfbdev インターフェース、またはQT_QPA_FB_DRM が設定されている場合はlibdrm 。
  • 入力:libinput 、libudev 、およびmtdev ;xkbcommon (システムからキーマップデータを追加で読み取る);またはtslib (独自の設定ファイルによって読み込まれるフィルタモジュールが決定されるため、Qtではそれらを選択または列挙できない)。

これらをデバイスのソフトウェア部品表(SBOM)に含め、常に最新の状態に保ち、デバイスが実際に使用するバックエンドのみを指定して Qt を設定してください。新しいデバイスについては、レガシーなtslib よりもlibinput を優先して使用してください。

フォント

Qtは通常、fontconfig を使用してシステムフォントへのアクセスを提供します。fontconfig が利用できない場合、QtはQBasicFontDatabase の使用に切り替わります。この場合、QtアプリケーションはQtのlib/fonts ディレクトリ内でフォントを検索します。Qtは、プリレンダリングされたフォントおよびTrueTypeフォントを自動的に検出します。このディレクトリは、QT_QPA_FONTDIR 環境変数を設定することで上書きできます。

サポートされている形式の詳細については、「Qt for Embedded Linux Fonts」を参照してください。

注:Qtは 、lib/fonts ディレクトリにフォントを同梱しなくなりました。つまり、必要なフォントの提供はプラットフォーム(システムイメージ)に委ねられます。

組み込みLinuxデバイス上のウィンドウシステム用プラットフォームプラグイン

XCB

これは、通常のデスクトップ Linux プラットフォームで使用される X11 プラグインです。X およびxcb に必要な開発ファイルが提供されている一部の組み込み環境では、このプラグインは通常の PC デスクトップと同様に機能します。

注: 一部のデバイスでは 、EGLの実装がXlibと互換性がないため、X環境下でEGLおよびOpenGLがサポートされていません。この場合、XCBプラグインはEGLサポートなしでビルドされるため、Qt Quick 2やその他のOpenGLベースのアプリケーションは、このプラットフォームプラグインでは動作しません。 ただし、ソフトウェアレンダリングによるアプリケーション(例えばQWidget に基づくものなど)を実行する目的であれば、引き続き使用可能です。

原則として、組み込みデバイスでの XCB の使用は推奨されません。eglfs のようなプラグインの方が、より優れたパフォーマンスとハードウェアアクセラレーションを提供できる可能性が高いです。

Wayland

Wayland は軽量なウィンドウシステムであり、より正確には、クライアントがディスプレイサーバーと通信するためのプロトコルです。

Qt Wayland は、Qt アプリケーションが Wayland コンポジターに接続できるようにする「wayland 」プラットフォームプラグインを提供しています。

詳細については、「Wayland と Qt」を参照してください。

パフォーマンス向上のためのガイドライン

可能な限りハードウェアレンダリングを使用する

アプリケーションのパフォーマンスが重要な場合は、ソフトウェアレンダリングに依存する Qt モジュールの使用を避けてください。可能であれば、代わりにハードウェアレンダリングに依存するモジュールを優先してください。

以下のベストプラクティスに従ってくださいQt Quick

QMLおよびQt Quick のベストプラクティスに従ってください。特に、QML CMake APIを組み込む点に留意し、qmllint、QMLスクリプトコンパイラ(qmlsc)、およびQML型コンパイラ(qmltc)が利用可能になるようにしてください。 また、宣言型のQMLを記述し、JavaScriptの使用を最小限に抑えることが推奨されます。JavaScriptの過度な使用がパフォーマンスに与える影響に関する詳細については、「QMLのパフォーマンスに関する考慮事項と提案」を参照してください。

Canvas QML タイプではなく、画像やテクスチャ、シェーダーエフェクトを使用してください

カスタム UI 要素を描画するには、画像やテクスチャ、およびシェーダー効果を使用してください。QML の `Canvas ` タイプは使用しないでください。シェーダーにはハードウェアアクセラレーション(GPU)が必要です。

Qt Quick の代わりにQt Widgets

Qt Quick を使用する場合、ハードウェアアクセラレーション対応のバックエンドとソフトウェアレンダリングのバックエンドのどちらでも使用可能です。複雑な UI については、組み込みターゲットでQt Widgets を使用することは推奨されません。これは、常にソフトウェアバックエンドが使用されるためです。

ここにはトレードオフがあります:

  • QMLエンジンとQt Quick を使用すると、初期のオーバーヘッドが発生します。
  • UIが非常に単純で再描画がめったに行われない場合は、QMLではなくウィジェットを使用して実装した方が高速に動作する可能性があります。
  • UIでアニメーション、smooth scrolling 、scaling 、rendering effects 、または3Dを活用する場合は、GPUアクセラレーションが必要となり、したがってQt Quick が必要になります。

UIのサイズに適した解像度を選択してください

高解像度については注意が必要です。720p以上の解像度では、パフォーマンスが低下する可能性があります。

アプリケーションのルート要素として QML の Window タイプを使用してください

アプリケーションのルート要素としてWindow を使用し、アプリケーションの背景にはcolor を指定してください。

その理由は、Windowコンポーネントには、バッファのクリアと同じ効果を持つcolorプロパティがあるためです。アプリケーションのルートItem としてフルスクリーンのRectangle を使用して背景を描画すると、余分な描画呼び出しが発生してしまいます。 一部の RHI バックエンドではこれが同じ処理となる場合もありますが、glClear 呼び出しとクワッドの描画には違いがあります。ほとんどの場合、単一の不透明な画像であればパフォーマンスへの影響はそれほど大きくないかもしれませんが、そのアイテムの色にアルファ値を使用すると、パフォーマンスに大きな影響が出る可能性があります。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.