Webレンダリングエンジン「Servo」をQtに組み込む
(掲載 2024年4月27日)
Qtで開発するネイティブアプリケーションに WebViewコンポーネントを組み込みたい場合、Chromium ベースのQt WebEngineモジュールを利用できます。
現在、標準に準拠した新たなブラウザ エンジンを作成するという作業は、ほぼ達成不可能と言われていますが、(Chromiumのコード行数は3,100万行もあることからもその難しさを想像できます)、Rustエコシステムでは、「Servo」と呼ばれる新しい Web レンダリングエンジンを開発しています。Servoは2012年にMozillaによって最初に作成され、現在はLinux Foundationの管理下で開発が続けられています。
ブラウザはインターネットにさらされているため、通常、システムに対する最大の攻撃対象となります。当然のことながら、Servo はメモリセーフな言語で記述されているため、代替のブラウザエンジンとして非常に魅力があります。
Servo WebView
KDABは、RustとC++のブリッジとして「CXX-Qt」ライブラリを開発し使用することで、Servo WebエンジンをQtに組み込むことに成功しました。これにより、QtアプリケーションのWebViewでChromiumの代替としてServoを使うことができるようになりました。
QMLの観点から見ると、このコンポーネントはChromium WebViewに似ており、canGoBack、canGoForward、loading、title、urlプロパティ、goBack、goForward メソッドを提供します。QML アイテム自体も同様に動作し、コンテンツはそのサイズに合わせてレンダリングされます。
import QtQuick
import QtQuick.Window
import com.kdab.servo
Window {
height: 720
width: 1280
title: webView.title
visible: true
ServoWebView {
id: webView
anchors.fill: parent
url: "https://servo.org/"
}
}
以下のスクリーンショットは、「戻る」、「進む」ボタンとアドレス バーを含むツールバーを備えた基本的な QML アプリケーションを示しています。 CXX-Qt を使用して、Rust で Qt プロパティ、メソッドやスロット、イベントハンドラー(タッチイベント他) などを定義し、Servoエンジンでイベントをトリガーします。その後、Servoからの更新リクエストは、Qtのイベント ループを介してQt 側の更新をトリガーできます。
KDABでは、CXX-Qtを安定させるためにQtからServoを使えるようにするなど、実際のユースケースを調査することで、潜在的に欠けている機能を特定し、RustとQtのエコシステムを繋ぐことで何が可能になるかを探ることができます。
技術的な詳細について
CXX-Qtバインディングは、RustとQt/C++の世界とのギャップを埋めてくれます。ただし、Servo のレンダリング コンテキストを接続して、Qt アプリケーションに描画できるようにするには、さらなる対応が必要です。 Servo は内部的に、Rust ライブラリであるSurfmanを使用してレンダリング サーフェスを管理します。この記事の元原稿執筆時点では、surfman は OpenGLと Metal をサポートしており、Vulkan のサポートも計画されています。
私たちは、surfman を使用して新しいOpenGLコンテキストを作成し、それをServo がレンダリングに使用します。結果を QtQuick シーンにレンダリングするには、Servo からサーフェスを借りて、新しいフレームバッファオブジェクトを作成し、Qt側でフレームバッファをQQuickFrameBufferObjectに転送します。
Servoの可能性
Servoの開発は、一定期間活動が鈍化していましたが、再び活発になっています。そのため、API は進化しており、組み込み向けのAPIを改善する作業が行われています。これにより、Servo をアプリに統合するためのプロセスがよりシンプルになり、ドキュメント化される可能性があります。また、 Tauriと Servo のコラボレーションの一環として、 WRYのバックエンドが利用できるようになる可能性もあります。そうした結果、Qt へのブリッジに多くの変更が生じるかもしれません。現時点では、このデモはServoコンポーネント (Servoshellと同様) を直接構築していますが、代わりに共有ライブラリまたは WRY を使用することもできます。
Qt側には、改善やさらに調査できる余地があります。たとえば、現在はOpenGLのバックエンドを強制的に使用するフレームバッファオブジェクトを使用していますが、RHI では、開発者が他のバックエンドを使用したいと思うかもしれません。 QMLでこれを解決する方法は、VulkanやOpenGLなどの実装を持ち、Servoエンジンから読み込むことができる、カスタムのQt Scene Graphノードを使用するように実装を変更することです。
また、Qt 6.7では新しいQQuickRhiItemが導入されました。これは現在テクニカルプレビューですが、QQuickFrameBufferObjectの代替となるレンダリング APIとして使用できます。
この技術デモのコードはGitHubのKDABLabs/cxx-qt-servo-webviewで公開されています。また、ServoやCXX-Qtについてご相談されたい場合は、SRAの営業担当もしくは問合せページまでご相談いただくか、KDABJapanのWebページよりお問合せください。
出典:Embedding the Servo Web Engine in Qt
KDAB日本語トップページ