Files
marfrit 8756ce38be
build and publish packages / distcc-avahi-aarch64 (push) Successful in 46s
build and publish packages / lmcp-any (push) Successful in 9s
build and publish packages / lmcp-debian (push) Successful in 4s
build and publish packages / claude-his-any (push) Successful in 7s
build and publish packages / ffmpeg-v4l2-request-aarch64 (push) Successful in 12m8s
build and publish packages / claude-his-debian (push) Successful in 5s
chromium-fourier r2 + firefox-fourier 150.0.1 + KWIN_PIVOT.md
chromium-fourier:
- patch 3/3 nv12-external-oes-on-modifier-external-only.patch — adds
  NativePixmapEGLBinding::ModifierRequiresExternalOES helper, extends
  OzoneImageGLTexturesHolder::GetBinding to honor EGL external_only
  flag for NV12 dmabufs on panfrost / panthor. Validated on ohm
  (RK3566 hantro mainline 6.19.10): bbb_1080p30_h264.mp4 plays at
  34.7 % combined CPU vs ~131 % pre-patch baseline (~3.8x).
- PKGBUILD pkgrel 1->2, source array + sha256sums + prepare() hook for
  patch 4, patch numbering 1/2,2/2 -> 1/3,2/3,3/3.
- NEXT.md appended with 2026-04-28 section: patch 4 design, validation
  log, KWin GL_ALPHA bug pinpoint (preexisting since 2026-03-06,
  affects every wayland video client; unrelated to chromium-fourier),
  device-renumbering note (/dev/video1 = encoder post-reboot).
- KWIN_PIVOT.md: 4-phase plan to identify and patch KWin's
  glTexImage2D(internalFormat=GL_ALPHA) site, ohm-only test plan,
  scope discipline.
- patches/ now tracked (compiler-rt-adjust-paths, enable-v4l2,
  wayland-allow-direct-egl-gles2, nv12-external-oes); the dead-end
  chromeos-pipeline-bypass.patch removed.

firefox-fourier:
- 4 patches (gfxinfo v4l2 stateless fourccs, libwrapper hwdevice ctx,
  ffmpegvideo v4l2-request route, prefs v4l2-request default).
- PKGBUILD bumped to firefox 150.0.1, Arch toolchain glue patches
  layered in, mozconfig with --without-wasm-sandboxed-libraries for
  ALARM, package() launcher fix (rm -f symlink before cat > to avoid
  ENOENT through the dangling /usr/local symlink mach install drops).
- 150.0.1-1-aarch64.pkg.tar.zst built on boltzmann (95 MB), pending
  fresnel power-on for V4L2 stateless validation on RK3399.
2026-04-28 12:02:18 +00:00

429 lines
22 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# chromium-fourier — first-build status (2026-04-26 00:42 UTC)
## Where we are
Build environment: **chromium-builder LXD container on boltzmann**
(8 cores, 28 GB RAM cap, 824 GB NVMe, Beryllium OS rkr3 host kernel).
Source: chromium-147.0.7727.116 release tarball extracted at
`/build/chromium/src` (25 GB extracted).
`gn gen out/Default` **succeeds** with our 7Ji-style args
(`use_v4l2_codec=true use_v4lplugin=true use_linux_v4l2_only=true
use_vaapi=false`, system toolchain via `unbundle:default`, system clang
at `/usr/bin/clang`, version-symlink `/usr/lib/clang/23`
`/usr/lib/clang/22`, compiler-rt-adjust-paths style suffix patch
manually applied). 28057 targets generated.
`ninja -C out/Default chrome` **fails immediately** with two distinct walls:
### Wall 1 — clang version mismatch (chromium 147 ↔ Arch clang 22)
Chromium 147's compile flags include
`-fno-lifetime-dse` and
`-fsanitize-ignore-for-ubsan-feature=array-bounds`. Both are clang 23+
features. Arch Linux ARM ships **clang 22.1.3** (extra repo). Every
single C++ compile fails with `clang++: error: unknown argument`.
Resolutions, in order of effort:
- **(a)** Wait for Arch ARM to bump clang to 23. Tracking package
upstream — happens whenever LLVM 23 lands in extra. Days to weeks.
- **(b)** Use chromium's bundled clang via
`tools/clang/scripts/update.py`. That hits the same CIPD/gs://
"linux-arm64 isn't a first-class target" issue we saw with
`gclient sync` earlier — chromium's clang prebuilts are x86_64-only
for many platforms.
- **(c)** Fork an older chromium (e.g., 132 or 138) that compiles
cleanly with clang 22. 7Ji's chromium-mpp PKGBUILD targets 132 and
builds clean on Arch ARM today. Loses 15 versions of upstream
chromium evolution but ships fast.
- **(d)** Patch chromium 147 to drop the offending flags
(`build/config/compiler/BUILD.gn` has the cflags lists). 50200 line
patch, brittle across version bumps but tractable. Fights every
rebase.
### Wall 2 — bundled x86_64 esbuild under qemu
After Wall 1 (or independently for Action targets):
`qemu-x86_64-static: Could not open '/lib64/ld-linux-x86-64.so.2'`
when chromium runs the bundled x86_64 `esbuild` from
`third_party/devtools-frontend/.../scripts/build/typescript/ts_library.py`.
Same shape as the bundled `node-linux-x64` issue we already fixed (we
symlinked system node into that path). `esbuild` needs the same
treatment — install system esbuild via `npm install -g esbuild` and
symlink it into the path chromium expects. Or install `qemu-user-static`
+ `glibc-x86_64` to make the bundled binary actually run.
**Wall 2 is much smaller than Wall 1** — a handful of bundled-x86_64
binaries to identify and replace, vs. fundamental clang version mismatch.
## What worked
- LXD container provisioning on boltzmann via his recommendation —
the host environment is right.
- Tarball-instead-of-gclient approach — sidesteps CIPD-doesn't-have-
linux-arm64 problem for source acquisition, leaves only a few
bundled binary issues at build time.
- Wall 1 / Wall 2 are both **identifiable and bounded**. We're past
the "is this even doable" phase; this is now down to grinding the
patches.
## Options — needs your call
1. **Grind through Wall 1 with patches** — patch
`build/config/compiler/BUILD.gn` to drop flags clang 22 doesn't
know. Iterate per build error. Estimated 515 patch-and-retry
cycles to compile clean. Then 610 h actual build.
2. **Pin to chromium 132** — match 7Ji's known-working version on
Arch ARM. Drop our STUDY focus on "current upstream Chromium" and
ship a 1-year-old binary. Build should work much sooner.
3. **Pin to chromium 138 or 140** — middle ground. Likely uses clang
22 features and not 23. Some research needed to find the cutover.
4. **Use chromium's bundled clang** — not viable on linux-arm64
without extensive sysroot setup; same CIPD issue as gclient sync.
5. **Wait for Arch ARM clang 23** — passive, days-to-weeks horizon.
Recommended (FWIW): **start with (3)** — find the latest chromium
version that builds clean against clang 22 (probably 138-141 range),
ship that as `chromium-fourier`, then bump as Arch ARM bumps clang.
That gives us a working browser in a few hours rather than days, on
mainline Linux + Wayland + V4L2 unlock — which is the actual goal.
The "current upstream Chromium" requirement was nice-to-have, not
essential.
## State of the build host (preserved)
- Container: `chromium-builder` on boltzmann (running, idle)
- Source: `/build/chromium/src` (extracted tarball, 25 GB)
- Build dir: `/build/chromium/src/out/Default` (gn-gen'd, no artifacts)
- Tools installed: gn, ninja, clang 22, lld, gperf, nodejs (system),
rust, qt5/6, all the gtk/wayland/va/v4l deps from the long pacman
shopping list
- Patches applied to source: `compiler-rt-adjust-paths` style (manual)
- Symlinks: `/usr/lib/clang/23``/usr/lib/clang/22`,
`third_party/node/linux/node-linux-x64/bin/node``/usr/bin/node`
- Service unit history: `chromium-fetch.service` (one-shot, succeeded
on tarball + extract); `chromium-build.service` (one-shot, three
failed attempts above).
Discard the container and start over with option 2 if you pick that
direction; otherwise iterate from current state.
## Pivot 2026-04-26 — cross-compile from x86_64
After the analysis above, the framing shifted. The real wall isn't
"Arch ARM clang 22 vs LLVM 23" — Arch x86_64 is also on llvm 22.1.3, no
LLVM 23 anywhere in extra/staging. The flags chromium 147 emits
(`-fno-lifetime-dse`, `-fsanitize-ignore-for-ubsan-feature=array-bounds`,
the `/usr/lib/clang/23/...` path) come from **chromium's clang fork**,
not upstream LLVM 23. Chromium ships its own LLVM with chromium-specific
passes; the "23" in the path is chromium-internal versioning.
Implication: PKGBUILD'ing clang 23 is the wrong tree. The right tree is
either pin to an older chromium (option 2 above) or **cross-compile from
an x86_64 host** so chromium's x86_64 bundled clang prebuilt is
reachable and `target_cpu="arm64"` produces the aarch64 binary cleanly.
Cross-compile sidesteps every wall we hit:
- CIPD has full `linux-amd64` prebuilts (the gap was `linux-arm64`)
- Chromium's bundled clang downloads cleanly on x86_64
- No qemu-x86_64-static dance for tools (host IS x86_64)
- `tools/clang/scripts/update.py` works as Google intends
- `gclient sync` works; no DEPS surgery needed
his provisioned a cross-build host for this on 2026-04-26:
- **CT 220 `chromium-builder-x86` on data**, x86_64 Ryzen 7 1700,
14 cores, 32 GiB RAM + 8 GiB swap, 200 GiB ZFS rootfs.
- Reach via `mcp__hub-tools__remote_shell host=hertz`
`ssh root@192.168.88.30` (data) → `pct exec 220 -- ...`
- `builder` user uid 1001, NOPASSWD sudo, `DisableSandbox` in pacman.conf.
Source fetch started 2026-04-26 05:45 UTC as transient unit
`chromium-fetch.service` on CT 220. Estimated 1-2 h for `fetch
--no-history chromium` over the LAN. Then `tools/clang/scripts/update.py`
to install chromium's bundled clang (x86_64 host, arm64 sysroot), then
`gn gen` with `target_cpu="arm64"` + cross-compile flags, then build.
The boltzmann `chromium-builder` LXD container is preserved as fallback
but no longer the active build host. If cross-compile pans out, that
container can be torn down.
## First runtime validation on ohm — 2026-04-26 22:26 UTC
Cross-compile produced a working aarch64 binary (chrome 647 MB ELF +
chrome_crashpad_handler 4.3 MB + .pak + locales). Tarball
`chromium-fourier-147.tar.gz` (226 MB) transferred CT 220 → hertz → ohm.
Launched in mfritsche's KWin Wayland session (tty2, panfrost render
node) playing `bbb_1080p30_h264.mp4` from file:// with
`LIBVA_DRIVER_NAME=v4l2_request`,
`LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video0`,
`--use-gl=egl --ozone-platform=wayland
--enable-features=VaapiVideoDecodeLinuxGL,AcceleratedVideoDecodeLinuxGL
--disable-features=UseChromeOSDirectVideoDecoder
--autoplay-policy=no-user-gesture-required`.
**Result: V4L2 path NOT engaged.** Chrome 147 routes the H.264 stream
through `MojoVideoDecoderService``media/filters/ffmpeg_video_decoder.cc`
(software FFmpeg). Renderer pegs at ~92 % CPU, `/dev/video0` is never
opened (`fuser` returns empty), no `V4L2VideoDecoder` /
`VaapiVideoDecoder` log lines appear at `--v=1
--vmodule="*/vaapi/*=2,*/v4l2/*=2,*video_decoder*=2,*media/gpu/*=2"`.
Compositor also fell back to software (`Switching to software
compositing.` even though panfrost render node was picked) — secondary
issue, separate from the codec wall.
**Conclusion**: 7Ji-style gn args (`use_v4l2_codec=true
use_v4lplugin=true use_linux_v4l2_only=true`) alone are insufficient
on chromium 147. The V4L2VideoDecoder factory is still gated behind
`BUILDFLAG(IS_CHROMEOS)``media/mojo/services/gpu_mojo_media_client_*.cc`
and `media/gpu/gpu_video_decode_accelerator_factory.cc` only register
the V4L2 path on ChromeOS targets.
## Validation pass 2 — 2026-04-26 22:38 UTC — V4L2VDA proven engaged
Two distinct issues were diagnosed and the codec one was fully resolved
without source surgery beyond a 2-line patch:
### Issue 1 — runtime master gate
`media::kAcceleratedVideoDecodeLinux` (user-visible feature name
"AcceleratedVideoDecoder") is hard-coded in
`media/base/media_switches.cc:750` to `FEATURE_ENABLED_BY_DEFAULT` only
when `BUILDFLAG(USE_VAAPI)` is set. On a USE_V4L2_CODEC-only build it
defaults DISABLED, the linux gpu_mojo_media_client returns
`VideoDecoderType::kUnknown`, and chrome silently falls back to
`media/filters/ffmpeg_video_decoder.cc`.
**Fix**: 2-line patch (now `patches/enable-v4l2-decoder-default.patch`):
```
-#if BUILDFLAG(USE_VAAPI)
+#if BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC)
```
The placeholder `chromeos-pipeline-bypass.patch` was deleted; PKGBUILD
now references the real patch. **Verified to apply cleanly on the CT 220
tree** (chromium 149 main).
### Issue 2 — bundled GL libs missing from tarball
The first runtime tarball shipped only `chrome` + `.pak` + locales +
`chrome_crashpad_handler`. It omitted `libEGL.so` / `libGLESv2.so`
(ANGLE) plus `libvk_swiftshader.so` and `libvulkan.so.1`. Without these,
the GPU process logs `gl::init::InitializeStaticGLBindingsOneOff failed`
and chrome falls into "Switching to software compositing." mode — which
*also* gates the V4L2 path off because the gpu_mojo_media_client never
gets a chance to dispatch.
Additionally, `--use-gl=egl` is rejected ("Requested GL implementation
gl=egl-gles2,angle=none not found in allowed implementations:
[(gl=egl-angle,angle=opengl|opengles|vulkan)]"): the build only allows
ANGLE-mediated paths. Right launcher invocation:
`--use-gl=angle --use-angle=gles`.
**Fix**: package the four libs alongside `chrome` and update the
launcher flag set. Both will be encoded in the next iteration of the
PKGBUILD's `package()` and a `chromium-fourier` launcher script.
### What we observed once both fixes were in place
With patch + bundled libs + `--enable-features=AcceleratedVideoDecoder`
+ `--use-gl=angle --use-angle=gles`, chrome on RK3566 hantro logs:
```
[gpu]: V4L2VideoDecoder()
[gpu]: Open(): No devices supporting H264 for type: 0 <- type=0 is single-planar; chrome retries multi-planar
[gpu]: InitializeBackend(): Using a stateless API for profile: h264 main and fourcc: S264
[gpu]: SetupInputFormat(): Input (OUTPUT queue) Fourcc: S264
[gpu]: AllocateInputBuffers(): Requesting: 17 OUTPUT buffers of type V4L2_MEMORY_MMAP
[gpu]: SetExtCtrlsInit(): Setting EXT_CTRLS for H264
[gpu]: SetupOutputFormat(): Output (CAPTURE queue) candidate: NV12
[gpu]: ContinueChangeResolution(): Requesting: 6 CAPTURE buffers of type V4L2_MEMORY_MMAP
[renderer]: OnDecoderSelected<video>: V4L2VideoDecoder
MediaEvent: "Selected V4L2VideoDecoder for video decoding,
config: codec: h264, profile: h264 main, [...]
coded size: [1920,1080], visible rect: [0,0,1920,1080]"
```
`fuser /dev/video1 /dev/media0` shows `chrome` (gpu pid) holding both
fds. The hantro stateless decoder is engaged. **First end-to-end
chromium-fourier V4L2 hardware decode validation: PASS** for H.264
1080p Big Buck Bunny on PineTab2.
Caveat: the render-side CPU was still ~85% during playback. Subsequent
investigation traced this to a different root cause than initially
guessed (see Pass 3 below).
## Validation pass 3 — 2026-04-26 22:50 UTC — zero-copy diagnosis
The 85 % CPU is **not** caused by software compositing or dmabuf v5
negotiation. The dmabuf-v5 warning ("Binding to zwp_linux_dmabuf_v1
version 4 but version 5 is available") is benign — chrome happily binds
to its supported max (v4). The `WaylandZwpLinuxDmabuf::OnTrancheFlags`
NOTIMPLEMENTED is also benign — KWin sends it, chrome ignores it, but
the substantive feedback (formats + modifiers) lands via
`OnTrancheFormats` / `OnTrancheTargetDevice` regardless.
Real cause: `gpu_feature_info.supports_nv12_gl_native_pixmap` ends up
**false** on this build. With it false, V4L2-decoded NV12 frames go
through the NV12-to-AR24 VPP conversion path (see
`media/mojo/services/gpu_mojo_media_client_linux.cc`
`GetPreferredRenderableFourccs` — without NV12 native pixmap support,
only `Fourcc::AR24` is added to the renderable set, forcing the VPP).
That's where the 85 % is spent.
Why is `supports_nv12_gl_native_pixmap` false?
`GLOzoneEGLWayland::CanImportNativePixmap` (in
`ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc`) requires the
chrome GL display to expose `EGL_EXT_image_dma_buf_import`. With
`--use-gl=angle --use-angle=gles`, chrome's GL display sits behind
ANGLE's EGL, and ANGLE's GLES backend on Linux does not propagate
`EGL_EXT_image_dma_buf_import` from the underlying mesa EGL up to its
clients. Verified directly: `EGL_PLATFORM=surfaceless eglinfo` on ohm
shows panfrost native EGL exposes both
`EGL_EXT_image_dma_buf_import` and `EGL_EXT_image_dma_buf_import_modifiers`
the capability is there at the panfrost layer, ANGLE just hides it.
We tried `--use-gl=egl` (direct EGL/GLES2, bypass ANGLE) but were
rejected with "Requested GL implementation (gl=egl-gles2,angle=none) not
found in allowed implementations". `WaylandSurfaceFactory::GetAllowedGLImplementations()`
in chromium 149 advertises only ANGLE-mediated impls; the
`kGLImplementationEGLGLES2` slot is missing from the list. The
`CreateViewGLSurface` dispatcher does still handle that impl — only the
*advertisement* was tightened.
### Patch 2/2 — `wayland-allow-direct-egl-gles2.patch`
3-line diff in `ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc`:
```
+ impls.emplace_back(gl::GLImplementationParts(gl::kGLImplementationEGLGLES2));
impls.emplace_back(gl::ANGLEImplementation::kOpenGL);
```
Re-allows the direct EGL/GLES2 path, ahead of the ANGLE entries so
chrome picks it by default. Verified to apply cleanly on the CT 220
tree; staged via `patch -p1` mid-rebuild (ninja's mtime-based rebuild
will pick up the change automatically).
### Outstanding for next pass (revised)
1. Rebuild lands → repackage with all four GL libs +
`chrome_crashpad_handler` + chrome → ship to ohm.
2. Validate via `chrome --use-gl=egl --ozone-platform=wayland`
`--enable-features=AcceleratedVideoDecoder` (no ANGLE shim) and
confirm `chrome://gpu` reports `Native GpuMemoryBuffers: true` and
`supports_nv12_gl_native_pixmap=true`. Target CPU during 1080p30 H.264
playback: under 30 % combined renderer + gpu.
3. If (2) passes, declare V1 of chromium-fourier shippable on ohm.
4. Add a `chromium-fourier` launcher shim under `/usr/bin/` that
defaults to `--use-gl=egl --ozone-platform=wayland`.
5. Sort the chromium 147 vs 149 confusion — the fetch went to ToT on
main rather than the 147 release branch. Either pin the branch or
accept that we're tracking ToT (probably preferable for V4L2 fixes
that are still in flight upstream).
6. Replicate end-to-end on RK3588 (ampere CoolPi or boltzmann Rock 5
ITX+) once the mainline VDPU381 driver is stable on those — those
boxes use **panthor** for Mali-G610 (Valhall), not panfrost; the
patches should be backend-agnostic but the validation is per-box.
### State of the build host (post pass 3)
- CT 220 `/build/chromium/src` patched with both
`enable-v4l2-decoder-default.patch` and
`wayland-allow-direct-egl-gles2.patch` (applied directly with
`patch -p1` mid-rebuild; ninja picks up the mtime change).
- `chromium-rebuild.service` running as a transient unit, output in
`/tmp/chromium-rebuild.log`. Most of the 93k ninja steps are cache
hits; only the patched files + their downstream objects need
recompiling.
- Tarball still on CT 220 at `/build/chromium-fourier-147.tar.gz`
(misleadingly named: it's actually 149.0.7812.0 from the main fetch,
not the 147 release tarball — separate cleanup for next pass) and on
hertz at `/tmp/chromium-fourier-147.tar.gz`. **Will be replaced by
the post-rebuild tarball once it lands.**
---
## 2026-04-28 — Patch 4 lands, KWin owns the residual stall
### Patch 4 — `nv12-external-oes-on-modifier-external-only.patch`
On panfrost / panthor, every NV12 modifier (LINEAR + AFBC ×2 + AFRC) is
flagged `external_only` in `eglQueryDmaBufModifiersEXT`. Chromium's
`OzoneImageGLTexturesHolder::GetBinding` only picked
`GL_TEXTURE_EXTERNAL_OES` when the SharedImageFormat carried
`PrefersExternalSampler` — which is set for the generic Linux multi-plane
case but **not** for V4L2 producers that arrive via the standard ozone
pixmap path. The frame then took the `GL_TEXTURE_2D` branch, ANGLE's
`validationES.cpp:4894` rejected the YUV EGLImage on a non-EXTERNAL_OES
target, the import failed, and the renderer fell back to the
NV12→AR24 software conversion (~131 % CPU baseline).
Patch closes the gap: also pick `EXTERNAL_OES` when the EGL driver
advertises the pixmap's modifier as `external_only` (cached per
`(fourcc, modifier)` tuple via a function-local
`base::flat_map`+`base::Lock`, so the EGL round-trip stays off the
per-frame hot path). Adds a single static helper
`NativePixmapEGLBinding::ModifierRequiresExternalOES`. ~+90 lines, zero
deletions, no shader changes (Skia Ganesh already handles
`GL_TEXTURE_EXTERNAL_OES` natively via `GrGLTextureInfo.fTarget`).
### Validation on ohm (RK3566 PineTab2 / hantro mainline 6.19.10)
- `bbb_1080p30_h264.mp4` plays clean, no garble, no decoder error
- Steady-state **34.7 % combined CPU** during 1080p30 H.264 (browser 12 +
GPU 9 + net 6 + render 6 + audio 1) vs v3 baseline ~131 % — **~3.8×
reduction**. Risk-1 (ANGLE+EXTERNAL_OES sampling regression on Skia
Ganesh / panfrost) **cleared**.
- `V4L2VideoDecoder()` constructor + `Using a stateless API for profile:
h264 main and fourcc: S264` confirmed in log; 6 CAPTURE buffers
V4L2_MEMORY_MMAP, NV12 output. 19 live dmabuf fds in GPU process
during steady playback — healthy V4L2 rotation + compositor depth, not
a leak.
### KWin 6.6.4 GL_ALPHA bug — separate, preexisting, blocks long playback
Across BOTH v3 (no patch 4) and v4 (with patch 4) chromium-fourier
builds, mid-playback the renderer + GPU process both park in
`futex_do_wait`, `<video>` element keeps its ⏸ icon, currentTime
advances on the audio clock, and audio outputs static (last ALSA buffer
recycled) then silence. No D-state, no v4l2/vb2/dma_fence wchan, no
error in `chrome-v[34].log`.
`journalctl` for `kwin_wayland`:
```
GL_INVALID_VALUE in glTexImage2D(internalFormat=GL_ALPHA)
GL_INVALID_OPERATION in glTexSubImage2D(invalid texture level 0) × N
```
First occurrence on this box: **2026-03-06**. KWin is requesting an
internal format that doesn't exist in modern GLES (`GL_ALPHA` is GLES1.x
legacy, not valid for `glTexImage2D` with GLES3 contexts). The
allocation fails, then every `glTexSubImage2D` to that texture errors at
level 0; KWin keeps retrying the same broken upload every frame, never
recovers. The frame-callback ack to wayland clients stalls → chrome's
renderer parks waiting for the present-feedback that never lands.
Patch 4 looks "guilty" only because of timing: with NV12 zero-copy, the
renderer is fast enough to actually post a v4l2-backed dmabuf within the
window where KWin's broken path runs; v3 was slow enough (NV12→AR24
software conversion) that the bug surfaced 510× later. **Triangulation:**
chrome v4 stalls + chrome v3 stalls + VLC `cannot convert decoder/filter
output` + mpv `could not initialize video chain` — every wayland video
client hits it; ffmpeg `-hwaccel v4l2request -f null` plays through
clean (decode path is healthy, the wall is the compositor's GL backend).
### Decoder-stack sanity post-reboot (2026-04-28 ~13:30)
After a reboot the V4L2 device numbering shuffled:
- `/dev/video0` = `rockchip,rk3568-vpu-dec` (hantro DEC, was video1)
- `/dev/video1` = `rockchip,rk3568-vepu-enc` (hantro ENC)
- `/dev/video2` = `rockchip-rga`
- `/dev/media0` = controller for DEC, `/dev/media1` = controller for ENC
Anything that hardcoded `/dev/video1` for decode now talks to the
encoder. Chrome and ffmpeg both handle this transparently (they enumerate
via media-ctl); mpv's `--hwdec=v4l2request` returns `Could not create
device` post-shuffle — separate mpv-side bug, not ours.
### Outstanding (revised, supersedes earlier list)
1. **Patch 4 lands publicly:** bump PKGBUILD `source=` and `prepare()`,
commit + tag a `chromium-fourier-149-r4` release on
`git@github.com:marfrit/chromium-fourier`.
2. **KWin pivot** — see `KWIN_PIVOT.md` (separate doc) for the plan to
identify and patch the `glTexImage2D(GL_ALPHA)` site, since ohm is the
only board on hand and every wayland video client is affected.
3. **Replication on ampere** (RK3588, panthor + rkvdec2 + hantro
multiplanar) — needs ampere woken; currently DOWN.
4. **firefox-fourier 150 build** — `firefox-fourier-150.0.1-1-aarch64.pkg.tar.zst`
is built (95 MB on workstation:/tmp/, sha256 acbf1870…), pending
fresnel power-on for V4L2 stateless validation on RK3399.