- ブラウザURL入力今ここ
- DNS名前→IP
- ルータ経路選択
- ロードバランサ振り分け
- Nginx受け口
- アプリ処理
- DB保存
前のレッスンで公式の12段を並べました。今回はその中から Layout・Paint・Raster・Layerize の4段を取り出し、それぞれが何を出力するのかを見ます。段の名前と、その段が実際に作るものがズレている箇所があります。
まず結論
**Paint はピクセルを塗る段ではありません。** 公式の逐語は `compute a display list` — 描画命令のリストを作る段です。それを `GPU texture tiles` に変えるのは後の **Raster** 段、公式が `create pixels on-screen` と書くのは最後の **Draw** 段です。
そのラスタには **software raster と gpu raster の2モード**があると公式が明記しています。だから「GPUが描く」と一言で断定できません。同じく **`will-change` を書けばレイヤに昇格する**とも仕様は書いていません。仕様の文言は `might` / `perhaps` で、**保証しているのは stacking context と containing block の生成だけ**です。
Chromium公式が Paint 段の説明として書いているのは、次のどれでしょうか。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
段の名前と、その段が作るものがズレている
前のレッスンで12段を並べました。今回は、その中の4段が何を出力するのかだけを追います。名前から受ける印象と、実際の出力がズレている箇所があります。
段 公式の説明 出力されるものLayout 大きさと位置を決める the immutable fragment treePaint compute a display list display list(描画命令のリスト)Layerize display list を合成レイヤに分割 composited layer listRaster GPUテクスチャタイルに変換する GPU texture tiles
Paint の行を見てください。 逐語はこうです。
Paint: compute a display list that describes how to raster GPU texture tiles from the DOM.
「塗る」という名前ですが、作っているのは display list です。Chromium ソース内の paint の README はもっと直接的に書いています。
Walks the LayoutObject tree and creates a display item list.
そして、その display list が誰に渡るのか。
The primary responsibility of this directory is to convert the outputs from layout (the
LayoutObjecttree) to the inputs of the compositor (thecc::Layerlist, which contains display items, and the associatedcc::PropertyNodes).
Paint 段は、Layout の出力をコンポジタの入力に変換する段です。ピクセルは1つも作りません。
Layout の出力も、名前から想像するものとは違います。公式が挙げるのは the immutable fragment tree です。LayoutNG の解説にはこう書かれています。
While the layout object tree structure closely resembles that of the DOM tree, the fragment tree is an output of layout, not an input to it.
Chromium の cc には何種類のラスタのモードがあり、それは何ですか。
ではピクセルは誰が作るのか
display list を GPU texture tiles にするのは Raster 段です(create pixels on-screen は最後の Draw 段の説明)。ここで初めてGPUの話が出てきます——ただし、必ずGPUとは限りません。
docs/how_cc_works.md の逐語です。
TileManager is responsible for rasterizing the world of tiles. Each PictureLayer provides a set of Tiles to rasterize, where each Tile is a subrectangle of painted content at a particular scale.
そして重要な一文。
There are currently two modes of raster in cc:
software raster: generate software bitmaps in the raster worker
gpu raster: generate gpu textures by sending paint commands over the command buffer
2つのモードがあります。 software raster はラスタワーカーでソフトウェアビットマップを作り、gpu raster はコマンドバッファ経由で描画命令を送ってGPUテクスチャを作ります。
だから「レンダリングの最後はGPUが描く」という説明は、片方のモードだけを述べていることになります。
cc 自身の役割はこうまとめられています。
cc is responsible for taking painted inputs from its embedder, figuring out where and if they appear on screen, rasterizing and decoding and animating images from the painted input into gpu textures, and finally forwarding those textures on to the display compositor in the form of a compositor frame.
CSS Will Change 仕様が `will-change` について「保証している」効果は何ですか。
Layerize のトレードオフ
レイヤを分けるほど再ラスタは減りますが、GPUメモリを食います。公式は両極端を先に示し、その間で釣り合いを取る段だと説明します。だから「分ければ速い」という単純な規則にはなっていません。
全部を1枚に統合 スクロールのたびに高価な再ラスタが要るchunkごとに分割 再ラスタは避けられるがGPUメモリをすぐ使い果たす公式の方針 既定は統合。コンポジタスレッドで変化が予想されるものだけ統合しない
will-change の仕様文言
事前に最適化を仕込ませるためのヒントですが、仕様は昇格を保証しません。宣言が多すぎるとGPUメモリを使い果たすため、ブラウザは昇格を避けてよい、と仕様自身が書いています。Layerize と同じ資源の制約が、仕様の側にも現れています。
might avoid doing that 昇格を「避けうる」perhaps rendering them to their own 「おそらく」A browser might take ... as a signal 「signalとして扱うかもしれない」保証されるもの stacking context とcontaining block の生成のみ
片方はChromiumの実装方針、もう片方はW3Cの仕様文言です。書き手も目的も違いますが、同じ慎重さが現れています。共通する構造は何でしょうか。
どちらも「最適化を増やすと何が減るのか」を考えてください。そのうえで、なぜ条件を確定させずに書いているのかを見てください。
この章のまとめ
- Paint はピクセルを作らない。 逐語は
compute a display list。README はcreates a display item listと書く。 - Layout の出力は
the immutable fragment tree。an output of layout, not an input to itと明記されている。 - display list を
GPU texture tilesにするのは Raster 段(create pixels on-screenは Draw 段)。ただし cc には software raster と gpu raster の2モードがあり、「GPUが描く」と断定できない。 - Layerize はトレードオフ。 既定は統合し、コンポジタスレッドで変化が予想される property tree state を持つものだけ統合しない。全部分けると GPUメモリを使い果たす。
will-changeが保証するのは stacking context と containing block の生成のみ。 昇格はmightであり、仕様自身が「宣言しすぎると昇格を避けることがある」と書いている。- ★ 「transform はレイアウトを起こさない」は、Chromium 設計文書・仕様では裏付けも反証も取れていない。 明示しているのは web.dev の解説記事(最終更新 2015-03-20)。断定も否定もしないのが正確。
- 60fps / 16.7ms は仕様の要求ではなく例示値。 仕様は
does not mandate any particular modelと明記している。 - 公式ドキュメント自身が
"draw"と“swap”というもう実態に合わない名前が残っていると認めている。名前ではなく入出力で段を理解する。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
「Layout の出力は render tree である」という説明を、Chromium公式の用語に照らすとどうなりますか。
用語集(5語)
- display list
- Paint 段の出力。描画命令のリストであってピクセルではない。paint の README は Paint 段について `Walks the LayoutObject tree and creates a display item list.` と書いている。
- the immutable fragment tree
- 公式が Layout の出力として挙げるもの。`the fragment tree is an output of layout, not an input to it`(LayoutNG の解説より)。
- software raster / gpu raster
- cc にある2つのラスタのモード。前者はラスタワーカーでソフトウェアビットマップを生成し、後者はコマンドバッファ経由で描画命令を送ってGPUテクスチャを生成する。
- layer(cc における定義)
- 逐語は `A layer is a 2d rectangle of content with integer bounds. It has some transform, clip, and effects on it that describe how it should look on screen.`
- will-change の規定上の効果
- stacking context と containing block の生成のみ。それ以外は UA への rendering hint であり、レイヤ昇格は保証されない(CSS Will Change Module Level 1、W3C CRD 2022-05-05)。
出典(一次ソース)
- RenderingNG architecture(各段の逐語) ↗
- Stick to Compositor-Only Properties and Manage Layer Count(web.dev, 最終更新 2015-03-20 — transforms と opacity) ↗
- WebCore Rendering I – The Basics(WebKit blog, 2007-08-08 — render tree) ↗
- RenderingNG: key data structures(Layerize のトレードオフ) ↗
- How cc Works(Chromium ソース内ドキュメント — ラスタの2モード) ↗
- CSS Will Change Module Level 1(W3C CRD 2022-05-05) ↗
- RenderingNG: inside the fragmentation(fragment tree が layout の出力である逐語の出所) ↗
- Blink paint README(Chromium ソース内 — Paint が display list を作る逐語の出所) ↗