Table of Contents
Work items — kwin_overlay_subsurface
Phase 1 — leading research question
Status: LOCKED 2026-05-02. Answer in phase2_source_findings lead section. Outcome: NO on both promotion paths for windowed Brave on rockchip-drm — Phase 4 design space narrows to architect's hypothesis (a), dmabuf-to-GL-texture import-caching.
On what condition does KWin promote a wp_linux_dmabuf_v1 surface to direct scanout versus falling back to GPU composite, and does the hantro NV12 DRM_FORMAT_MOD_LINEAR output satisfy those conditions on this DRM driver (rockchip-drm on RK3568, Mesa 26.0.5)?
This is the question that materially shapes which Phase 2 hypothesis is even reachable, so it leads. It has a yes/no answer that gates everything downstream:
- If KWin can promote our buffer to direct scanout in principle on this DRM driver (hantro NV12 LINEAR is on a list of formats/modifiers the rockchip DRM scanout planes accept), then the Phase 4 design space includes both: (a) cache the dmabuf-to-GL-texture import (architect's primary hypothesis driven by A2 cold-path warmup), AND (b) promote single-color-plane subsurface video to direct scanout via
wp_drm_lease_v1(architect's secondary hypothesis). - If KWin cannot promote our buffer to direct scanout on this DRM driver — because rockchip-drm's overlay planes don't accept the format/modifier/size combination, or because KWin's promotion check has additional gates we don't satisfy — then path (b) is structurally unreachable and the import-caching hypothesis is the only candidate. The Phase 4 design narrows.
Either answer also informs the bug-report shape: a “your overlay subsurface composite is slow” frame works for the import-caching case; a “your DRM-plane probe is rejecting buffers it should accept” frame works for the scanout-promotion case. Different messages, different audiences (KWin maintainers vs rockchip-drm or Mesa panfrost-drm interaction maintainers).
How to answer it concretely (Phase 2 source-read goal #0, ahead of file-by-file priorities below):
- Read KWin's per-frame promotion check —
src/scene/composite.cppand the strategy code undersrc/scene/. Find the predicate (something likeOutputLayer::testFormat(format, modifier, size)or the plane-probe path). Document the conjunct list it uses. - Cross-check rockchip-drm's advertised plane formats via
drm_infoormodetest -pon ohm. Compare what scanout planes claim to support (probably NV12 LINEAR + a few tiled modifiers) against what hantro emits (NV12 LINEAR with bytesperline=2240 for 1920-wide). - Check whether KWin's promotion check additionally requires the surface to be the only damageable region of a given plane (i.e. needs the parent surface to be transparent in that region), or whether it composes scanout-eligible subsurfaces with non-eligible parent regions. Brave's page renders the parent surface with chrome UI on top, which would block plane-promotion on most architectures.
Output of this question: a yes/no plus a paragraph naming the specific conjunct(s) that pass or fail. Lands in phase2_source_findings as the lead section, before the file-level reading.
Phase 2 — source archaeology (NO PATCHES YET)
Read the KWin source and document findings before designing anything. Quote directly from architect's 2026-05-02 second consultation: “Do not write any patch before that read is documented. This is the discipline ohm_gl_fix lacked early.”
The Phase 1 leading question above tells you which of these two hypothesis-tracks to prioritise:
Files to read (priority order driven by A2 trajectory hint — cold-path EGL/dmabuf re-import suspected, see phase0_findings):
- [ ]
src/wayland/linuxdmabufv1clientbuffer.cpp— how KWin receives azwp_linux_dmabuf_v1buffer from a client (Brave). Document the import path: where the dmabuf fd becomes a GL texture, whether the import is cached. - [ ]
src/scene/surfaceitem_wayland.cpp— how the imported buffer becomes a scenegraph item, whether per-subsurface state has a slow path on first sight or each new fd cycle. - [ ]
src/scene/itemrenderer_opengl.cpp— how the scenegraph item is rendered. Whether the renderer has special-case handling for parent+subsurface vs single surface. - [ ]
src/scene/composite.cpp+ scene scheduling code — the per-frame promotion check that decides scanout vs composite. This is also where the Phase 1 leading question is answered. - [ ]
src/backends/drm/— DRM atomic path. Plane-probe logic, format / modifier acceptance per output, whether KWin can promote a single-color-plane subsurface to direct scanout viawp_drm_lease_v1(which KWin advertises, per Brave'schrome:gpudump). Output of Phase 2: phase2_source_findings documenting: * The Phase 1 leading question's answer (yes/no + named conjuncts). * The exact code path a wp_subsurface dmabuf takes from client commit to display. * Hot-path operations identified by reading. * One or two concrete hypotheses for where the per-frame cost lives, each pointing at file:line. ===== Phase 3 — measurement (validate hypotheses with hot-path data) ===== Status: pass-1 LOCKED 2026-05-02. H1 rejected at N=1 across C0/C1/C2 + exploratory C3 stock-Brave. Verdict and full data in phase3_findings. Pass-2 replicates deferred — replication does not change a verdict reached two orders of magnitude beyond the threshold. Phase 4 design space pivots to H1' (Wayland-protocol dispatch as the kwin CPU cost) and to a new H1-drops question (drops are not CPU-caused, per the Brave-vs-chromium-fourier inversion). Phase 2-prime source-read ofKWin::Display::dispatchEventsand the libwayland-server arrival path becomes the new Phase 4 prerequisite. * [ ] Highest-value first measurement:perf record -p $(pgrep kwin_wayland)during BOTH cage and direct-Brave runs. Same clip, same 70 s window. Convert hypothesis from Phase 2 into hot-path evidence. Architect: “single highest-value remaining measurement, and it's cheap.” * [ ] Capture cage baseline metrics under this campaign's measurement protocol (per phase1_lock). Record into metrics.csv asphase1_reference_cage. * [ ] Capture default-KWin baseline metrics under this campaign's protocol (will replicate ohm_gl_fix A2 numbers). Record into metrics.csv asphase1_baseline_kwin. * [ ] (Optional, nice-to-have) DRM-backend cage on a free VT for the decisive isolation test. Disruptive — requires user at the box for VT switching. Defer unless Phase 2 source read points at something only DRM-backed cage can confirm. ===== Phase 4 — design ===== * [ ] Pick patch shape based on Phase 2 + Phase 3 evidence. Two candidate shapes: * Shape A: cache the dmabuf-to-GL-texture import in KWin'slinuxdmabufv1clientbuffer(or wherever the import happens), keyed by dmabuf fd identity (per ohm_gl_fix's original Phase 1 fd-identity-keyed cache hypothesis, which matches A2's cold-path warmup pattern). * Shape B: promote single-overlay-subsurface video paths to direct DRM scanout viawp_drm_lease_v1when possible. Bigger refactor; harder to land upstream. * [ ] Document the chosen shape inphase4_design.mdwith explicit comparison to other candidates and a paragraph explaining the mechanism the patch attacks (not the symptom). ===== Phase 5 — review (pre-MR checklist) ===== Per architect, baked in here to avoid the “AI slop, not 100 % done” rejection mode: * [ ] Reproducer minimised to awestonorcagetest client +kwin_wayland, NOT requiring full Brave. (One client emits a parent surface + one subsurface holding a dmabuf; that's it.) * [ ] Before/after measurement under phase1_lock's protocol. All four binding cells captured both before and after. * [ ] Patch description explains the mechanism (e.g. “KWin was re-importing the dmabuf to a GL texture every frame because…”) not just the symptom (“playback drops frames”). * [ ] At least one KDE upstream reviewer has acknowledged the underlying bug report fromphase8_handover/BEFORE the MR is filed. * [ ] Independent (Sonnet Architect or human) review of the patch against the pre-MR checklist. ===== Phase 6 — implementation ===== Standard implementation phase. Deliver patch + test + measurement artefacts. ===== Phase 7 — verification ===== * [ ] Phase 1 binding cells re-measured post-patch, captured in metrics.csv rowphase1_goal_actual. * [ ] Independent reviewer reads the row + the patch + verifies the claim. ===== Phase 8 — handover ===== * [ ] If patch lands upstream: short close-out doc, repository archive notice. * [ ] If patch is parked at a stable intermediate (e.g. local marfrit-packages override but no upstream MR): clear description of state, what's left for someone else to take up. ===== Open items inherited from ohm_gl_fix (not blocking) ===== * File mpv hwdec=vaapi silent-fallback bug somewhere — only if the user explicitly tasks it. * File Mesa-panfrost WSI pitch bug somewhere — only if explicitly tasked. * File Step 2 upstream PR (upstream_shape_3.patchfrom ohm_gl_fix) — defer until this campaign's KWin patch is in flight, then file with cross-reference. Or never, per the no-unsolicited-upstream principle. ===== Non-upstreaming reminder ===== This campaign inherits ohm_gl_fix's principle: bug reports + MRs are explicit user-tasked decisions, not background process steps. The user previously hit “AI slop, not 100 % done” on a KWin MR — Phase 5's pre-MR checklist exists specifically to guard against that recurring.
