Phase 12: Metal GPU Compositor (5/7)#
Goal: Translate the existing PaintCommand display list into Metal GPU draw calls, replacing the software renderer for the main rendering path.
Depends on: Glyph texture atlas for GPU text rendering
Requirements#
-
Implement display list → Metal translation for each PaintCommand variant:
FillRect→ emit a solid-color quad (4 vertices, 2 triangles)DrawGlyphs→ for each glyph in the TextLine, emit a textured quad sampling from the glyph atlas, tinted with the text colorDrawImage→ emit a textured quad sampling from the image's MTLTexturePushClip→ set MTLRenderCommandEncoder scissor rect (intersect with current)PopClip→ restore previous scissor rect from stack
-
Batch draw calls for efficiency:
- Collect all solid-color quads into one vertex buffer range
- Collect all textured quads (same atlas page) into another range
- Minimize draw call count by batching quads that share the same texture
- Maintain correct painter's order (don't reorder across clip boundaries)
-
Handle scroll offsets:
- Apply page scroll offset as a vertex transform (translate all positions by -scroll_y)
- Per-element scroll offsets applied during display list generation (already handled)
-
Wire into browser main loop:
render_page()produces display list → Metal backend processes it → presents drawable- Replace the current Renderer → BitmapContext → CGImage path
Acceptance Criteria#
- All PaintCommand types render correctly via Metal
- Clipping (scissor rects) works for overflow containers
- Visual output matches the software renderer for test pages
- Scrolling works correctly
- Draw calls are batched (not one draw per rectangle)
- No external crate dependencies
-
cargo clippy --workspace -- -D warningspasses -
cargo test --workspacepasses