WSLgアーキテクチャ

If you landed on this blog, you’ve probably seen our announcement for GUI applications support in the Windows Subsystem for Linux being available to Windows Insiders and looking for more details on how WSLg was built. If so, you’ve come to the right place!

情報源: WSLg Architecture | Windows Command Line

雑に翻訳。

このブログにたどり着いた方は、Windows Insidersに提供されるWindows Subsystem for LinuxのGUIアプリケーションのサポートについての発表をご覧になり、WSLgがどのように作られたかについての詳細をお探しだと思います。もしそうなら、あなたは正しい場所に来たのです。

理念と初期の目標

WSLでGUIアプリケーションのサポートを検討し始めたとき、すぐにX11とWaylandの両方のアプリケーションをサポートしたいと考えました。ユーザーがWSL内で実行したいと要望していたアプリケーションのほとんどはX11ベースのものでしたが、LinuxデスクトップコミュニティがWaylandに向かっていたので、それをサポートすることが重要だと考えました。Windows上のLinuxが過去に囚われ、X11アプリケーションに限定されたり、WSLgがWaylandへの移行の妨げになったりすることは避けたかったのです。

また、標準に忠実なLinuxアプリケーションのデスクトップ環境を構築することも重要でした。私たちは、アプリケーションが何の変更も必要とせず、そのままの状態で動作することを望んでいました。LinuxアプリケーションがWSLg内で動作するために、その動作を調整したり変更したりする必要はなく、WSLgがすべてのLinuxデスクトップ標準に徹底的に従うことで、物事がうまくいくようにしたかったのです。私たちはこれをオールラウンドなWin-Winだと考えました。フラグメンテーションを避け、アプリケーションの互換性を高め、ユーザーの満足度を高めることができます。もしそのような問題に遭遇したら、回避するのではなく、WSLgのGitHubプロジェクトに問題を提起して、私たちに知らせてください。

また、WSLgはオープンソースであり、WSL 2仮想マシンで実行されるLinuxとWindowsホスト間のすべての通信が、文書化された標準規格か、通信チャネルの両サイドで利用可能なオープンソースコードで定義されたものに従っていることを保証する必要がありました。シークレットソースは許されません。私たちは、コミュニティの開発者が望めばWSLgをいじれるようにしたかったのです。GitHubのWSLgプロジェクトには、アーキテクチャの概要と、WSLgのプライベートバージョンの構築と実行を開始する方法の詳細があります。

ユーザーエクスペリエンスの面では、統一された統合デスクトップを提供したいと考えました。LinuxとWindowsのアプリケーションが1つの統一されたデスクトップ上で隣り合って共存し、アプリケーションが予測可能な方法で動作するような体験です。世の中には、デスクトップ・オン・デスクトップのスタイルを提供するソリューションがたくさんあります。私たちは、WSLgがシームレスに感じられ、バックグラウンドに溶け込み、開発者が自分の仕事に集中して、LinuxやWindowsのアプリケーションを手間なく使用できるようにしたいと考えました。プレビュー版では、かなり良い体験を提供していますが、まだいくつかの気を散らす原因となる様々な制限があります。例えば、プレビュー版ではまだサーバーサイドでウィンドウの移動やサイズ変更を行っているため、ウィンドウの移動やサイズ変更の操作がネイティブのようにスムーズに行えません。また、Linuxのウィンドウをモニターの端にスナップさせたり、カスタムのスナップ領域にすることもできません。これらは私たちも困っています😊。私たちは、時間をかけてエクスペリエンスを向上させ、LinuxアプリケーションとWindowsアプリケーションの動作やパフォーマンスのギャップを減らしていきたいと考えています。一方で、これらのソリューションが私たちの基本原則に沿って設計されていることも確認しています。

ウェストンをベースに道を選ぶということ

私たちは、WaylandファーストのLinuxデスクトップとしてWSLgを構築し、xorgコミュニティが構築したXWaylandサーバーをホストすることで、X11アプリケーションをサポートすることにしました。

私たちにとっての大きな問題は、このWaylandコンポジターを作るために、どこから始めればいいのかということでした。新しいコンポジターを一から作るのか?Waylandプロトコルをホストにリモート接続して、Windows上で新しいコンポジターを実行するのか?それとも、既存のプロジェクトの上に構築して貢献するのか?

これは私たちにとって全く新しい分野であり、Linuxコミュニティの賢明な人々からの意見が必要だと考えました。私たちは、Windows上でLinuxのGUIアプリケーションを実現したいということを全世界に向けて発表する準備ができていなかったので、これまで一緒に仕事をしてきた信頼できる人たちに連絡を取りました。特に感謝したいのは、WSLのGitHubコミュニティで特に親切で活発なメンバーであるKenneth Clark氏です。Kennethは、//build2020で公開された、後にWSLgとなる最初の概念実証のためのプロトタイプの構築を手伝ってくれました。そして、Collabora社のDaniel Stone氏は、MesaプロジェクトのD3D12ガリウムドライバーで広範囲に協力してくれました。ダニエルの洞察力、視点、そしてWaylandとWestoneに関する豊富な知識は、私たちの選択を正しく理解し、WSLgがしっかりとした基盤の上でスタートするために不可欠なものでした。

では、なぜウェストンをベースにしようと思ったのか。

一言で言えば、コミュニティが既に構築したものの上に構築し、可能な限り準拠したコンポジターを確保することができる最良のアプローチだと考えました……公式のWaylandリファレンスコンポジターを実行する以外に、これを達成する方法はありません

WestonはWSLgの心臓部です。様々なWaylandプロトコルを定義・実装しているWestoneコンポジターのフロントエンドは、バグフィックスや、アプリケーションのリモーティングに関する新しいパラダイムに対応する以外は、事実上変更されていません。WSLgはWestoneから新しいまたはプライベートなWaylandプロトコルを追加することはなく、Waylandアプリケーション(X11アプリケーションの場合はXWayland)に関する限り、Westoneと相互作用しています。これを観察する1つの方法は、アプリの互換性です…我々は、drmバックエンドに対して実行されるネイティブのWestoneと、かなり同等に近い状態です。一般的に、アプリケーションがWestoneネイティブで正しく動作する場合、WSLgでも正しく動作しますし、その逆も同様です。

私たちは、それが素晴らしいポジションだと感じています。私たちがWSLgのアプリの互換性の問題を修正し、その修正をアップストリームすることで、Westone(とWayland)をより良くすることができます。コミュニティがWestoneに修正を加えると、私たちもその修正から直接利益を得ることができます。アプリケーションの互換性を高めるのは長い道のりになると思いますが、Waylandプロジェクトのリファレンスコンポジターの上に構築することで、Waylandコミュニティとの連携が取れていると感じています。

WestonにはすでにRDPバックエンドがあり、FreeRDPを使ってMicrosoft標準のリモート・デスクトップ・プロトコル(RDP)でホストと通信することができました。既存のWestoneのRDPバックエンドを拡張して、新しい技を教えることは、私たちにとって非常に興味深いことでした。Windows側では、RDPをリモートアプリケーションに活用した経験がたくさんあります。Windows Virtual Desktop(WVD)は、Azureで稼働する世界規模のサービスで、世界中のユーザーにWindowsアプリケーションをストリーミングしています。WVDはRDP RAIL(Remote Application Integrated Locally)技術を使用して、これらのリモートアプリケーションをユーザーのローカルデスクトップ体験に統合しています。また、Windowsクライアント技術としては、Edgeや今回のOffice向けのWindows Defender Application Guardなどがありますが、これらはRAIL(Virtualized Application Integrated Locally)と呼ばれるRDP技術の一種であり、ネットワーク上ではなくVM境界上での転送に最適化されています。

Westonを拡張してアプリケーションリモーティングを教え、RDPのバックエンドを拡張してRAILとVAILの両方を活用することで、ネットワークの透明性を念頭に置いて、業界ですでに広く使われていて大規模に運用されているプロトコルを使って、ゼロから構築された一般的なソリューションを手に入れることができ、これは非常に魅力的なことでした。

WSLgのアーキテクチャ

WSLgの心臓と魂はWestoneコンポジターです。これは、標準的なWestoneコンポジターに、大幅に拡張されたRDPバックエンド、新しいRAIL/VAILシェル、そしてあちこちでの様々なバグフィックスを加えたものです。現在、私たちはプロジェクトミラーからこれらのコンポーネントを構築していますが、その間、私たちの貢献をそれぞれのプロジェクトに戻すアップストリーム作業を行っています。最終的には、純粋にアップストリームのコンポーネントからWSLgを構築し、WaylandやWestoneをいじりたい人たちにとって、WSLgが素晴らしくてシンプルな生産環境になることを目標としています。

RDPのバックエンドを様々な方法で拡張しました。RAILおよびVAIL(別名:GrfxRedirection)プロトコルを使用したアプリケーションのリモーティングをサポートしました。RDPバックエンドでは、デスクトップ全体ではなく、個々のウィンドウをリモートすることが可能になりました。RAILとVAILの違いは、RAILはRDPトランスポート上にウィンドウのピクセルコンテンツをコピーし、ネットワーク上に接続されたRDPサーバー(WSLg)とRDPクライアント(ホスト上)に最適化されていることです。VAILはRAILと非常によく似ていますが、VM境界上のトランスポートに最適化されています。VAILはホストとゲストのVM間で共有メモリを使用し、RDPトランスポート上での高価なピクセルコピーを回避します。WSLgの構築の一環として、VAIL/GrfxRedirectionプロトコルを公開しています。

アプリケーションのリモーティングに加えて、RDPバックエンドが拡張され、モニターごとのDPIスケーリングのサポートを含むマルチモニター構成がサポートされるようになりました。DPIスケーリングでは、Waylandでネイティブにサポートされているスケールファクターに対してはWaylandのネイティブサポートを、サポートされていないスケールファクターに対してはRDPクライアントサイドスケーリングを組み合わせて使用しています。これにより、ユーザーがWindowsのUI設定で選択した環境設定に基づいて、Linuxアプリケーションが常に適切にスケーリングされるようになります。クリップボードのサポートが追加され、LinuxとWindowsアプリケーションの間でテキスト、HTML、ビットマップデータのカット&ペーストが可能になりました。ドラッグ&ドロップは現在サポートされていません。

オーディオの入力と出力の両方に対応しました。オーディオについては、PulseAudio サーバーを使用することにしました。PulseAudio と RDP バックエンドの間でオーディオデータをシャッフルし、RDP トランスポートを介してローカルまたはリモートの RDP クライアントにオーディオストリームを統合できるようにするための、Pulse 用の小さなシンクおよびソースプラグインを作成しました。

WSLGdは小さなデーモンのようなアプリケーションで、WSLg環境で最初に起動するプロセスであり、Westone、Pulseを起動し、ホストとのRDP接続を確立し、これらを監視し、クラッシュしたり動作が停止した場合は再起動します。

WindowsのスタートメニューにWSLgを統合するための小さなRDPプラグインを書きました。Westonの内部にあるプラグインの部分は、ユーザーのディストロにインストールされたアプリケーションを列挙し、デスクトップファイルを探します。Westonの内部にあるプラグインの部分は、ユーザーのディストロにインストールされているアプリケーションを列挙し、デスクトップファイルを探します。そのアプリケーションのリストを、起動するためのコマンドラインとそれを表すアイコンとともに、プラグインのホスト部分に送り、ユーザーのスタートメニューにこれらのアプリケーションを追加し、WindowsのスタートメニューからLinuxアプリケーションを直接起動できるようにします。いくつかの標準的なデスクトップファイルの場所が監視されます。ユーザーがLinuxディストロのアプリケーションをインストールしたりアンインストールしたりすると、その操作が数秒後にWindowsホストに反映されます。

最後に、FreeRDPを拡張して新しいプロトコルをサポートするとともに、mstscとの通信におけるいくつかの互換性の問題を修正しました。WestonはすでにRDPのサポートにFreeRDPを使用していましたが、別のソリューションに移行する必要はないと考え、代わりにFreeRDPにいくつかの機能強化を行うことにしました。

システムディストロ

上の写真で、システムディストロと呼ばれる新しいものに気づいたかもしれません。システムディストロは、コンテナ化されたLinux環境と考えることができ、その中でWestoneや友人たちを走らせ、様々なサーバーソケットをユーザーディストロに投影しています。ユーザーディストロはデフォルトで、X11、Wayland、オーディオのサポートのためにこれらのサーバーを参照するように設定されています。

WSLgをユーザー・ディストロから切り離すことができるため、WSLgにはこの方法を採用することにしました。WSLgはユーザー・ディストロとは独立してサービスを提供することができ、異なるLinuxディストリビューションでも一貫した体験を提供することができます。WSLgを導入するにあたり、新機能の追加、パフォーマンスの向上、操作性の改善、アプリケーションの互換性問題の修正を継続して行うため、今後数ヶ月の間に頻繁にアップデートを行う予定です。システム・ディストロに手を加えたいユーザーのために、プライベート・バージョンを実行するためのメカニズムを提供しています(WSLg contributeページを参照)。

システム・ディストロには、WSLgをホストするためにCBL-Marinerを使用することにしました。CBL-Marinerは、軽量でカスタマイズ可能なLinuxディストリビューションで、当社のLinuxシステムグループによって管理されています。これにより、マイクロソフトのさまざまな部分にまたがるLinux環境のメンテナンスを一元化し、セキュリティ脆弱性やその他の重要なパッチを確実に入手して最新の状態を保つことができます。これまでCBL-Marinerは、Azureやエッジ製品・サービスで動作するヘッドレス、コンテナ型のワークロードに焦点を当てていました。CBL-Marinerチームと協力して、WSLgを実現するための様々なUI関連パッケージをCBL-Marinerの公式RPMリポジトリに公開しました。

WSLg project on GitHub

WSLgのアーキテクチャについてさらに詳しく知りたい方、ソースコードを見て自分で作ってみたい方は、GitHubにあるWSLgプロジェクトの公式ページをご覧ください。

OpenGLのハードウェアアクセラレーション

以前、WSLにおける仮想GPUのサポートを発表しましたが、これにより、一般的な計算APIをネイティブに近いパフォーマンスでWSLで利用できるようになります。これは、マイクロソフトが独自に開発したTensorflow用のDirectMLバックエンドに加えて、幅広いハードウェアに対応したWSLでのAIトレーニングを可能にするものです。

vGPUに加えて、私たちはMesaコミュニティと協力してMesa用の新しいd3d12 galliumドライバーを開発してきましたが、先日、この作業がWindows上で可能になったことを発表しました。これにより、これまでサポートされていなかったARMベースのWindows PCでハードウェアアクセラレーションによるOpenGLおよびOpenCLのサポートが実現しました。

新しいd3d12 MesaドライバのLinuxサポートは、数週間前にMesaにアップストリームされ、公式Mesa 21.0リリースの一部となっています。これは長い道のりの集大成であり、WSLgでハードウェアアクセラレーションによるOpenGLアプリケーションを可能にします。

WSLgは、vGPUやアクセラレーションされたOpenGLの有無に依存していないことが重要です。WSLgは、OpenGLアクセラレーションがあってもなくても、単純な2Dアプリケーションには最適です。しかし、BlenderやGazeboなどのより複雑な3Dアプリケーションを実行しようとする場合、WSL vGPUサポートに標準装備されているWDDMv3.0をサポートするGPUを搭載したシステム上で実行した方が、はるかに優れた体験を得ることができ、Mesaを通じてこのOpenGLアクセラレーションを自動的に点灯させます。

下記のリンクを利用して、各パートナーのWDDMv3.0ドライバーのプレビューを見つけることができます。これらのドライバーは、Windowsの次のバージョンがリリースされたときに、Windows Updateや新しいシステムとともに出荷される予定です。

Mesaに関しては、現在ほとんどのディストリビューションが古い20.xバージョンのままです。私たちは、様々なWSL Linuxディストリビューションのパブリッシャーに連絡を取り、Mesa 21.xへのアップデートが予定されていること、そして新しいd3d12 galliumドライバをビルドして含めるようにMesaパッケージの定義を更新することを確認しました。

あなたがこの文章を読んだときには、古いバージョンのMesaを使っているかもしれないので、WSLgのアクセラレーションOpenGLがあなたのシステム上ですぐに点灯するかどうかはわかりません。もし、あなたのディストロがこれらの変更に対応するのを待ちたくなく、すぐにでもこの機能を試したいのであれば、Mesaの公式ホームにアクセスして、このサポートを備えたMesaのプライベートバージョンをビルドすることができます。あるいは、Canonical社が最近発表した「Ubuntu on Windows Community Preview for WSL 2」を試すこともできます。このUbuntuの新しいディストリビューションは、最先端のコンポーネントで構築されており、Mesa 21.0をサポートしているため、WSLgでシームレスなハードウェアアクセラレーションによるOpenGLがすぐに利用できます。このディストリビューションは、WSLの上級ユーザーが今後の機能のテストやデバッグを行うためのものであり、「毎日使う」ものではありませんが、これらの機能をいち早く体験するには最適なものです。

ネイティブ版とWSLg版のアプリケーションを比較したい方もいらっしゃると思いますので、パフォーマンスについてメモしておきます😊。WSLg v1では、Mesaはシステムメモリを介してWestoneと相互作用します。ディスクリートGPUの場合、レンダリングされたコンテンツは、コンポジターに表示される前にシステムメモリにコピーされ、Windows上で動作するRDPクライアントでGPUに戻される必要があります。このコストはフレームレートに比例して増加し、超高フレームレートで動作するアプリケーションは、より妥当なフレームレートで動作するアプリケーションよりも大きな影響を受けます。統合されたGPUの場合、データはシャッフルされるのでシステムメモリから離れる必要はありませんが、Mesaを介したプレゼントは現在のところ同期的で、つまりフレームごとに小さなバブルが発生し(レンダリングを待ち、レンダリングされたフレームをプッシュし、次のフレームを開始する)、パフォーマンスに影響を与えます。

ここでは、私の2台のPCから取った完全に非公式なパフォーマンスの断片を紹介します。1つ目は、非常に高いフレームレートを実行するディスクリートGPU(特に悪いケース)、2つ目は統合GPU(特に良いケース)です。これはGeeks3D GpuTestのピアノ版です。

Native Win32 (Mesa)WSLg (vGPU – Mesa)WSLg (Software – Mesa)
NVIDIA RTX 3090
(Yeah, super lucky to have friends in right places)
540fps350fps
4fps
Surface Book Gen3 (Intel – GPU)19fps18fps
1fps

システムメモリのインターロップを行う必要があるため、パフォーマンスの低下は避けられませんが、結果としてソフトウェアレンダリングよりもはるかに優れたパフォーマンスを実現しています。WSLgで動作するネイティブのWin32アプリケーションとLinuxアプリケーションのパフォーマンスの差を縮めることは、WSLg v2以降で改善していきたいと考えていますが、v1では、ネイティブでなくても良いパフォーマンスを提供しつつ、コアな体験にエネルギーを集中させたいと考えました。

フィードバック

私たちは、WSLgについて、うまくいった点、そうでない点などのご意見をお待ちしています。問題が発生した場合や提案をしたい場合は、WSLgの公式プロジェクトページで問題を提起してください。