LinuxでのGUI
1. 概要
この記事では、Linuxベースのオペレーティングシステムで使用されるグラフィックスタックについて説明します。 グラフィカルアプリケーションを可能にするさまざまなテクノロジーと、それらが互いにどのように相互作用するかを見ていきます。 ゼロから始めて、高レベルのGUIツールキットに進みます。
最後に、これらのテクノロジーがどのように組み合わされて、本格的なグラフィカルエクスペリエンスを形成するかについて説明します。
2. Linuxの核心
「Linux」という名前は、単にLinuxカーネルを指します。 これは、箱から出してすぐにすべてを含む完全なオペレーティングシステムではなく、すべてがセットアップされるカーネルです。 カーネルは、実際のハードウェアとプロセスの間のインターフェースです。
ヘルパーツールやユーティリティと一緒にLinuxカーネルを構築してマシンにインストールすると、仮想端末のカーネルモード設定で非常に原始的なグラフィックを取得できますが、プログラムウィンドウ、視覚効果、視覚効果などの複雑なグラフィックは取得できません。派手なグラデーションの画像。 Linuxを複雑なグラフィックスで動作させるには、グラフィックスドライバー、グラフィックスAPIラッパー、ウィンドウシステム、コンポジターなどを含む完全なグラフィカルスタックが必要です。
そのため、Ubuntu、Debian、openSUSEなどのほとんどのLinuxベースのオペレーティングシステムでは、このグラフィカルスタックがすでにディストリビューションにパックされています。 したがって、すぐにグラフィカル環境にアクセスできます。 ただし、Arch、LFS、Gentoo、Alpineなどの他のオペレーティングシステムを使用する場合は、グラフィック環境にアクセスできるようにするために、グラフィックスタックを手動で構成する必要があります。
したがって、要約すると、Linuxには、GUIプログラムを開発するためのネイティブGUIまたは標準化されたライブラリが組み込まれていません。 それでも、グラフィカルシステムを使用できる無数のライブラリ、GUIツールキット、ドライバー、およびパッケージにアクセスできます。
3. グラフィックAPI
グラフィックAPIは、三角形の描画などの一般的な一連の命令を、GPUが実行できるより具体的なコードに変換する役割を果たします。 したがって、グラフィックAPIは、開発者のコードがGPUとどのようにインターフェースするかを記述したものです。
OpenGL 、 OpenGL ES 、 Metal 、 Direct3D 、Vulkanなどの一般的なグラフィックAPIがいくつかあります。 ただし、Linuxのグラフィックスタックのほとんどは、無料でクロスプラットフォームであるため、OpenGLを多用しています。
3.1. OpenGL API
OpenGLは、OpenGraphicsLibraryの略です。 これは、プラットフォームに関係なく、ハードウェアアクセラレーションによる2Dおよび3Dグラフィックスのレンダリングのみに関係する一連の仕様です。 APIの母国語はCです。 ただし、Java、Golang、Rustなどの他の言語のバインディングもあります。
正確には、 OpenGLは正確にはライブラリではありません。これは、各ベンダーがOpenGLライブラリを作成するための仕様を実装する必要があるためです。 したがって、Linuxベースのディストリビューションでは、libGL.soライブラリファイルはベンダーごとに異なります。 さらに、サードパーティとオープンソースの両方の実装を含む、OpenGL仕様の複数の実装があります。
3.2. メサ
Mesa は、OpenGLAPIとVulkanのオープンソース実装です。 カード固有のドライバーを使用して、APIをハードウェア固有の形式に変換します。 さらに、Mesaは3Dグラフィックスドライバーを構築するための Gallium3D アーキテクチャをサポートしているため、すべての主要なオペレーティングシステムへの移植が可能です。
X.OrgやWaylandなどの最新のディスプレイサーバーやウィンドウマネージャーは、内部でOpenGLを使用するため、すべてのグラフィックがMesaを通過します。
3.3. GLES
GLES は、OpenGLEmbeddedSystemの略です。 これは、AndroidフォンやiPhoneなどの組み込みデバイスを対象とするOpenGLプロファイルです。
3.4. GLXとWGL
上で見たように、 OpenGLは2Dおよび3Dグラフィックスの描画のみに関係し、ウィンドウ管理の概念はありません。 そのため、OpenGLシーンをウィンドウにバインドする方法が必要です。 GLX は、OpenGLシーンとXWindowSystem間のインターフェイスを提供するXWindowSystemの拡張機能です。
GLXと同様に、 WGL は、OpenGLおよびMicrosoftWindowsのネイティブウィンドウシステムのインターフェイスです。
3.5. EGLとGLUT
EGL は、プラットフォームに依存しないAPIであり、OpenGLとオペレーティングシステムのネイティブウィンドウシステムのインターフェイスを提供します。 GLXやWGLに依存していませんが、代わりにベンダーがその仕様を実装しています。
EGLとは異なり、 GLUT はGLXおよびWGLのラッパーであり、ポータブルグラフィックスアプリケーションを作成できます。
3.6. fglrxおよびCatalyst
CatalystはAMDのXorgOpenGLドライバーであり、fglrxという名前で呼ばれています。 これはX.Org専用のドライバーであり、OpenGL仕様の独自の実装があります。
4. DRMとDRI
OpenGLとウィンドウシステムはどちらも、画面上のオブジェクトの描画に関連する部分を実装しています。 したがって、それらはカード固有の命令のセットを生成し、LinuxカーネルはDirect Rendering Manager(DRM)を介して処理します。
Linuxには、 libdrm があり、オペレーティングシステムのDRMに簡単にアクセスできます。 DRMは、一連の汎用システムioctlを使用して、グラフィカルオブジェクトにメモリを割り当て、必要なコマンドとテクスチャを詰め込みます。 ioctlシステムは、デバイス固有の入出力操作を処理する特殊なタイプのシステムコールです。 この場合、ビデオカードの入出力操作を扱います。
したがって、グラフィカルアプリケーションを実行すると、OpenGLドライバー(Mesaなど)が読み込まれます。 次に、ドライバーは libdrm をロードします。これにより、ioctlを介してカーネルと直接通信できるようになります。
したがって、このプロセスは、グラフィカルアプリケーションが実行されている限り続行されます。 ただし、Xサーバーなどのウィンドウシステムに何が起こっているかを知らせて、同期して更新できるようにする方法が必要です。 この同期プロセスは、ダイレクトレンダリングインフラストラクチャ(DRI)として知られています。
4.1. KMS
グラフィカルアプリケーションは、実行中のXServerまたはコンポジターがある場合にうまく機能します。 では、仮想端末や読み込み中のスプラッシュ画面など、Xサーバーの外部で実行されるグラフィックスについてはどうでしょうか。 これがカーネルモード設定サブシステムの出番です。
KMS は、Linuxカーネルおよびlibdrmのサブシステムであり、ioctlsを介して実際のハードウェアを直接構成できます。 そのため、Xサーバーに依存する必要はありません。 ただし、 KMSは非常に低レベルのサブシステムであり、グラフィックサーバーまたはコンポジターを実行できない場合にのみ使用する必要があることに注意してください。
5. Xウィンドウシステム
X Window System は、ほとんどのLinuxベースのディストリビューションで使用されているオープンソースのウィンドウシステムです。 これはクライアントサーバーアーキテクチャに基づいており、リモート環境でも使用できるウィンドウと対話するためのネットワーク透過的な方法を提供します。
GUI環境の基本的なフレームワークを提供するだけでなく、イベント処理や視覚的な装飾も実行します。
5.1. X11
X Window Systemはクライアントサーバーアーキテクチャに基づいているため、クライアントとサーバーが同じマシン上にある必要はありません。 そのため、クライアントとサーバーの間でメッセージを伝送するプロトコルが必要です。 X11プロトコルは、メッセージ配信を担当します。 クライアントとサーバーが同じマシン上にある場合、メッセージはUNIXソケットを介して交換されます。
それとは別に、X11は拡張可能です。 したがって、新しいプロトコルを作成したり、既存のクライアントを壊したりすることなく、新しい機能を簡単に追加できます。 最も便利な拡張機能の1つは、アンチエイリアス描画のサポートを追加するXRenderです。
5.2. XlibとXCB
Xライブラリ、または Xlib は、クライアント側の実装です。 このライブラリは、 GTK+やQTなどのグラフィカルツールキットによって使用され、ソフトウェアアプリケーションのグラフィカルフロントエンドを作成します。
XCBまたはXC言語バインディングもXのクライアント側実装です。 ただし、はXlibよりもはるかに低いレベルであり、Xlibの一部は一部の機能にXCBを使用します。
5.3. X.Orgサーバー
X.Orgは、XWindowSystemのサーバー側の実装です。 これは、Unixライクなシステムで最も一般的に使用されるディスプレイサーバーです。 X.Orgサーバーは通常、ディスプレイマネージャーによって、または仮想端末から手動で起動されます。
6. カイロ
Cairo は、ベクターグラフィックのみを扱う描画ライブラリです。 それは実質的に同じAPIを実装します HTML5 。 さらに、Xlibバックエンドを介したX11サーフェスへの描画もサポートしています。
6.1. ピックスマン
XサーバーとCairoにはそれぞれ、ピクセルレベルの操作のための独自の実装があり、その結果、コードが肥大化しました。 この問題を解決するために、Pixmanが開発されました。 Pixmanは、XサーバーとCairoの共有ライブラリであり、ラスタライズアルゴリズム、グラデーションのサポートなどを提供します。
7. コンポジター
コンポジターは、画面上の各ウィンドウにオフスクリーンバッファーを提供するプログラムです。 このバッファーは、CompositeOverlayWindowまたはCOWとも呼ばれ、コンポジターによって操作されます。 したがって、コンポジターは、シャドウ、透明度、グラデーションなどの追加のスタイリングを適用できます。 それだけでなく、垂直同期とティアフリー体験を提供することもできます。
実行中の各ウィンドウの各フレームは、コンポジターを通過します。 コンポジターはXサーバーからウィンドウのピックスマップを取得し、OpenGLシーンにレンダリングします。
8. ウェイランド
Xはまだ機能的で安定していますが、かなりの問題があります。 まず、ネットワークの透過性のため、設計上安全ではありません。 したがって、ペイロードは有害なスニッフィングの影響を受けやすくなります。 第二に、これは拡張機能に大きく依存する非常に古いウィンドウシステムであり、その機能の一部はLinuxカーネルに移植されています。
Waylandは、Xの新しい代替品です。 Waylandはクライアントサーバーアーキテクチャに依存していません。 したがって、サーバーに依存する代わりに、 evdev を介してイベントを処理し、説明したのと同じスタックを使用してウィンドウを表示するグラフィカルアプリケーションのウィンドウマネージャーまたはコンポジターとして機能します。 WaylandのプロトコルもUNIXソケットに基づいています。
Waylandクライアントは、コンポジターにバッファーを要求し、OpenGL、Cairo、またはその他のレンダリングモジュールを使用してバッファーに取り込みます。 コンポジターは、クライアントに渡す前に、視覚効果のためにバッファーを簡単に操作できます。 つまり、ある意味ではサーバーであり、コンポジターはです。
8.1. XWayland
XWayland は、Waylandの下で実行されるXサーバーを提供します。 したがって、Waylandへの移行中のXアプリケーションの互換性パッケージです。 ただし、メッセージはWaylandコンポジターを通過するため、XクライアントとXサーバーの間に追加のレイヤーが追加されます。
9. GUIツールキット
GUIツールキットまたはGUIライブラリには、ウィジェット、シーン、イベントハンドラーなどのグラフィカルインターフェイスと要素を作成するために必要な機能が含まれています。 一部のGUIツールキットは、ウィジェット、グラフィカルデザイナー、および開発環境を提供するフル機能のフレームワークです。
GUIツールキットライブラリは通常、XlibやXCBなどの低レベルライブラリのラッパーです。 したがって、追加のスタイルと動作を備えたグラフィカルアプリケーションを開発するためのより簡単な方法を提供します。
さらに、ほとんどの成熟したGUIツールキットは独創的なデザインを持っています。 つまり、独自のマークアップ言語、イベントシステム、およびステートマシンを実装します。 ステートマシンは、本質的に反応的な複雑なプログラムの管理を担当します。
さまざまなGUIツールキットがあり、それぞれが独自の目的を果たします。 今日使用されている最も人気のあるものは、GTK +、Qt、 wxWidgets 、 FLTK 、およびimguiです。 それらのいくつかを詳しく見てみましょう。
9.1. GTK +
GTK+またはGIMPToolkitは、XWindowSystemとWaylandを使用するUnixライクなオペレーティングシステムに最適なツールキットです。 クロスプラットフォームで最新のGUIアプリケーションを構築するための安定したGUIツールキットです。 GIMP 、 Mozilla Firefox 、 GNOME デスクトップ環境、 Inkscape 、
GTKツールキットには、Windows用のGDIやmacOS用のQuartzなど、他のバックエンド用のサブシステムもあります。つまり、他のプラットフォーム用のプログラムも開発できます。 さらに、GTKプログラムの開発を容易にする追加のプログラムを提供する独立したプロジェクトがあります。 そのようなプロジェクトの1つがGladeです。 Gladeは、プログラムのフロントエンドを簡単に設計するためのグラフィカルインターフェイスを提供します。 Firefoxのようないくつかのプロジェクトには、GTKの独自のカスタマイズされたフォークがあります。
もともとはC言語で書かれていますが、C++の場合はGTKmm 、Pythonの場合は PyGObject 、Golangの場合はgotk3などの他の言語のバインディングもあります。
9.2. Qt
Qtは、ウィジェットライブラリと追加機能の完全なセットを提供するクロスプラットフォームのアプリケーション開発フレームワークです。 GTKとは異なり、QtにはQtDesignerと呼ばれる独自のデザイナーとQtCreatorと呼ばれる統合開発環境があります。
さらに、ネットワーク、Webソケット、マルチメディア、SQL、XML、およびWebエンジンの独自の実装を定義します。 ソースコードをほとんどまたはまったく変更せずに、Qtプログラムを他のプラットフォームに簡単に移植できます。 したがって、組み込みシステムとデスクトップシステムの両方を対象とするソフトウェアに最適なツールキットです。
QtフレームワークはC++言語で完全に実装されています。 ただし、他の言語にもバインドがあります。 独自のマークアップ言語QMLを定義します。これは、構文的にはCSSに似ています。 そのため、ウィジェットを好みに合わせてカスタマイズするための大きな力が得られます。
Qtで記述された人気のあるアプリケーションには、 Autodesk Maya 、 Autodesk 3ds Max 、 Crytek CryEngine 、 DaVinci Resolve 、Kなどがあります。デスクトップ環境(KDE)。
10. OpenGLの役割
これまで見てきたように、LinuxでGUIアプリケーションを開発するための特効薬である公式のネイティブツールキットやGUIライブラリはありません。 グラフィックスタックの各モジュールが独自の目的を果たしていることがわかりました。
ほとんどの場合、グラフィックスタックでは、すべてのグラフィック命令がOpenGLを通過することがわかりました。 したがって、OpenGLのみに基づいてスタンドアロンアプリケーションを開発できると言っても過言ではありません。 したがって、 OpenGLは、Linuxでグラフィカルアプリケーションを開発するための一種のネイティブツールであると見なすことができます。
例として、クロスプラットフォームの3DモデリングおよびアニメーションツールであるBlenderを見てみましょう。 Blenderは他のGUIツールキットや低レベルのクライアントライブラリに依存していませんが、OpenGLに完全に基づいた独自のウィジェットライブラリを持っています。
11. 結論
この記事では、Unixライクなオペレーティングシステムで使用されるグラフィックスタックについて説明しました。 低レベルのコンポーネントから始めて、スタック全体を使用してグラフィックをレンダリングする高レベルのGUIツールキットに進みました。
最後に、グラフィカルアプリケーションのレンダリングを担当するネイティブツールとしてのOpenGLの役割について簡単に説明しました。