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:
wp_drm_lease_v1 (architect's secondary hypothesis).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):
src/scene/composite.cpp and the strategy code under src/scene/. Find the predicate (something like OutputLayer::testFormat(format, modifier, size) or the plane-probe path). Document the conjunct list it uses.drm_info or modetest -p on 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).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.
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 a zwp_linux_dmabuf_v1 buffer 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 via wp_drm_lease_v1 (which KWin advertises, per Brave's chrome:gpu dump).
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 of KWin::Display::dispatchEvents and 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 as phase1_reference_cage.
* [ ] Capture default-KWin baseline metrics under this campaign's protocol (will replicate ohm_gl_fix A2 numbers). Record into metrics.csv as phase1_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's linuxdmabufv1clientbuffer (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 via wp_drm_lease_v1 when possible. Bigger refactor; harder to land upstream.
* [ ] Document the chosen shape in phase4_design.md with 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 a weston or cage test 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 from phase8_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 row phase1_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.patch from 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.