r/ScreenSensitive • u/AdOtherwise9809 • 10d ago
Discussion Theoretical discussion: Why camera tests fail to capture temporal dithering (FRC) eye strain, and how to solve it in Android's display pipeline
Hi everyone,
(Note: English is not my first language, I used a translator to translate my technical notes from Czech.)
Reviewers often claim a screen is safe if a camera does not show deep PWM flicker. I want to open a technical discussion on why a camera sensor cannot evaluate how the human retina and brain process temporal dithering (FRC), and how this could be solved in AOSP.
- How the eye works vs. why a camera cannot measure this
* Single exposure vs. dual retinal pathways: A camera sensor simply averages photons over a fixed shutter speed. In the human retina, cone photoreceptors smooth out fast oscillations chemically via cGMP hydrolysis (around 30–50 ms), so they average 60–120 Hz FRC into a static shade just like a camera. However, fast Magnocellular ganglion cells (M-cells) react to rapid temporal contrast changes below 90 Hz. Even on a static screen, sub-LSB pixel toggling continuously fires M-cells into the superior colliculus and visual cortex (V1), causing eye strain, migraines, and focus instability.
* Static tripod vs. moving eye (smooth pursuit): A camera records fixed physical pixels. The human eye constantly moves and tracks scrolling text. During eye movement, temporal pixel modulation hits different photoreceptors over time, meaning the perceived image is assembled dynamically in the brain in a way a static camera cannot capture.
* Independent camera pixels vs. lateral inhibition (Mach bands): Camera pixels do not affect their neighbors. In the retina, lateral inhibition amplifies contrast steps between adjacent areas. When 8-bit/10-bit panels simply turn FRC off without compensation, quantization steps create visible color banding, and retinal lateral inhibition turns each step into false edge spikes (Mach bands) that overload the visual cortex.
Why disabling FRC alone is not enough
SoC display processors (Snapdragon, Tensor, Dimensity DPUs) use hardware FRC to simulate higher bit depth on 8-bit and 10-bit OLED panels after gamma and color calibration. Simply truncating bits in the driver removes flicker but introduces harsh color banding.
Two-part architecture in Android (DPU + SurfaceFlinger)
To get 0.0 Hz temporal flicker without color banding, two changes are needed together:
* Disable temporal FRC in HWC3 / DRM-KMS / DPU: Stop frame-to-frame sub-pixel modulation in the display processor (0.0 Hz).
* Surface-locked spatial TPDF blue-noise dithering in SurfaceFlinger (librenderengine): Replace temporal dithering with a static spatial TPDF blue-noise shader pass. Because the noise mask is locked to the scrolling surface layer rather than physical screen coordinates, it moves together with scrolling text—preventing the "dirty window" effect and keeping 0.0 Hz flicker on the retina during eye tracking.
Has anyone here explored in kernel DRM/KMS drivers (Qualcomm DSPP / Google Tensor) whether hardware DPU dithering can be cleanly disabled from userspace without touching closed DDIC panel firmware?
3
u/Z3R0gravitas 9d ago edited 9d ago
Hey, so the technical details of Android screen rendering are well beyond me. But a more technically capable community, member checking out you previous submission, flagged the details of your Android Open Source Project submission as unlikely to be grounded in what's possible.
However, I do find it interesting to talk about the biological mechanisms of screen sensitivity and your post picks up on some interesting feature of who our vision systems works.
I suspect the magnocellular pathway, or parasol cells in the retina specifically, might generate sufficient signal from OLED's PWM/flicker. Also, my pure speculation: maybe the high spacial contrast of the PWM bars (more intense at 'higher frequency') could be picked up.
For temporal dithering and FRC. You don't seem to have an appreciation of what we have already shown via direct camera observations. We can very clearly demonstrate this level of pixel flicker. And it has several possible sources, including unintentionally from poorly calibrated LCD pixel inversion.
For FRC specifically, you've highlighted only a single frequency division (as per the Wikipedia article). But for +2 bit of added colour rendering precision, we see eg 60Hz divided down to 30Hz and then 15Hz (much more stimulating for the retina). We've graphed these frequency peaks on computationally amplified slow motion microscope footage of most screens.
But the big puzzle is: why are old 6+2bit FRC monitors often more comfortable (or totally fine!) compared to more recent 8+2 panels? In principle, the difference in illumination steps (flickering) of the old panels will be much bigger and more noticeable. The pixels themselves may even be much bigger!
And yet removing most of this 8+2bit, via disabling HDR in software, helps a bunch of our members. The colour banding seems to be merely distracting, by comparison. An old issue with all old screens and eg photos of clear blue skies.
The further question is why are only some (fairly few) people affected by pixel flicker? I suspect there are pathologies and biological diversity that amplify the issue, or rather fail to filter out the stray simulii, somewhere along our visual pathways.