Table of Contents
ohm_gl_fix — Phase 6 Step 0: Chromium's Wayland video presentation path, 2026-05-01
Per Phase 4 §3 Step 0 (with the Q2 methodology fix applied): characterise statically whether Chromium's GPU process routes a hardware-decoded NativePixmap to the Wayland zwp_linux_dmabuf_v1 overlay path, or composes it via Skia GL onto the page's main surface. Output gate: file:line citation for the gating logic in the decision document.
Summary
Step 2 is confirmed needed. Under the current Chromium M138 design, overlay delegation on KWin Wayland is forced off by a gate condition that KWin's compositor capabilities trip. Phase 4 Step 2 (Chromium display-side patch) is no longer conditional; it is in scope.
The patch site is one specific predicate in WaylandConnection::ShouldUseOverlayDelegation().
Routing decision chain (top-down)
A NativePixmap (dmabuf-backed VA-API surface) flows from VaapiVideoDecoder to the GPU process to Viz compositor to Ozone Wayland. The routing decision happens in two stages:
- Stage 1 — system-wide enable.
WaylandConnection::ShouldUseOverlayDelegation()returns a single bool that gates the entire overlay-subsurface path. If false, no buffer ever becomes an overlay regardless of its properties; everything goes through Skia GL composite onto the main page surface. - Stage 2 — per-buffer candidate filtering. If overlay delegation is enabled, individual buffers are filtered by a Viz-side
OverlayProcessor/IsOverlayCandidate()chain (incomponents/viz/service/display/overlay_processor*.cc). This stage checks format, modifier, size, damage region, and so on. The transport layer (WaylandBufferManagerHost) is buffer-agnostic at this point — it just shuttles whatever the candidate pipeline produced.
For Brave on KWin: Stage 1 fails, so Stage 2 is unreachable. The campaign's Step 2 patch lives at Stage 1.
The gating predicate
ui/ozone/platform/wayland/host/wayland_connection.cc lines 495-509:
bool WaylandConnection::ShouldUseOverlayDelegation() const { bool should_use_overlay_delegation = IsWaylandOverlayDelegationEnabled() && !fractional_scale_manager_v1(); should_use_overlay_delegation &= !!single_pixel_buffer(); return should_use_overlay_delegation; }
Three conjuncts:
IsWaylandOverlayDelegationEnabled()— runtime feature flag. Likely off by default but settable via–enable-features=orchrome:flagsenumeration). Open.. Sub-task open: confirm flag name in M138. *wp_fractional_scale_manager_v1!fractional_scale_manager_v1()— the compositor must NOT advertise theWayland protocol. *!!single_pixel_buffer()— the compositor MUST advertise thewp_single_pixel_buffer_manager_v1Wayland protocol. KWin's compositor capabilities (verified empirically in mpv's verbose log captured during Phase 3): * Registeredwp_fractional_scale_manager_v1at version 1 → second conjunct is false → predicate returns false. * Registeredwp_single_pixel_buffer_manager_v1at version 1 → third conjunct passes (but moot given second). So on KWin Wayland,ShouldUseOverlayDelegation()returns false unconditionally regardless of feature flag. ===== Why the gate exists (per upstream comment) ===== Reading of the surrounding comment block (lines 497-502): fractional scaling requires viewport rescaling that, on non-exo compositors (i.e. anything that isn't ChromeOS/Crostini), conflicts with overlay support because subpixel viewport destinations and subsurface positions aren't widely available. The conservative gate disables overlay whenever fractional scaling is even *possible* (advertised), not just when it's actually active for the surface. This is over-conservative for Markus's use case: PineTab2 + KWin typically runs at integer (1.0) display scale; fractional scale is advertised but not enabled. The gate trips on capability advertisement, not on actual scale state. ===== Patch shape (Phase 4 Step 2 specification) ===== Three plausible patches, in order of least-to-most invasive: - Surface-state-gated relaxation. Replace!fractional_scale_manager_v1()with a check that returns true when the surface's currently-applied scale is integer (1.0, 2.0, etc.). The protocol is allowed to be advertised; we just require that the relevant surface isn't *using* fractional scale right now. Smallest behavioural change; preserves correctness when fractional scale is in fact active. - Per-surface negotiation. Drop the gate entirely and let the VizOverlayCandidatevalidator (Stage 2) reject candidates that need viewport-subpixel destinations on this compositor. Bigger refactor; touches Viz's overlay validator code. - Compositor-capability allow-list. Add a feature flag (e.g.–enable-features=WaylandOverlayDelegationOnFractionalCompositor) that bypasses the second conjunct when set. Crudest; relies on the user to know the trade-off. Useful as a probe during Step 2 development but not a shippable answer. Patch (1) is the recommended Step 2 shape — minimal blast radius, restores correct behaviour for KWin's typical integer-scale usage without breaking fractional-scale users. ===== Step 0 sub-task status ===== * Source archaeology —wayland_buffer_manager_host.cc,wayland_window.cc,wayland_connection.ccall read. The gating predicate is named with file:line. ✓ * Verify with feature-flag inventory. ConfirmIsWaylandOverlayDelegationEnabled()accepts a known–enable-features=flag name (M138 source archaeology orchrome:flags- Optional stub libva driver test. Per Phase 4 §3 Step 0, only run if static analysis is inconclusive. Static analysis is conclusive enough — Step 2 is needed. Skipped.
- Document Viz-side per-buffer filtering (Stage 2 above). If/when the Step 2 patch lifts the Stage-1 gate, Stage 2 becomes the next-level gate that needs to pass for actual Brave-decoded
NativePixmapto land as an overlay. Not blocking Step 1 / Step 2 work, but should be characterised before Phase 7 verification so we can predict whether C3 (DRM_IOCTL/sec ≤ 100) will be met. Open.
Implications for Phase 4
Phase 4 §3 has been amended (in-place, 2026-05-01):
- Step 2 is confirmed needed, no longer conditional.
- Step 2 patch site:
chromium/ui/ozone/platform/wayland/host/wayland_connection.ccWaylandConnection::ShouldUseOverlayDelegation()lines 495-509. - Step 2 patch shape: surface-state-gated relaxation of the
!fractional_scale_manager_v1()predicate. - Step 2 build target:
chromium-ohm-gl-fixorbrave-ohm-gl-fixon marfrit-packages.
The R2 risk in Phase 4 §6 (“Chromium routes via Skia GL by default”) was correctly anticipated and the mitigation is now activated, not just spec'd.
Artefact references
- This document — Step 0 decision document, attached to Phase 4.
- phase6/step0_5_uapi_audit_2026-05-01 — companion Step 0.5 UAPI layout reference.
- Chromium M138.0.7204.157 source files cited inline.
