Wayland は、ディスプレイサーバとクライアント間の通信方法を記述した通信プロトコルである。 また、そのプロトコルをCで実装したライブラリでもある。 Waylandプロトコルを使用したディスプレイサーバをWaylandコンポジタと呼ぶ。 これは、このディスプレイサーバがコンポジット型ウィンドウマネージャの機能も持つためである。

Waylandは当初、Kristian Høgsberg率いるボランティアによって、自由かつオープンソースコミュニティ主導のプロジェクトとして開発されていた。 このプロジェクトは、Linuxやその他のUnix系OSにおいて、X Window Systemをモダンで安全でよりシンプルなものに置き換えることを目的としている。プロジェクトのソースコードは、パーミッシブ・ライセンスのひとつであるMITライセンスで公開されている。

成果の一部として、WaylandプロジェクトはWestonと呼ばれるWaylandコンポジタのリファレンス実装も開発した。

概要

コンポジット型ウィンドウマネージャがアプリケーションやグラフィクスハードウェアと直接通信できる方法を、Waylandが提供する。具体的には、各アプリケーションは自身のバッファに画像を描画し、ウィンドウマネージャがディスプレイサーバとしてそれらバッファを合成して、ディスプレイ上に各アプリケーションウィンドウを作り出す。これは、コンポジット型ウィンドウマネージャとX Window Systemを一緒に使う従来の方法より効率的かつシンプルである。

Waylandはグラフィクス周りのみに特化しており、入力ハードウェアとの通信には他のライブラリを使用することを想定している。

Waylandディスプレイサーバプロジェクトは、Red Hatの開発者であったKristian Høgsbergによって、2008年に開始された。

2010年頃、Linuxデスクトップのグラフィックスは、「中心にあるXサーバとやり取りするためだけの山積みのレンダリングインタフェース」を持つ状態から、"XやWaylandのようなウィンドウシステムを脇に退けて"、Linuxカーネルやそのコンポーネント (たとえばダイレクト・レンダリング・インフラストラクチャ(DRI)、を"間に置く"ように移行した。その結果、"グラフィックシステムはシンプルになり、より柔軟性があり、より良いパフォーマンスを発揮する"ようになった。

Høgsbergは、多くの最近のプロジェクトと同様にを追加することもできたが、"クライアントとハードウェアの間のホットなパスからXを[締め出す]"ことを採用した。 その理由について、プロジェクトのFAQには以下のとおり記載されている。

Waylandの初期バージョンでは、を提供していなかった。 しかし、Høgsbergは、2010年にネットワーク透過性が可能であることを記した。 それは、2011年のGoogleサマーコードプロジェクトとして挑戦されたが成功しなかった。 Adam Jacksonは、(VNCのような)"ピクセルスクレイピング"や (RDP、 X11のように)ネットワーク越しに"レンダリングコマンドストリーム"を送る方法で、Waylandアプリケーションへのリモートアクセスを目論んだ。 2013年初頭、Høgsbergは、本物のコンポジタへ圧縮画像を送るプロキシWaylandサーバーを使ってネットワーク透過性の実験を行った。 2017年8月、GNOMEはWayland下で最初のピクセルスクレイピングVNCサーバの実装を提示した。

ソフトウェア アーキテクチャ プロトコル アーキテクチャ

Waylandプロトコルはクライアントサーバモデルである。クライアントはピクセルバッファを画面上へ表示するよう要求するグラフィカルアプリケーションであり、サーバ(コンポジタ)はこれらのバッファの表示を制御するサービスプロバイダである。

Waylandリファレンス実装は、2層のプロトコルとして設計された。すなわち、 下位レイヤあるいはワイヤプロトコル: 関係する2つのプロセス—クライアントとコンポジタ—の間のプロセス間通信と、それらが内部で変えるデータのマーシャリング (英語版) を扱う。 その上の高位レイヤ: クライアントとコンポジタがウィンドウシステムの基本機能を実現するために交換する情報を扱う。このレイヤは、"非同期オブジェクト指向プロトコル"として実装された。

下位レイヤはCで手作業で書かれたが、高位レイヤはXMLフォーマットで書かれたプロトコルの記述から自動生成された。 このXMLで書かれたプロトコルの記述が変更されたときは、いつでもプロトコルを実装したCのソースコードを再生成できる。これによって、非常にフレキシブルで、拡張性が高く、エラーを防止したプロトコルになる。

Waylandプロトコルのリファレンス実装は、2つのライブラリ、すなわち、Waylandクライアントによって使われるlibwayland-clientライブラリと、Waylandコンポジタによって使われるlibwayland-serverライブラリである。

プロトコルの概要 Waylandプロトコルは、"非同期オブジェクト指向プロトコル"として記述されている。オブジェクト指向とは、コンポジタによって提供されるサービスが、同じコンポジタ上に存在する一連のオブジェクトとしてもたらされることを意味する。 各オブジェクトはインタフェースを持つ。インタフェースは、名前と、いくつかのメソッド(リクエストと呼ばれる)、いくつかの関連したイベントを持つ。それぞれのリクエストとイベントは0以上の引数を持ち、それぞれに名前とデータ型がある。プロトコルが非同期とは、リクエストが、同期した返信やACKを待つ必要がないことを意味する。これによりラウンドトリップタイムを避け、パフォーマンスが改善する。

Waylandクライアントは、あるオブジェクトがサポートしているリクエストを、そのオブジェクトへリクエストできる(メソッドを呼び出せる)。クライアントは、必要とされるデータをリクエストの引数として提供しなければならない。これが、クライアントがコンポジタからサービスを要求する方法である。次に、コンポジタは、イベントを(おそらく引数付きで)発行するため、オブジェクトによって情報をクライアントへ返す。これらのイベントは、あるリクエストに対する反応や、あるいは非同期の (入力デバイスからのイベントといった)内部イベントや状態変化としてコンポジタによって発行される。エラー状態もコンポジタによってイベントとして通知される。

オブジェクトへリクエストを発行できるクライアントのために、最初に、オブジェクトを識別するために使うID番号をサーバに伝える必要がある。コンポジタには2種類のオブジェクトがある。グローバルオブジェクトと、非グローバルオブジェクトである。グローバルオジェクトは、生成時(そして廃棄時)にコンポジタによってクライアントへ通知される。一方、非グローバルオブジェクトは、通常、すでに機能の一部として存在している他のオブジェクトによって生成される。

インタフェースとその要求およびイベントは、Waylandプロトコルを定義する中心となる要素である。プロトコルの各バージョンは、どんなWaylandコンポジタにもあると期待されるインタフェースと、その要求およびイベントの集合を含んでいる。オプションとして、Waylandコンポジタは新しいリクエストとイベントをサポートする独自のインタフェースを定義して実装するかもしれない。それによって、コアプロトコル以上の機能へ拡張することができる。プロトコルの違いを管理するため、それぞれのインタフェースは名前に加えて"バージョン番号"属性を持っている。この属性により、同じインタフェースの派生版を区別できる。 各Waylandコンポジタは、どのインタフェースが使用可能かだけでなく、それらのインタフェースがサポートしているバージョンも公開する。

Waylandコアインタフェース

現在のバージョンのWaylandプロトコルのインタフェースは、Waylandソースコードにあるで定義されている。これはXMLファイルであり、現在のバージョンに存在するインタフェースが、リクエスト、イベント、その他の属性と共にリストアップされている。このインタフェース集合は、どのWaylandコンポジタも最低限必要とされるインタフェースである。

いくつかのWaylandプロトコルでの最も基本的なインタフェースは、以下のとおりである。 wl_display コアグローバルオブジェクト。Waylandプロトコル自身をカプセル化した特別なオブジェクトである。 wl_registry グローバルレジストリオブジェクト。すべてのクライアントが利用できるよう、コンポジタがすべてのグローバルオブジェクトを格納する。 wl_compositor コンポジタを表すオブジェクト。異なるサーフェイスを1つの出力へと結合することを担当する。 wl_surface 画面上の四角形の領域を表すオブジェクト。位置、サイズ、描画内容(ピクセル)によって定義される。 wl_buffer wl_surfaceに貼り付けたとき、表示する内容を提供するオブジェクト。 wl_output 画面の表示可能領域を表すオブジェクト。 wl_pointer, wl_keyboard, wl_touch ポインタやキーボードといった入力デバイスを表すオブジェクト。 wl_seat 1台のコンピュータを複数人で同時に使う構成(マルチシート構成)において、1つのシート(入出力デバイスの集合)を表すオブジェクト。

標準的なWaylandクライアントセッションは、wl_displayオブジェクトを使ってコンポジタに接続することで開始する。これは接続を表す特別なローカルオブジェクトであり、サーバー内には存在しない。このインタフェースを使うことで、クライアントはコンポジタからwl_registryグローバルオブジェクトを要求できる。wl_registryオブジェクトには、すべての名前があり存在しているグローバルオブジェクトが格納され、クライアントは望むオブジェクトを紐付ける。通常、クライアントは最低限1つのwl_compositorオブジェクトを紐付ける。アプリケーションの出力をディスプレイに表示するため、wl_compositorオブジェクトから、1つ以上のwl_surfaceオブジェクトを要求する。

Wayland拡張インタフェース Waylandコンポジタは、自身の追加インタフェースを定義して公開することができる。この特徴によって、コアインタフェースによって提供される基本機能を超えてプロトコルを拡張できる。そしてこれは、Waylandプロトコル拡張を実現する標準的な方法になった。コンポジタは、特化したあるいはユニークな特徴を提供するために、カスタムインタフェースを追加できる。WaylandリファレンスコンポジタであるWestonは、新しいコンセプトやアイデアのためのテストベンチとして、あたらしい実験的なインタフェースを実現するためにカスタムインタフェースを使用した。それらのコンセプトやアイデアは、その後にコアプロトコルの一部になった(たとえばwl_subsurfaceインタフェースは、Wayland 1.4で追加された)。

コアプロトコルの拡張プロトコル

XDG-Shellプロトコル

XDG-Shellプロトコル(XDGについてはfreedesktop.orgを見よ)は、Waylandコンポジタ(Westonに限らず)でサーフェイスを管理するための拡張手段である。サーフェイスを操作(最大化、最小化、フルスクリーンなど)するための伝統的な方法は、wl_shell_*()関数を使用することだった。この関数は、Waylandコアプロトコルの一部で、にある。対して、XDG-Shellプロトコルの実装は、Waylandコンポジタによって提供される。そのためヘッダがWestonソースツリーに含まれる。それぞれのWaylandコンポジタは自身の実装を提供することを想定している。

, XDG-Shellプロトコルはバージョン管理されておらず、まだ変更する可能性がある。

xdg_shellは、長期的にはwl_shellを置き換えることを目指したプロトコルである。しかし、現状ではxdg_shellは、Waylandコアプロトコルの一部ではない。xdg_shellは、開発版のAPIとして始まり、当初は開発用に使われた。これらの特徴がいくつかのデスクトップシェルによって要求されるとなれば、最終的には安定版へ移行できる。xdg_shellは、主に2つの新しいインタフェース:xdg_surfaceとxdg_popupを提供する。xdg_surfaceインタフェースは、動かせ、サイズ変更ができ、最大化等ができるデスクトップスタイルウィンドウを実現する。xdg_surfaceインタフェースは、親子関係を生成するためのリクエストを提供する。xdg_popupインタフェースは、デスクトップスタイルのポップアップとメニューを実現する。xdg_popupは、常に別のサーフェイスのための一時的なものであり、暗黙的なグラブを持つ。

IVI-Shellプロトコル IVI-Shellは、Waylandコアプロトコルの拡張で、車内エンターテインメント (IVI) デバイスをターゲットにしている。

レンダリングモデル

Waylandプロトコルは、レンダリングAPIを含んでいない。その代わり、Waylandはダイレクトレンダリングモデルを採用している。ダイレクトレンダリングモデルでは、クライアントはウィンドウコンテンツをコンポジタと共有できるバッファへ描画しなければならない。そのため、クライアントはCairoやOpenGLなどのライブラリを使って、自分自身ですべてをレンダリングすることも選択できる。あるいは、QtやGTKといった、Waylandをサポートする高位のウィジェットライブラリのレンダリングエンジンに頼ることもできる。クライアントは、特定のタスクをこなすために、オプションとしてその他の特化したライブラリを使用することもできる。たとえばフォントレンダリング(英語版)のためにFreeTypeを使用できる。

レンダリングされたウィンドウコンテンツの結果(バッファ)は、wl_bufferオブジェクトに格納される。このオブジェクトのデータ型は、実装依存である。コンテンツデータがクライアントとコンポジタとの間で共有可能でなければならないことだけが唯一要求される。もしクライアントがソフトウェア(CPU)レンダラを使用し、その結果がシステムメモリに格納されるなら、クライアントとコンポジタは、バッファ間のやり取りを余分なコピーなしに実現するため、共有メモリを使用できる。Waylandプロトコルはすでにこの種の共有メモリバッファに何も追加することなしに対応している。共有メモリバッファは、wl_shmおよびwl_shm_poolインタフェースによって実現できる。この方法の欠点は、コンポジタはそれを表示するために追加の作業(通常、共有データのGPUへのコピー)を必要とする可能性があることである。これにより、グラフィックパフォーマンスは低下する。

最も一般的なケースでは、クライアントがOpenGL、OpenGL ES、Vulkanといったハードウェア(GPU)アクセラレーションのためのAPIを使って、ビデオメモリバッファへ直接レンダリングする。クライアントとコンポジタは、このGPU空間のバッファを参照するための特別なハンドラを用いて共有できる。この方法は、コンポジタに余計なデータコピーをしないようにする。結果として、グラフィックパフォーマンスは向上し、よりよい方法である。コンポジタはAPIクライアントとして、同じハードウェアアクセラレーションAPIを使って、ディスプレイへ描画する最終的なシーンのコンポジションをかなり最適化できる。

レンダリングが共有バッファ内で完成したとき、Waylandクライアントはバッファのレンダリングされたコンテンツをディスプレイに表示するため、コンポジタを導くべきである。そのために、クライアントはレンダリングされたコンテンツを格納するバッファオブジェクトをサーフェイスオブジェクトに紐付ける。そして"commit"リクエストをサーフェイスに送り、バッファの制御をコンポジタヘ転送する。それから、クライアントは、もしまた別のフレームをレンダリングするためにバッファを再利用するなら、コンポジタがバッファを開放するのを待つ(イベントによって通知される)あるいは新しいフレームをレンダリングするため別のバッファを使用し、レンダリングが完了した時にこの新しいバッファをサーフェイスに紐付け、そのコンテンツをコミットすることもできる。数個の関連するバッファやその運用を含めて、レンダリングに使用される方法は、全体的にクライアントの制御下にある。

他のウィンドウシステムとの比較

WaylandとXとの違い WaylandとXとの間には、パフォーマンス、コードの保守性、セキュリティに関して、いくつかの違いがある。

アーキテクチャ Xのディスプレイサーバとコンポジット型ウィンドウマネージャは分離している一方、Waylandはディスプレイサーバとコンポジタを単一の機能として統合している。また、Waylandは、ウィンドウマネージャの仕事のいくつかを組み込んでいる。一方、Xは、クライアント側の仕事として分離されている。

コンポジット Xではコンポジットはオプションであるが、Waylandでは必須である。Xではコンポジタはピクセルデータを"能動的"に取り出さなければならないため遅延が生まれる。Waylandでは、コンポジタはピクセルデータを"受動的"にクライアントから直接受け取る。

レンダリング Xサーバは自身でレンダリングができ、さらにクライアントによって送られたレンダリングされたウィンドウを表示するために構築することもできる。対して、WaylandはレンダリングのためのAPIは表に出しておらず、そうした仕事を(フォント、ウィジェット、等のレンダリングを含めて)クライアントに委譲している。ウィンドウの装飾は、(たとえば、グラフィカルツールキットを使って)クライアント側でレンダリングできるし、(コンポジタによって)サーバサイドでもできる。

セキュリティ Waylandは、各ウィンドウの入出力から独立しており、入力・出力それぞれの機密性、整合性、および可用性を実現する。オリジナルのXの設計では、これらの重要なセキュリティの特徴が欠けており、いくつかの拡張が、それを軽減すべく開発されてきた。また、Waylandは、コードの大部分がクライアント側で実行されており、「root」権限で実行する必要のあるコードが少なくなり、セキュリティが向上する。一方、複数の一般的なLinuxディストリビューションでは、現在はXをroot権限なしに実行できる。

プロセス間通信 Xサーバは、Xクライアント同士の基本的な通信方法を提供する。後にICCCMによって拡張された。このXクライアント-クライアント通信は、ウィンドウマネージャによって使われる。また、Xセッション(英語版)、ウィンドウの選択とドラッグアンドドロップ(英語版)、その他の機能を実現する。Waylandコアプロトコルは、Waylandクライアント間の通信をサポートしない。対応する機能は(もし必要であれば)(KDEやGNOMEといった)デスクトップ環境や(たとえばOSのプロセス間通信といった)サードパーティによって実現される。

ネットワーク Xウィンドウシステムは、ネットワーク越しにコア部分が実行されるよう設計されたアーキテクチャである。Waylandは、それ自身ではネットワーク透過性を持たない。しかし、コンポジタは、リモートディスプレイを実現するためにどんなリモートデスクトッププロトコルも実現できる。加えて、Waylandイメージストリーミングとイメージ圧縮の研究がある。この研究は、Virtual Network ComputingVNCのようにリモートフレームバッファアクセスを実現し得る。

Xとの互換性 XWaylandは、Waylandクライアントとして動作するXサーバである。XWaylandによって、Waylandコンポジタ環境でネイティブのX11クライアントアプリケーションを表示させることができる。これは、XQuartzがXアプリケーションをmacOSのネイティブウィンドウシステムで動かす方法に似ている。XWaylandのゴールは、移植されていないアプリケーションを実行する方法を提供することで、XウィンドウシステムからWayland環境への移行を促進することである。XWaylandは、X.Orgサーババージョン1.16に取り込まれた。

Qt5やGTK3といったウィジェット・ツールキットは、ユーザーがアプリケーションをX上あるいはWayland上で実行させるかに関わらず、ユーザがローダを選択することで、グラフィカルバックエンドを実行時に変更できる。Qt5は、この効果のためにコマンドラインオプションを提供している。一方、GTK 3は、環境変数を設定することで、ユーザがGDK(英語版)バックエンドを使用するか選択可能にしている。

Waylandコンポジタ

Waylandディスプレイサーバプロトコルを実装したディスプレイサーバは、Waylandコンポジタとも呼ばれる。なぜなら、それらはコンポジット型ウィンドウマネージャの仕事もこなすからである。 Weston Waylandコンポジタのリファレンス実装である。Westonは、クライアントサイド・デコレーションを実現する。 Lipstick Waylandコンポジタを実装したモバイルグラフィカルシェルフレームワークである。これは、Sailfish OS(英語版), Nemo Mobile(英語版), AsteroidOSで使われる。 Enlightenment は、バージョン0.20から、完全にWaylandをサポートしている。しかし、完全なWaylandコンポジタになるための作業は続けられている。 KWin は、2021年現在、ほとんど完全にWaylandサポートを完了した。 Mutter は、(2013年9月に)GNOME 3.9にWaylandを統合するためのブランチを切った状態である。 Clayland(英語版) – Clutterを用いたWaylandコンポジタのシンプルな例である。 Westeros – Waylandコンポジタライブラリである。Westerosによって、アプリケーションが自身のWayland表示を作ることが可能になる。それによりサードパーティアプリケーションのネストと埋め込みを可能にする。 wlroots – モジュラWayland実装である。wlrootsは、他のコンポジタ、とくにSwayのためのベースとして機能する。 Sway – タイル型Waylandコンポジタである。また、X11のためのi3ウィンドウマネージャの置き換えである。 gamescope – SteamOSの一部である。初期のsteamcompmgrの置き換えである。

Weston Westonは、Waylandコンポジタのリファレンス実装であり Waylandプロジェクトによって開発されている。Cで書かれており、MITライセンスの下で公開されている。Westonは、Linuxカーネルの特定の機能に依存しているため、公式にはLinuxのみサポートしている。Westonが依存している機能は、カーネルモードセッティング(英語版)、Graphics Execution Manager (GEM) 、udevである。これらは、他のUnixライクOSには実装されていない。Linuxで実行するとき、evdev(英語版)によってハードウェアの入力を運用する。一方、バッファの運用は、ジェネリックバッファマネジメント (GBM) (英語版)に依存している。しかし、2013年にWestonのFreeBSD向けのプロトタイプportがアナウンスされた。

Westonは、HDCPをサポートしている。

Westonは、コンポジタとアプリケーション間のアプリケーションバッファを共有するためにGEMに依存している。ドックやパネルといった共通のデスクトップの機能のための"シェル"のプラグインシステムを含む。クライアントは、自身のウィンドウボーダや装飾の描画に対して責任を負う。Westonは、レンダリングのためOpenGL ESを使ったり、ソフトウェアレンダリング(英語版)のためにpixmanライブラリを使ったりすることができる。完全なOpenGL実装は使われない。なぜなら、現在のほとんどのシステムでは完全なOpenGLライブラリをインストールしている場合、GLXやその他のXウィンドウシステムサポートライブラリを依存関係のためにインストールしているからである。

Westonのためのリモートアクセスインタフェースは、2013年10月にRealVNC(英語版)の従業員によって提案された。

Maynard

Maynardは、グラフィカルシェルである。Maynardは、GNOME ShellがMutterへのプラグインとして書かれたことと同様に、Westonのプラグインとして書かれた。 ラズベリーパイ財団は、Collabora(英語版)とのコラボレーションの中でMaynardをリリースし、パフォーマンスとメモリ使用量の改善に取り組んでいる。

libinput

入力デバイス(キーボード、ポインタ、タッチスクリーン等)を扱うためのWestonコードは、libinputと呼ばれる独立したライブラリとして分けられている。Weston 1.5に初めてマージされた。

libinputは、Waylandコンポジタのための入力デバイスを扱う。また、汎用的なX.Orgサーバ入力ドライバを提供する。libinputの狙いは、入力イベントを扱う共通の方法でWaylandコンポジタ用の単一の実装を提供することである。これによりコンポジタ用にインプットコードをカスタムするための量を最小化する。libinputは、(udevを通じて)デバイスの検出、デバイスの運用、入力デバイスイベントの処理と抽象化を提供する。

libinputのバージョン1.0は、バージョン0.21の次にリリースされ、タブレット、ボタンセット、タッチパッドジェスチャのサポートを含んでいる。このバージョンは、安定したAPI/ABIを維持する(API/ABIが変わらない。)。

GNOME/GTKおよびKDEフレームワーク5が本流にしたことで、Fedora 22は、X.OrgのevdevとSynapticsドライバをlibinputに置き換えた。

バージョン1.16では、X.Orgサーバがと呼ばれるラッパによって、libinputライブラリをサポートした。

Waylandセキュリティモジュール Waylandセキュリティモジュールは、LinuxカーネルにおけるLinuxセキュリティモジュールインタフェースに似た位置づけである。

(とくにアクセシビリティに関連した)いくつかのアプリケーションは、高い権限(特権)を必要とする。これらの権限は、Waylandコンポジタに共通して持たれる。現在、Waylandにおけるアプリケーションは、一般的にスクリーンショットや入力イベントの発行といったセンシティブな処理は、いずれも実行できない。Waylandの開発者達は、特権を付与されたクライアントを安全に処理するための実行可能な方法を積極的に探しており、クライアント用の特権を持たせるインタフェースを設計している。

Wayland Security Moduleは、コンポジタ内でのセキュリティの決定を、一元化されたセキュリティ決定エンジンに移譲する方法である。

採用実績