Web開発
WebKitにおけるIgaliaのレイヤーベースSVGエンジンのアップデート(レイヤーオーバーヘッドの削減)
An Update on Igalia's Layer Based SVG Engine in WebKit (Reducing Layer Overhead) (blogs.igalia.com)
要約
Igaliaは、WebKitのレイヤーベースSVGエンジン(LBSE)の開発状況を報告しています。LBSEは、SVGレンダリングをHTML/CSSレンダリングエンジンと統合し、ハードウェアアクセラレーションなどの恩恵を受けることを目指しています。最近の進捗では、レイヤーオーバーヘッドを削減するための「条件付きレイヤー作成」という大きな変更が導入され、パフォーマンス向上と将来的な統合の基盤が築かれました。
全文翻訳
最後にレイヤーベースSVGエンジン(LBSE)についてここで書いたのは2021年の秋で、技術設計書を公開した時でした。それ以来多くのことがありましたが、おそらく4年近く経ってから期待されるようなことではないかもしれません。エンジンはWebKitに組み込まれ、うまく動作していますが、まだデフォルトではありません。ミニブラウザのランタイム設定を切り替えることで有効にする必要があります。
2021年秋から2022年後半にかけて、LBSEはパッチごとにアップストリームでブートストラップされました。新しいLBSE設計内で、パス、シェイプ、テキスト、ポリゴンなど、SVGを構成するすべての個々のビルディングブロックのサポートを追加しました。その最初の大きなプッシュの後、作業は数ヶ月停滞し、Wixからの手厚い支援により2023年中頃に再開され、2024年4月まで続きました。この期間中、クリッピング、マスキング、フィルター、非ソリッドペイントサーバー(パターン、グラデーション)、マーカーなどのほとんどの高度なペイント機能が実装され、レガシーSVGエンジンが行っていたような別々のコードパスを通るのではなく、HTMLやCSSとロジックを共有しました。その後、作業は再び一時停止しました。この規模のプロジェクトは、前進するために継続的な資金提供を必要としますが、しばらくの間その資金がありませんでした。
LBSEは有望ですが、まだその地位を確立する必要があります。そして、その意味について正確であることが重要です。なぜなら、目標は単に「SVGを速くする」ことではなかったからです。レガシーSVGエンジンは孤島です。歴史的に成長し、独自のペイントコード、独自の変換、クリッピング、マスキングなどの処理を持ち、歴史的な理由からHTMLやCSSをレンダリングするコードとはほとんど共有していません。WebKitに投入された多くの改善は、「もう一方のエンジン」、つまりメインの部分であるHTML/CSSレンダリングエンジンに投入されました。GPUアクセラレーテッド変換とアニメーション、アクセラレーテッドコンポジット、HTML/CSSを高速化したすべての作業です。SVGはそれと並んでいましたが、その恩恵を全く受けていませんでした。それがLBSEの真の目的です。SVGを同じ仕組みに乗せることで、それらすべてを一度に継承し、次に何が来ても継承し続けることができます。誰かがSVGのためだけにそれを二度構築する必要はありません。
落とし穴は、共有される仕組みは汎用的な仕組みであり、汎用性にはコストがかかるということです。レガシーエンジンは、20年間のチューニングを経て、まさに一つの仕事のために手作業でチューニングされています。一方、LBSEは、HTML/CSSレンダリングコードに外科的に統合する必要があり、そのコードを少しでも後退させることはできません。これはエンジンの最もホットなコードであり、すべてのウェブページをレンダリングするため、LBSEが見栄えがするようにレイアウトやペイントにSVGの特別なケースを散りばめることは単に選択肢ではありません。LBSEが必要とするものは、既存のデザインに適合するか、HTMLやCSSのためにも既存のデザインを改善する必要があります。
そこには第二の種類のアプローチも隠されています。HTMLではまれなものが、SVGではどこにでもあります。変換がその明白な例です。典型的なウェブページには数個の変換された要素がありますが、SVGではほぼすべての要素が変換を持つことができ、深くネストされた変換が標準です。共有コードはHTMLを念頭に置いて書かれており、そこで完璧に機能します。そのため、共有される仕組みの一部は再作業が必要であり、HTMLのために誰も必要としなかった高速パスは、何も遅くすることなくゼロから発明されなければなりません。
したがって、ハードルは二重です。LBSEはまず、レガシーエンジンがすでに得意としているプレーンで日常的なレンダリングにおいて、レガシーエンジンと競争できなければなりません。なぜなら、静的なアイコンが突然ペイントに時間がかかるようになっても、誰もエンジンを切り替えないからです。残りの部分、ハードウェアアクセラレーション、そしてSVGが今や無料で得られるHTML/CSSエンジンのすべての将来の改善は、最初のハードルが満たされた場合にのみ勝利と見なされます。
2026年初頭に早送りします。今年、ついに現状が変わりました。Igaliaは、エンジンがその実力を証明する機会を与えるために、LBSE開発の新たなラウンドに一時的な投資を行いました。私たちは、LBSEがパフォーマンスに優れていることを世界に示し、パフォーマンスが高くハードウェアアクセラレーテッドなSVGエンジンが組み込みデバイス上のUIの未来であるという私たちのビジョンを共有する新しいパートナーを引き付けることを望んでいます。これは、2026年前半の状況と、2024年の長期休暇以降のLBSEプロジェクトの進化をカバーする2つの投稿のうちの最初のものです。過去6ヶ月は集中的で、最初の執筆以来LBSEに対する最も侵襲的な変更で終わりました。この記事はその変更をカバーし、次の記事ではそれが残した難しい問題を取り上げます。
どこにいたかの簡単な復習
LBSEを設計したとき、中心的なアイデアは単純でした。古い、別々のSVGペイントコードを維持する代わりに、SVGはHTMLとCSSがすでに使用しているのと同じ仕組み、RenderLayerツリーを再利用すべきです。それが、SVGがWebKitでこれまで持っていなかったハードウェアアクセラレーテッド変換アニメーション、パースペクティブ変換、z-indexサポートなどのすべての良いものを解き放ったのです。
そこへ迅速に到達するために、初期の頃にショートカットを取りました。すべてのSVGレンダラーが独自のRenderLayerを取得しました。<rect>、<path>、<g>、すべてです。理由は利便性でした。各要素がレイヤーを持つ場合、既存のレイヤーツリーはすでに子要素の順序付け、変換の適用、クリッピング、コンポジットの方法を知っています。それらのいずれかを再発明する必要はありませんでした。さらに、DOM構造に1対1で従うSVG固有のペイント順序は、この方法で自動的に保証され、z-indexサポートは必要に応じてその順序から逸脱するために依然として存在します。すべてのレンダラーが独自のレイヤーを受け取れば、それらはすべてすぐに機能します。RenderSVGModelObject::requiresLayer()は常にtrueを返し、WebCoreの残りの部分が重い作業を行いました。
このアプローチは、あまりにも無駄が多いため、この形式で出荷されることはまずないだろうと、最初からわかっていました。しかし、それは問題ありませんでした。それは最終的な設計を意図したものではありませんでした。それが私たちに与えたのは、SVGが長年欠けていたものを最終的に試す方法であり、すべてHTMLやCSSと同じ仕組みで動作することでした。また、SVGレンダリングツリークラスをすべて再実装する可能性も与えてくれました。これにより、例えばSVG <clipPath>がSVG要素またはHTML要素に適用された場合、歴史的にWebKitで行われていたように、もはや異なるコードパスを通らなくなりました。したがって、レンダラーとレイヤーの1対1の対応を維持することが、アイデアが実際に機能するのを見るための最も速い道であり、一度それが実現すれば、エンジンの本当の形がそれに続くことができました。
正確さが第一
LBSEの作業を再開したとき、まず長期のアップストリーム作業の停止後にエンジンが再び正しく動作することを確認する必要がありました。LBSEはその期間中テストを受けていなかったため、壊れた状態である可能性が高く、実際その通りでした。テキストレンダリングは当初完全に壊れており、ほとんどのテストベースラインは古く、レガシーSVGエンジンは修正を受けていたのにLBSEは受けていなかったため、多くの新しいリグレッションが存在しました。回復するのにしばらく時間がかかりました。
LBSEのブートストラップという事業における私のパートナーであるRob Buisは、この作業の多くを行い、私が残りのパフォーマンス問題に取り組み、エンジンをプロファイリングし、新しい設計を試すことに集中できるようにしました。例えば、<use>要素のgetBBox、NaN座標や線キャップを持つパス、子要素が変更されるマーカーなど、多くのクラッシュを修正しました。テキストが全くレンダリングされない、テキストの不透明度、非可逆なgradientTransformを持つグラデーション、SVGビューフラグメントのサポートなど、実際のレンダリングバグも修正しました。
フィルターは春の間、多くの注目を集めました。無効なフィルターが要素全体をドロップするのではなく、HTMLの場合と同じように動作するように修正し、feOffsetクリッピング、フィルターのスケーリング、畳み込みフィルターのテストを修正しました。しかし、最も重要なフィルターの変更はまだ行われていません。条件付きレイヤー作成、つまりこの記事の残りの部分で説明する変更が中間レイヤーを削除すると、フィルターの座標空間はペイントコードが想定していたものと一致しなくなり、フィルターされたコンテンツの多くが間違った場所に配置されることになります。保留中のプルリクエストは、レイヤー化されていないレンダラーに対してそれを修正します。