- GTK のレンダリング基盤が、GL 向けの ngl と Vulkan 向けの vulkan に再編され、2つのレンダラーは同じソースからビルドされる統合構造になった
- 共通実装は Vulkan API の流れを基準に、GL 3.3+ と GLES 3.0+ の違いを抽象化し、シーングラフの走査やキャッシュなどの レンダリングインフラを共有して使う
- 新レンダラーは当面、速度よりも 正確性と保守性を優先し、アンチエイリアシング、分数スケーリング、無制限のグラデーション色停止点、dmabuf 対応を改善する
- アプリ開発者は glshader ノード非対応、分数位置の扱いの変化、ドライバー問題の可能性を確認する必要があり、ドライバー問題に見えても GTK 側に報告するのがよい
- GTK 4.13.6 スナップショットでは ngl が新しいデフォルトだが、まだ試験導入段階であり、大きな問題があれば GTK 4.14 で従来の gl レンダラーに戻す可能性がある
GL と Vulkan のための統合レンダラー
- GTK は GL 向けの新しいレンダラー ngl と、Vulkan 向けの新しいレンダラー vulkan を追加した
- 2つのレンダラーは同じ ソース からビルドされるため、統合レンダラーと呼ばれる
- 実装モデルは Vulkan API に従い、GL 3.3+ と GLES 3.0+ の違いを扱うための抽象化を含む
- この構造により、レンダラーごとに別々に保守していた基盤作業を共有できる
- シーングラフの走査
- 変換やその他の状態の維持
- テクスチャとグリフのキャッシュ
- 2つのレンダラーを最新状態にそろえて維持する作業
Metal と DirectX へ拡張する際の条件
- 同じアプローチを macOS の Metal ベースのレンダラーや Windows の DirectX ベースのレンダラーへ拡張できる可能性はある
- Vulkan と GL は基本的に同じシェーダー言語である GLSL を共有している点で有利である
- Metal や DirectX には同じ条件は当てはまらず、シェーダーを重複して書くか、SPIRV-Cross のような変換ツールが必要になる
- こうした作業に関心のあるコントリビューターは歓迎される
実装方式と ubershader
- 従来の GL レンダラーは各 rendernode タイプごとに単純なシェーダーを使い、複雑なコンテンツではオフスクリーンレンダリングに頻繁に依存している
- 統合レンダラーもより強力な ノード別シェーダーを備えるが、オフスクリーンの代わりにバッファデータを解釈する複雑なシェーダーも併用する
- ゲームプログラミングでは、このアプローチは ubershader と呼ばれる
- 新しい実装は従来の GL レンダラーほど最適化されていないが、正確性と保守性を優先し、より多様な rendernode ツリーを正しく処理できる
レンダリング品質と新機能
-
アンチエイリアシング
- 従来の GL レンダラーでは、ピクセル1行分の境界の間に収まるほど小さい細部を失うことがある
- この問題は mnemonic のような下線にも影響する可能性がある
- 統合レンダラーは小さな細部をよりよく保持し、プリミティブの輪郭のジャギーも減らす
-
分数スケーリング
- アンチエイリアシングは 分数スケールを適切に扱うための基盤になる
- 1200×800 のウィンドウを 125% にスケーリングする場合、統合レンダラーは 1500×1000 のフレームバッファを使う
- コンポジターに 2400×1600 の画像をダウンスケールさせる方式より、処理するピクセルがはるかに少なく、画像もより鮮明になる
-
任意のグラデーション
- 従来の GL レンダラーは、線形・放射状・円錐形グラデーションで最大6個の色停止点しか処理できなかった
- 統合レンダラーは色停止点の数を 無制限に許可する
- グラデーションにもアンチエイリアシングを適用し、鋭い境界に滑らかな線を作る
-
dmabuf
- GTK は昨秋、dmabuf 対応とグラフィックスオフロードの作業を進めた
- 新レンダラーはこれをサポートし、render_texture API でテクスチャ生成を要求されたときに dmabuf を作れるよう拡張している
- 現時点でこの拡張は Vulkan レンダラーのみに該当する
アプリ開発者が確認すべき点
-
glshader ノード非対応
- glshader ノードは GTK 4.0 デモでは有用だったが、従来の GL レンダラーに強く結びついている
- このノードは従来レンダラーが公開する GLSL API を前提としている
- 新レンダラーは glshader ノードをサポートしない
- GTK のドキュメントでは、シェーダーに依存する前に検証し、失敗した場合はより単純なシェーダーまたはシェーダーなしの代替経路を使うよう案内している
- GTK 4.0 以降、mask ノードや straight-alpha テクスチャ対応などの機能が追加され、多くの glshader ノード利用例はもはや不要になった
-
分数位置
- 従来の GL レンダラーは位置を丸めていたため、分数位置を渡しても問題が表面化しないことがあった
- 新レンダラーは指定した位置にそのまま配置する
- この違いは意図しない結果を生む可能性があるため、位置が期待どおりの値か確認する必要がある
- 特に、1行分のピクセルを正確に塗りつぶすために線を半ピクセル位置に置く cairo スタイルの描画には注意が必要である
-
ドライバー問題
- 新レンダラーはグラフィックスドライバーを新しく異なる方法で使うため、ドライバー側の問題を引き起こす可能性がある
- 問題がドライバーの問題に見えても、GTK に報告するのがよい
- さまざまなドライバーやハードウェアで新しいコードがどれだけうまく動作するかを把握する助けになる
現在の性能状況
- 新レンダラーはまだ従来レンダラーより速くない
- 従来の GL レンダラーは速度に合わせて強く最適化されており、より単純なシェーダーを使い、アンチエイリアシングのような機能に必要な計算を行わない
- 新レンダラーを最終的により高速にすることが目標だが、現時点では 新機能と正確性のほうが大きな改善点である
- すべての GPU ベースのレンダラーは、現在の GTK アプリを 60fps または 144fps でレンダリングするのに十分高速である
- 非科学的なベンチマークでは、Vulkan レンダラーは従来の GL レンダラーと同程度、または一部のケースで上回る水準に近い
- 新しい GL レンダラーがより遅い理由は、まだ追跡されていない
デフォルト変更と例外
- リリースされたばかりの GTK 4.13.6 スナップショットで、ngl レンダラーが新しいデフォルトになった
- この変更は試験導入であり、複数のアプリでより広くテストし、本番利用に耐える状態かを確認する必要がある
- 大きな問題が現れた場合、GTK 4.14 で従来の gl レンダラーに戻す可能性がある
- Vulkan レンダラーはまだデフォルトではない
- WebKit GTK4 ポートは GL では動作するが、Vulkan では動作しない
- GtkGLArea と GtkMediaStream は現在 GL テクスチャを生成しており、Vulkan レンダラーはそれを直接取り込めない
- これらの問題が近い将来解決されれば、デフォルトレンダラーの判断を再検討する予定である
- 非常に古いハードウェアで GTK を使っている場合は、従来の GL レンダラーのほうがよい可能性がある
- 従来の GL レンダラーは GPU に求める条件が少ない
GSK_RENDERER 環境変数でレンダラー選択を上書きできる
- 例:
GSK_RENDERER=gl
今後可能な作業
- 新レンダラーは、以前から望まれていた機能を実装するための基盤になる
- 今後可能な作業には次のものが含まれる
- HDR を含む適切な 色処理
- GPU でのパスレンダリング
- グリフレンダリングを含める可能性
- メインスレッド外でのレンダリング
- 古く、性能の低いデバイスでの性能改善
- 一部の項目は短期・中期作業の焦点になる予定である
- 新レンダラーにはさらに機能追加が予定されており、ユーザーは自分で試して動作可否を知らせることができる
1件のコメント
Hacker News のコメント
ずいぶん前、おそらく2010年ごろに、ブラウザ内で GTK アプリを表示し、UIを通常の HTML+CSS で構成する実験的な HTML レンダラーがあった気がする
当時は本当に衝撃的で、Atom、VS Code、Electron、もしかすると NodeJS もまだ出る前だったと思う
そのレンダラーがまだ残っているかは分からない
https://docs.gtk.org/gtk4/broadway.html
https://www.phoronix.com/news/GTK4-Broadway-Being-Used
主流/公式のバックエンドだとは思っていなかったけど、まだ残っていて Gtk4 にも移植されている
ブラウザが提供するほぼすべてを捨てて最初から作り直す、純粋な canvas アプローチに近い動作特性だから
正しく動作しているかを判断する基準はだいたい (a) ブラウザのスクロールを使うこと、(b) ブラウザのテキストレンダリングを使うこと、(c) リンクを実際の要素として扱うことだが、Broadway はその3つすべてに失敗している
スクロールを再実装し、テキストをサーバー側でレンダリングして画像として送り、リンクをクリックしようとすると実際に止まるように見える
さらにテキスト入力もキーイベントだけを使っているようなので IME の合成が完全に壊れ、キーボードナビゲーションもネイティブではなく GTK 側の可能性が高い
アクセシビリティツリーも意味のある形では提供できない
技術デモや制約を受け入れる個人用途ならよいが、一般公開向けの配布には不向きで、実質的には少し DOM 利用が混ざった RDP/VNC 系に近い
コードがすべてサーバー上で動く点も覚えておく必要がある
実質的にはピクセルデータを canvas 要素へストリーミングする方式なので、Web ビューア付きの VNC とほとんど同じ
https://imgur.com/a/2EDZ2Ti
https://github.com/moondev/gtk3-docker
自分の用途は、ブラウザの中でブラウザを実行し、ポートフォワーディングやプロキシなしで Kubernetes clusterip サービスと簡単にやり取りすることだった
もう1つのクールな例としては、virt-manager を立ち上げて gtk virt-viewer で VM を実行し、ブラウザから操作する方法がある
https://github.com/m-bers/docker-virt-manager
GTK には タイトルバーにウィジェットを入れる流れに乗らないでほしい
ドラッグできるものとできないものがあり、アプリ名やファイル名を表示するスペースも減ってしまう
これは GTK だけへの不満ではない
ピクセル単位で正確な 分数スケーリング、いいね、やった!
あとは Wayland で適切にサポートされさえすれば、主要な Linux デスクトップ環境すべてで HiDPI サポートが可能になりそう
1200×800 のウィンドウを 125% にスケールすると、統合レンダラーはコンポジターに 2400×1600 の画像を縮小させる代わりに 1500×1000 のフレームバッファを使う、と書かれている
私の理解では、125% の倍率のため画面上では 1500×1000 ピクセルで描かれるべきウィンドウが、アプリケーションピクセル基準では 1200×800 という意味だと思う
OpenGL と Vulkan は浮動小数点でレンダリングするので、座標変換を通じて画面に 1:1 でレンダリングできるバッファへ直接描けばよい、という話なのだろう
これが正しいなら、ようやく 常識的な方式に見える
Linux で デスクトップ環境がどう動作しているのかをきちんと理解している人はいるのだろうか? 私にはよく分からない
ますます複雑になり、継ぎ足されている感じしかしない
クライアント/サーバー構造は、結局私たちが到達した高度に統合されたグラフィックス処理モデルとは正反対だった
X11 を早く諦めて損切りする代わりに、Unix ベンダーとオープンソースの双方が、腐ったレモンをトラック1台分使ってレモネードを作ろうと長く粘りすぎた
だから Linux GUI はここまで遅れたのだ
Apple は X11 に縛られず統合モデルを受け入れたため、Unix GUI を素早く発展させることができ、今では自社 GPU まで設計している点が注目に値する
Wayland アーキテクチャがどれほど大きな影響を与えるのか、そして GNOME 専用アプリが実際に生まれるのか気になる
ANSIテキストレンダラーがあるといい
自分のxterm内でGTKプログラムを実行できるように、任意でsixelも少し添えたい
サイドバー、タイトルバー上のいくつかの操作、詳細ビュー構造だ
Macアプリ、“Modern” Windowsアプリ、モバイルアプリも似ている
UXツールキットが完全に宣言的かつ意味論的になれるのか気になる
「マスター/詳細ビュー、このようなフィールドを持つリストビュー、いくつかの操作が必要だ」のように、高いレベルでは位置やスタイルを与えず、適切なシステムウィジェットを自動的に使う方式だ
その上に少しのCSSやネイティブウィジェットへ抜けるエスケープハッチを載せられる
ブラウザー、WYSIWYGエディター、メディアビューアーでないほぼすべてのアプリはこの枠に収まりそうで、こうした記述からTUIを簡単に生成できることが要点だ
https://github.com/fathyb/carbonyl
https://i.imgur.com/pIQ4K7Q.png
https://wgpu.rs/を使っていれば、DirectXとMetalがタダで手に入ったのに :)
この作業は本当に面白そう
アンチエイリアシングの部分を読みながら、ゲームエンジンで使うような符号付き距離場が任意倍率のフォントレンダリングにもよく効くのではないかと思った
Valveがこのテーマで良い論文を出したことがある
ゲームレンダラーのUIコードやデカールレンダリング周りには、GUIコードにも役立ちそうな優れた手法がたくさんある
なぜ性能低下が受け入れられているのか分からない
自分は古いハードウェアでほとんどの作業をしているので、こういう機能はオフにできるならオフにしたいし、自分のGPUではそもそも対応していないかもしれない
目に見える性能低下があるなら
GSK_RENDERER=glを使えばいいMicrosoft、Apple、Googleなら、こういう内容を議論すらしなかった可能性が高い
おそらくMicrosoftは「既存のAPIは忘れて、ここに新しいAPIがある」、Appleは「${WEIRD_NAME}から強制」、Googleは「そのアップデートは受け取れない」くらいだっただろう
ただ残念なのは、Vulkanレンダラーが既存のGLレンダラーとほぼ同程度の性能にしか到達していない点だ
これは問題が3D APIそのものよりも呼び出し側にあるという兆候に見える
実装中ずっと性能を追跡して反復改善すべきで、「アーキテクチャ上の純粋性」に頼るのは良い考えではなかったのだろう
即時モードのレンダリングAPIを保持モードに変換して速くなった例を見たことがない
何らかの形で可能ではあるだろうが、膨大な作業が必要で、病的なケースを直すにはAPIクライアント側の変更も必要になるはずだ
記憶では、彼らの多くは高価なMacBookを使っているため、「自分のコンピューターでは問題ない」で無視される問題が多い
たとえばRetinaディスプレイには影響しないフォントレンダリングの問題がいくつもある
苦々しく聞こえないとよいのですが、まともなグラフィックスエンジン開発者の大半は、オープンソースのGUIツールキットのレンダラーより何世代も先を行くレンダラーをすでに作ってきました。
私たちの中には、オープンソースのデスクトップに本当の次世代レンダリングを持ち込める人が何人もいますが、ゲーム開発会社で働いており、それが生活の糧になっています。
オープンソーススタックに貢献する時間はありません。
コミュニティがこうした開発者に定期的に報酬を支払う予算を組めるなら、レンダラーやツールキットのアップデートは大きく変わるでしょう。
他のオープンソースアプリも同じです。
2Dグラフィックスはゲームエンジンとの共通点が非常に少ないです。
2Dでは通常、入力としてベジェ曲線や他のスプラインが入り、オーバードローが多く、ユーザーが提供するテクスチャのためにVRAMメモリ管理が複雑になります。
それに対してゲームエンジンは、動的ライティング、ボリュメトリック効果、動的環境のような、2Dレンダラーとは無関係な難しい問題を解いています。
ゲームUIツールキットとデスクトップGUIフレームワークは、期待されるものが違う別々の世界にいるように感じます。
私のキャリアで両方を使った経験では、GTK/QtはOS統合、アクセシビリティ機能、キーボードナビゲーション、コピー/ペーストのような機能の扱いが、たいてい良いか非常に良いです。
ゲームUIツールキットはこうしたものを必要としないため、完全に諦めていることが多く、その代わりに性能、テーマ、ゲームエンジン統合に注力します。
理論上はレンダラーはこうした部分から独立していると言えますが、実際には完全にそうではありません。
予算が限られているときに、どの機能に時間を使うかも違います。
非常に高速で正確なレンダラーは、ゲームUIツールキットほどデスクトップGUIフレームワークでは重要ではありません。
CMYKや印刷単位をサポートしているものはいくつありますか?
GUIレンダラーには必要だがゲームエンジンには不要なものの、表面をなぞった程度にすぎません。
ゲーム開発者たちが集まって、Skiaよりはるかに速く、それでいて多くの機能を犠牲にしない何かをさっと作れる、という話には非常に懐疑的です。
生活を成り立たせる必要がありつつ、ソフトウェアを使い、ときどきコードを貢献する形で、できる範囲で貢献する人たちです。
もちろんコミュニティが資金を集められれば素晴らしいですが、その調整作業自体も、誰かにとっては生活の糧にならない仕事になります。
オープンソース/自由ソフトウェアが好きで、その存在に感謝し、可能なときには貢献もしますが、私はずっと以前から、これは特権を持つ人々の営みだと考えてきました。
自由時間が必要で、その自由時間を生活水準を上げないことに使えなければならず、しかもそれを継続できなければなりません。
私はゲーム業界で働いていて、3Dレンダラーは非常に優れていますが、競争力があると感じられる2D UIレンダラーは見たことがありません。
パスやパターンのレンダリングには何を使っているのですか?