Table of Contents

Phase 2 — Situation Analysis (ohm_gl_fix iteration 1)

Substrate enumeration on ohm (PineTab2, RK3566, Mali-G52 MP2, hantro-vpu, kernel 6.19.10-danctnix1-1-pinetab2), 2026-04-30.

Phase 1 lock: Phase 1 goal formulation, 2026-04-30. Goal target: on bbb_1080p30_h264.mp4 with mpv –hwdec=v4l2request –vo=gpu-next over a 60 s steady-state window, drops drop from baseline 1039/1440 (72 %) into the gst v4l2slh264dec → waylandsink transient-startup floor — equivalently, EGLImage-import ceases to be the binding constraint.

This page is descriptive, not prescriptive. No plan here; the plan is Phase 4. If something below turns out to be the wrong thing to measure once Phase 3 baselines run, that's a Phase 3→1 loopback, not a Phase 2 revision.


1. Mesa version + panfrost build flags

2. EGL/GLES extensions advertised

EGL client extensions: EGL_EXT_client_extensions, EGL_EXT_device_*, EGL_EXT_explicit_device, EGL_EXT_platform_base, EGL_EXT_platform_{wayland,x11,xcb,device}, EGL_KHR_debug, EGL_KHR_platform_{gbm,wayland,x11}, EGL_MESA_platform_{gbm,surfaceless}.

EGL display extensions (panfrost, both GBM and Wayland) — selecting the ones load-bearing for this campaign:

What eglinfo does not report, and what we therefore still need before Phase 4 (so this is a Phase 3 baseline action, not a Phase 2 hole): the per-format modifier list returned by eglQueryDmaBufModifiersEXT(DRM_FORMAT_NV12) and the external_only flag for each modifier. That's the data point that decides whether a kernel-allocated dmabuf can flow into a regular 2D sampler in libplacebo's GL path or only into samplerExternalOES.

GL ES extensions are advertised at GLES 3.1 level — full extension string lives in eglinfo's GBM block; nothing surprising for a Mali-G52 panfrost build. es2_info cannot run from an SSH session without a display; the Wayland eglinfo GLES profile already covers the same ground.

3. V4L2 buffer-pool size on the hantro path

Probe: strace -f -e ioctl ffmpeg -hwaccel v4l2request -hwaccel_output_format drm_prime -i bbb_1080p30_h264.mp4 -frames:v 60 -f null - against /dev/video1 (hantro-vpu, mainline rockchip,rk3568-vpu-dec).

Result:

rotation — the hantro-VPU DPB just holds the frames longer than mpv's consumer would.

Implication for the campaign. A 60 s / 1440-frame run cycles each of the 9 dmabuf fds ≈160 times. The current gpu-next path treats every DQBUF as a new fd-into-EGLImage import; a cache keyed on fd identity collapses 1440 imports into 9. This is the upper bound on what fd-identity caching can save on this clip — useful as the Phase 3 prediction sanity-check.

4. mpv + libplacebo + which hwdec gpu-next loads

5. KWin / kwin_wayland version + startup GL spam

6. Known failure modes — consolidated

Inherited from the ohm_gl_fix README and the fourier Phase 5 page. Listed here so they don't get re-discovered later.

Success-transition lock-in

Numbers locking the journey from baseline to goal live in metrics.csv (sibling file). Four rows: phase1_baseline (138 % CPU, 1039/1440 drops, 72 %), phase1_reference and phase1_reference_fs (the gst→waylandsink floor: 6–7 % CPU, 0/1488 drops), and phase1_goal_target (post-warmup drops = 0; warmup = first 10 s with ≤ 10 drops tolerated). Binding cell is phase1_goal_target.drops_post_warmup; the drops cell carries the warmup sanity cap (10) so the path can't trivially satisfy “0 post-warmup” by stretching warmup. Phase 3 must decompose the baseline 1039 drops into warmup vs post-warmup before any Phase 4 prediction is made. Phase 3 and Phase 7 append rows; the role column distinguishes the metric from references. Loopback Phase 3 → Phase 1 (per dev-process) edits the goal_target row's binding cell rather than rewriting prose.

Locked metrics (success-transition)

Machine-readable lock — see metrics.csv in the repo for the editable source.

# ohm_gl_fix metrics — success-transition lock-in
# Phase 1 anchor + reference + goal target. Phase 3/7 add rows as they run.
#
# Schema:
#   phase             phase1_baseline | phase1_reference[_*] | phase1_goal_target
#                     | phase3_* | phase7_*
#   path_label        descriptive playback configuration
#   clip              source media file (sha16: dcf8a7170fbd49bb for bbb_1080p30_h264.mp4)
#   decoder           hantro-vpu | sw
#   vo_sink           mpv VO or GStreamer sink
#   surface_protocol  how decoded frames reach the compositor
#   cpu_pct           total %CPU (top -p style); empty = not the locked metric
#   drops             total dropped frames over window_s (warmup + steady-state)
#   frames_total      total frames considered (delivered + dropped) over window_s
#   drop_pct          100 * drops / frames_total
#   window_s          full measurement window in seconds
#   warmup_s          duration of pipeline warmup at window start; drops inside
#                     this sub-window are tolerated and are NOT a goal failure
#   drops_post_warmup dropped frames in the (warmup_s, window_s] sub-window;
#                     THIS is the binding metric for phase1_goal_target
#   effective_fps     delivered frames per second
#   role              metric=THE success criterion; reference=floor/control;
#                     context=informational
#   source            where this row's number came from
#   date              ISO date the number was taken
#
# Phase 1 prose goal (refined 2026-04-30): "0 drops after pipeline warmup —
# warmup = first 10 s; ~10 dropped frames during warmup is acceptable".
# Binding cell: phase1_goal_target.drops_post_warmup == 0.
# Sanity guard: phase1_goal_target.drops <= 10 (caps `drops` so the path
# can't satisfy `drops_post_warmup == 0` by extending the warmup forever).
# Phase 3 baseline must split phase1_baseline.drops into warmup vs post-warmup
# (the 1039 figure is total over 60 s — not yet decomposed).
phase,path_label,clip,decoder,vo_sink,surface_protocol,cpu_pct,drops,frames_total,drop_pct,window_s,warmup_s,drops_post_warmup,effective_fps,role,source,date
phase1_baseline,mpv_gpu_next_v4l2request,bbb_1080p30_h264.mp4,hantro-vpu,gpu-next,EGLImage_per_frame,138,1039,1440,72.0,60,10,,8.5,metric,ohm_gl_fix:README_L19,2026-04-30
phase1_reference,gst_v4l2slh264dec_waylandsink,bbb_1080p30_h264.mp4,hantro-vpu,waylandsink,linux-dmabuf-v1_direct,7,0,1488,0.0,62,10,0,24.0,reference,fourier:README_L189,2026-04-24
phase1_reference_fs,gst_v4l2slh264dec_waylandsink_fullscreen,bbb_1080p30_h264.mp4,hantro-vpu,waylandsink_fs,linux-dmabuf-v1_direct+VOP2_scale,6,0,1488,0.0,62,10,0,24.0,reference,fourier:README_L190,2026-04-24
phase1_goal_target,mpv_gpu_next_v4l2request_cached,bbb_1080p30_h264.mp4,hantro-vpu,gpu-next,EGLImage_cached_by_fd,,10,1440,0.69,60,10,0,24.0,metric,ohm_gl_fix:phase1_2026-04-30,2026-04-30

What's deliberately not in this page

References used in this enumeration