jordan unfortunately I don't have access to a true 10-bit panel (unless you count the built-in display if that turns out to be true). If anyone here has a Pro Display XDR you'll do us a real solid comparing it to the image of an M2/M3 Max/Pro, at least it will tell us they use the same tech.

    @aiaf I've just reproduced how dithering works with different type of cables and external monitor with StillColor on/off. Making a video, will post in hour or two.

    Looks very promising

    aiaf this is exceptional. I've suspected quality chabges between cables before. Maybe there is a flag or value where we can pick up the negotiated bandwidth or info about what is active. I looked into creating a tool to continously diff parts of ioreg to show deep changes as they happen, but didn't find enough time yet. I looked around in some other places as well, and there are lots of info. Do ioreg with the -a flag to output xml and more easily see deeper hierarchical values that are mostly there for debugging.

    What I don't get is the many references to bitdepth 8 for the built in monitor.

    Not sure, but I guess other interference from power cables might also be capable of affecting the bandwidth.

    • aiaf replied to this.

      async Diffing is essential, thanks for the -a flag tip. I planned to do it for this investigation but I thought I'd post my initial findings first. Regarding Depth in the registry, it's not what you think it means.

      Depending on where it appears, the known values are 4 and 8 (you can confirm this by looking at AllRez source code). Mine was set to 7 at some point in the past couple of months- not sure how or why or if it was me who did it.

      • DepthFormat = 8 => PixelEncoding = "--RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB"
      • DepthFormat = 4 => PixelEncoding = "--------RRRRRRRRGGGGGGGGBBBBBBBB"

      So a depth format of 8 means 10bpc

        aiaf I created a continous diff solution. It's a starting point and can be adapted to other interesting areas. Finally got a working conversion of the data to json, so I used a json diff that also makes it easy enough to see where things changed.

        Just created it, so didn't test anything yet, but you can see the AmbientBrightness changing live for example. I'm sure there are areas where you can monitor things related to the cable bandwith as well that can be found thru IORegistryExplorer.

        This script needs jd for the diffing, so run brew install jd first, and then more or less just sh iodiff.sh

        #!/bin/bash
        
        CMD="ioreg -l -d0 -w0 -r -c AppleCLCD2 -a \
        | sed -e '/^\t*<data>/,/^\t*<\/data>/ { /^\(\t*\)<data>\(.*\)/ { s//\1<string>_data:\2/; h; d; }; /^\t*<\/data>\(.*\)/! { s/^\t\(.*\)/\1/; H; d; }; /^\t*<\/data>\(.*\)/ { s//\1:data_<\/string>/; H; g; s/\n//g; }; }' \
        | plutil -convert json -r - -o -"
        SLEEP_TIME=5
        
        OLD_FILE="/tmp/iodiff_old.json"
        NEW_FILE="/tmp/iodiff_new.json"
        
        # Initialize both files before starting the loop
        eval "$CMD" > "$OLD_FILE"
        cp "$OLD_FILE" "$NEW_FILE"
        
        print_heading() {
          echo "\033[1m$1\033[0m"
        }
        
        print_heading "$(date)"
        cat "$OLD_FILE"
        echo ""
        
        while true; do
          eval "$CMD" > "$NEW_FILE"
          OUTPUT=$(jd -color "$OLD_FILE" "$NEW_FILE")
          if [ ! -z "$OUTPUT" ]; then
            print_heading "$(date +"%Y-%m-%d %H:%M:%S")"
            echo "$OUTPUT"
          fi
          mv "$NEW_FILE" "$OLD_FILE"
        
          sleep "$SLEEP_TIME"
        done

          I discovered today accidentally that when I'm connecting MBA M3 to my Asus VG27AQ 2K monitor with HDMI the banding on gray gradient is changing when I'm turn on and off StillColor app. Attaching photos of display.

          I was surprised to see this, because I was always using DisplayPort to connect to my external display. So after that I tried the same again with my regular displayport, nothing changed, the banding stayed the same as with on or off.

          So after that I was thinking maybe the HDMI I have is lower version which could not give a proper bandwidth for 2K 10bit 144hz. So I took 2.1 version from my PS5 (I hope PS5 goes with 2.1 version tho) and tried, and I again saw a banding when StillColor was ON. After that I also realized that my monitor support only 2.0 version of HDMI. I also tried to connect with some type-c dongles, so in all cases HDMI was showing those banding when StillColor was ON.

          After that I went to the store to find any DisplayPort with version 1.1, but its too outdated, I think it was in years 2005-2008 so probably only on ebay I can order it for testing. So right now there is no way I can try older version, I have only 1.2.

          Conclusion from my side:

          • MBA M3 + StillColor ON 144hz with HDMI 2.0 -> External display: ✅ shows banding
          • MBA M3 + StillColor ON 60hz with HDMI 2.0 -> External display: ❌ doesn't show banding
          • MBA M3 + StillColor ON 144hz with DisplayPort 1.2 -> External display: ❌ doesn't show banding
          • MBA M3 + StillColor ON 60hz with DisplayPort 1.2 -> External display: ❌ doesn't show banding

          Photos for 2k 60hz with HDMI and StillColor on/off:

          As you can see when I'm enabling 60hz with 2K display there is no banding on gradient, which means that the cable have enough bandwidth to send 10bit 2K signal for 60hz, but could not send 144hz and switching to 8bit. But I don't understand why I'm able to control it with StillColor app only at 144hz, is it like because the bandwidth like almost on the edge or so and the MacOS letting you do this? Or is this how HDMI implementation works right now? I remember before M1 macbooks had problems with HDMI, using old version of it.

          Also when connecting monitor with HDMI in settings I can select 1920 as HiDPI, but when connecting with DisplayPort I have only 1280 as HiDPI. Weird, don't know why. And If I select 1920 with displayport the image is blurry in compare with HDMI.

          From the feelings perspective, In situation when I can see bandings I'm getting weird symptoms, even more weird than when just working with laptop screen. I'm getting strange brain fog and eye strain, also slight nausea and it comes and goes away, very weird. Its also very bad when looking at this gray gradient. Hopefully this information would help somehow 🙂

            madmozg Totally yeah I get that, I just meant that sometimes no OEM screens yield different (usually worse) results then OEM. Basically there's no crazy increased flashing or dithering, same as before, also the display doesn't appear to be a sRGB/RGB/6 bit +FRC etc as you might think from a cheaper panel.

            Not really related because it PWM but for example swapping a iPhone 13 mini I had from OEM OLED to LCD got rid of the PWM, with some draw backs. Also changing my iPhone 12 mini, no PWM at max brightness, to LCD got rid of the annoying dithering they added in iOS 17.

              madmozg

              I know folks here don't trust the microscope/camera method but it would be really interesting to know if you could upload microscope footage for each of these different cases. I found similar things with banding and testing a windows PC and a LG 4k monitor with different bandwidth cables.

              Not sure if this is helpful (details about TCON and FRC)
              https://tsuhuai.wordpress.com/2015/04/20/lcd-timing-controller-tcon-design/

              async Here is a version of the script that does not stream outputs.
              So that means you can run sh iodiff.sh, change some cable or thing, then run iodiff.sh again to see what changed. It should probably target some other places as well, or diff some of the AllRez output, but it's a starting point to try to work out what actually happens in different circumstance.

              #!/bin/sh
              
              CMD="ioreg -l -d0 -w0 -r -c AppleCLCD2 -a \
              | sed -e '/^\t*<data>/,/^\t*<\/data>/ { /^\(\t*\)<data>\(.*\)/ { s//\1<string>_data:\2/; h; d; }; /^\t*<\/data>\(.*\)/! { s/^\t\(.*\)/\1/; H; d; }; /^\t*<\/data>\(.*\)/ { s//\1:data_<\/string>/; H; g; s/\n//g; }; }' \
              | plutil -convert json -r - -o -"
              
              OLD_FILE="/tmp/iodiff_old.json"
              NEW_FILE="/tmp/iodiff_new.json"
              
              # Execute command and save output to NEW_FILE
              eval "$CMD" > "$NEW_FILE"
              
              # Compare OLD_FILE and NEW_FILE if OLD_FILE exists
              if [ -f "$OLD_FILE" ]; then
                OUTPUT=$(jd -color "$OLD_FILE" "$NEW_FILE")
                if [ ! -z "$OUTPUT" ]; then
                  echo "$OUTPUT"
                fi
              fi
              
              # Move NEW_FILE to OLD_FILE for next comparison
              mv "$NEW_FILE" "$OLD_FILE"

                madmozg Banding looks like the banding I have (not on a Mac) when in YCbCr mode. If you change it to RGB in the settings, the banding will go away.

                Hi,

                Thanks op for the program

                I installed it on my new M3 Air, but unfortunetaly i still have mild headache

                I use SRGB color profile, 80% light, and this program (it installed very easily), and i made sure it's running with the command you gave

                Do you think i can adapt ? I have no problem with Lenovo Thinkpad with IPS panel, Dell monitor etc

                • aiaf replied to this.

                  MTNEYE did you test the mini iPhone under a microscope to verify no dithering ?

                    jordan no I did not, but it was verifiable to me by sight after heavy use. Felt like old iphone 6s

                    async this is great. I ended up diffing only the AllRez output for the time being, most of the changes are in the preferred timing modes and their ordering, but it's not useful for figuring actual color depth used.

                    madmozg try this calculator and see the effective bandwidth used by your configuration. Switching to 144Hz should more than double the required bandwidth hence why it falls back to 8bpc. Use BetterDisplay to adjust gamma/contrast in Image Adjustments. You should see drastic and chaotic changes in banding/band count if it's in true 8bpc.

                    aiaf I'd like to make one correction to these findings, the change in Lagom gradient banding observed in the undithered 8bpc signal is detected by adjusting software brightness/gamma/contrast using BetterDisplay. Otherwise, it's not necessarily 128 bands in 8bpc. Whereas on a 10-bit (8-bit+FRC) image, the 256 band count does not change or behave erratically with brightness/contrast/gamma adjustments. Thanks to @DisplaysShouldNotBeTVs for this tip.

                    This does not change my conclusion regarding bit depth being affected by cable choice.

                    Request

                    Can anyone with an M2 Air note or videotape their observations re. banding behavior and count with dithering disabled and through adjusting software brightness, gamma, and contrast?

                    riverandsea How long have you been using the app for? We're starting to suspect the all these Apple display panels have another dithering layer that's driven by the TCON on the display. Stillcolor still disables the DCP-controlled dithering, so ideally you should be getting less eyestrain with this app than without.

                      The Lagom banding gradient has become a key tool in figuring out what is going on. The problem is, the Lagom gradient is outdated. It is encoded at 8-bit, and as such is only meant to show dithering support for up to 8-bits. We are trying to determine 8-bit+FRC and higher.

                      So I went down a rabbit hole with this and programmed a new, more sophisticated test gradient. It is a ladder of gradients rendered from 1-bit to 12-bit, without spatial dithering. All encoded to a 16-bit PNG image.

                      Download and open with a non-dithering image viewer to see what bit depth your system supports. Zoom in as needed. Each higher bit level splits the color of the lower bit level into two colors. Find the highest level where you can see each lower color band split in two. With visible banding separation between the two new colors. Safari seems to cap out at 8-bit when rendering this image, so you need to download the image directly from Imgur, or drag and drop the embedded image below to your machine. Then view in Preview.app.

                      Download on imgur

                      When viewing with Preview.app on my MacBook Pro 16" M1, I can just barely make out the banding divisions at the 10-bit level. Stillcolor does not increase or decrease the level. But enabling Stillcolor does reveal some vertical waves of color in the upper right (high bit depth) portions of the test image. I think I could argue these waves appear magenta and cyan. I think every level takes on this slight wavy color cast, but the effect is most noticeable in the upper right.

                      Hopefully my test image can help sort some of this out!

                        Hopefully I get to test on an eizo cg2700x soon. Not sure if it is true 10 bit or not.
                        update: will test backlight. Others who are photographers have similar eizo monitor and didn't like the PWM.

                        I took a brief look at MacBooks at the store today passing by the table they were on.

                        I don't remember the text size being so small before. If you have never changed the size of the UI and wear glasses, you might want to think about doing so.

                        • aiaf replied to this.
                          dev