I have found many methods related to dithering in the scaler driver: AppleM2ScalerCSCDriver.
AppleM2ScalerCSCDriver is the driver for the M2 Scaler (scaler + Color Space Converter). This is a separate block in the Apple Silicon SoC that sits between the GPU and the TCON.
GPU -> DCP -> M2 Scaler (CSC) -> TCON -> panel
In AppleM2ScalerCSCDriver, I discovered several classes:
DitherControl
DitherControlMSR
DitherControlMSR4, MSR7, MSR8.
And a couple of interesting methods:
DitherControlMSR8::setDither_gatedContext(M2ScalerCSCRequest*)
DitherControlMSR8::isDitherUseful(M2ScalerCSCRequest*)
What MSRX means is also unclear for now - versions of registers?
A probe placed on isDitherUseful does not trigger:
sudo dtrace -n 'fbt::*isDitherUseful*:entry { trace("isDitherUseful called"); }'
So for some reason, the method is not being called by anyone. Perhaps it is called once during OS startup? But I cannot place a probe at such an early boot stage.
On my M1, this driver is loaded:
kmutil showloaded | grep com.apple.driver.AppleM2ScalerCSCDriver
94 4 0xfffffe0007430280 0x372ad 0x372ad com.apple.driver.AppleM2ScalerCSCDriver (265.0.0) 08FBC36A-1F8D-3B82-9210-05A7910BAACA <41 35 27 7 6 5 4 3 1>
Also, there is an interesting line in the driver:
"Quadra Bayer: Setting Dither Clamp registers to max \n"
This tells us that there are hardware registers for dithering. "Clamp" might control the dithering amplitude, and this log line could mean that the maximum possible amplitude is set. But I believe it's not FRC, it's spatial dithering.
So we are seeing hardware-level dithering control.
In AppleM2ScalerCSCDriver, there is a IOKit registry property: EnableFiltersNoRewriteMode. By default, it is False. I don't know what it means. But its value can be changed.
Update
As soon as I started watching a video on YouTube, calls to isDitherUseful and setDither_gatedContext started appearing: isDitherUseful returned zero, meaning dithering is not being applied in this case. But when I played the video in QuickTime, isDitherUseful started returning one.
The client of AppleM2ScalerCSCDriver is not only WebKit/QuickTime, but also WindowServer. WindowServer is the window compositor - it handles the composition of the GUI interface. But probes showed that there wasn't a single call from WindowServer the entire time - only from video players.
I need to take a closer look at the code of the MSR classes.