There may be no 30 fps lock at all -- the panel runs at 60 and ph-framprobe reports ~31 whether the screen is on or OFF
scope: device:google-taimen · severity: finding · confidence: proven · subsystem: display
The panel is at 60, the operator sees smooth scrolling, and the probe says 31 either way
Section: The panel is at 60, the operator sees smooth scrolling, and the probe says 31 either wayThe measurement. ph-framprobe.py against
/sys/kernel/debug/dri/c901000.display-controller/encoder-0/status, with the
panel verified on before AND after each run (bl_power=0,
card0-DSI-1/enabled=enabled) and idle blanking disabled:
run1 31.4 fps vsync +302 / 5 s = 60.4 vsync/srun2 32.1 fps vsync +349 / 5 s = 69.8 vsync/srun3 31.6 fps vsync +347 / 5 s = 69.4 vsync/sThat reads like two frames of display for every one the client is given. It is not safe to conclude that, and the operator caught why: phosh scrolls smoothly, which a genuine half-rate session does not.
THE PROBE REPORTS THE SAME ~31 fps WITH THE PANEL SWITCHED OFF. Four runs
taken against a blanked screen gave 28.3/31.5/30.8/31.9 while vsync did not
move at all and both display IRQs (msm, dsi_isr) were frozen. A number
that does not change when the display stops existing is not measuring the
display. So ~31 is what this probe produces on this device, and the session’s
real rate is not known from it.
What IS established: the panel delivers ~60 vsync/s under load, and the operator reports smooth scrolling. There may be no session-wide half-rate lock to explain.
What this rules out, each measured on the same boot:
- Power policy. The whole suspend-era set is armed – TZ LMH, the a540
on-die limiter, the vendor energy model, schedutil at
rate_limit_us=2000. The die was 39 C and the GPU sat at its lowest OPP (257 MHz of 710 available) because the load is trivial. Nothing was throttling anything. - mesa. Measured across the fork rebase, 26.2.3-r0 stock and 26.2.3-r52 with all four a5xx patches. Same rate.
- The GTK renderer.
glandngl, interleaved, twice, on both mesa builds. 31.0/31.6 against 31.9/31.8. No difference outside noise. - The two things that fixed this once.
0204-drm-msm-dpu-cmd-mode-send-the-pageflip-event-at-rd_p.patchis in the shipping series and in the tree, andFD_MESA_DEBUG=sysmemis not set anywhere in the session. Those are the pair that the-session-is-back-to-30fps-on-7-2-and-ctl-start-is-not-why measured at 57.7 fps. Both present, and the rate is back at half.
THE TRAP THAT COST THIS SESSION MOST OF AN HOUR, and it is not new.
A blanked panel still delivers frame callbacks. On a screen that is OFF the
probe reports ~31 fps – indistinguishable from the real half-rate number
– while vsync and both display IRQs (msm, dsi_isr in
/proc/interrupts) do not move at all. Four figures were taken that way after
a reboot and had to be retracted. With the panel genuinely mid-wake the same
probe reports 2.5-2.8 fps, which is also not a real number.
So: no frame-rate figure on this device means anything unless the panel
state is read from the kernel either side of the run, and the DPU’s vsync
counter is sampled across it. bl_power/enabled for the first,
encoder-0/status for the second. This is the same law as
taimen-touch-test-discipline, one subsystem over.
Idle blanking has to be disabled for the duration or it lands mid-run:
gsettings set org.gnome.desktop.session idle-delay 0.
RESOLVED, same session. The probe’s own paint is the limiter. A control window with the identical tick callback and NO damage, run the same minute against the same compositor and panel:
tickonly (frame clock, no damage) 58.6 / 59.3 fpsph-framprobe (clock + its repaint) 30.4 / 30.5 fpsThe frame clock hands out 60. The probe halves it with the per-tick CSS class swap, which forces a restyle and repaint of the widget every frame. There is no session-wide 30 fps lock, which is exactly what the operator saw by scrolling the phone while the probe claimed otherwise.
ph-framprobe.py now runs that control BY DEFAULT and prints the verdict
itself:
control (no damage) = 59.0 fpsframes=151 over 5.0s = 30.1 fpsTHIS PROBE is the limiter: the clock offered 59 fps and the damaged runreached 30. Not a session frame-rate result.Every historical figure from this tool measures its own paint cost, not the session – including the 57.7 fps in the-session-is-back-to-30fps-on-7-2-and-ctl-start-is-not-why. That number may still mean something as a RELATIVE comparison between two configurations measured the same way, but it was never a session frame rate.
Two tool bugs found on the way, both live:
-
ph-session.sh wakepresses power twice without re-reading the panel between presses, so on a phone that woke on the first press it blanks it again and then reportspanel still off after two power presses. A singleph-key.py powerworks. -
Several tools (
ph-session.sh,ph-chromium-videoarm.sh,ph-webarm.sh,ph-videoarm.sh,ph-scrollarm.sh) require/tmp/sess.shexporting the session environment, and nothing creates it. A reboot clears/tmp, after which every one of them fails withcan't open /tmp/sess.sh. It can be rebuilt from the compositor’s own environ:P=$(pgrep -x phosh); sudo tr '\0' '\n' < /proc/$P/environ |grep -E '^(WAYLAND_DISPLAY|XDG_RUNTIME_DIR|DBUS_SESSION_BUS_ADDRESS|XDG_CURRENT_DESKTOP)=' |sed 's/^/export /' > /tmp/sess.sh
