Troubleshooting blue-and-yellow banding on GIFs across a dual-screen setup
| Item | Notes |
|---|---|
| Document type | Troubleshooting Report |
| Date of the hunt | 2026-11-01 |
| Target | Blue-and-yellow banding on GIF images in a Windows 10 dual-screen setup |
| Final state | Root cause located, verification experiments passed |
1. Background
1.1 The symptom
Playing or displaying particular animated GIFs on the secondary screen (the HDMI external monitor) produced blue-and-yellow streaky artefacts, visually an abnormal colour overshoot on hard chroma edges; moving the window to the internal screen weakened the banding until it vanished.
1.2 Environment
| Item | Configuration |
|---|---|
| Form factor | Laptop (internal screen + HDMI external secondary) |
| Internal screen | LG LP156WFG-SPP1 (eDP direct), 1920×1080 @ 144Hz |
| Secondary screen | Lanlip HC-L156A (IPS panel, 1080P 60Hz, HDMI), 1920×1080 @ 60Hz |
| GPU | NVIDIA RTX 2060 (driver 32.0.16.2101, HDMI 2.0) |
| OS | Windows 10 (Build 19045) |
| Layout | Side by side (internal on the right, secondary on the left), tops aligned; secondary at (-1920, 0), internal at (0, 0) |
2. Details of the reproduction
- With the GIF window on the secondary screen, clear blue-and-yellow banding artefacts appear.
- Taking a screenshot of the secondary screen still shows the banding; viewing that screenshot on the internal screen, the banding is still there.
- That proves the banding has been encoded into the pixel data itself, rather than being a transient effect at the physical display level.
- Dragging the GIF's window to the internal screen (144Hz, 125% scaling), the banding visibly weakens until it disappears.
- The same content behaving so differently once the window crosses screens says the problem is strongly tied to the difference in rendering/compositing between the two screens.
3. The investigation (layer-by-layer elimination)
Layer 1: ruling out the physical layer — the banding lives in the pixels
Action: screenshot the secondary screen's image and view that screenshot on the internal screen.
Conclusion: the banding reproduces on the internal screen too, so the anomaly happens at the pixel data layer (rendering/compositing) and has nothing to do with the secondary panel, its ribbon cable, the HDMI cable or signal degradation at the connector. Physical-layer possibilities eliminated.
Layer 2: checking the output colour configuration (colour format / bit depth / dynamic range)
Checked both screens' output colour paths through the registry (the Configuration key), EDID and QueryDisplayConfig:
| Check | Internal (eDP) | Secondary (HDMI) | Verdict |
|---|---|---|---|
| Pixel format | 32bpp RGB (PixelFormat=21 / ColorBasis=2) | 32bpp RGB (PixelFormat=21 / ColorBasis=2) | identical |
| Pixel clock | 346.5 MHz (1080p144) | 148.5 MHz (standard 1080p60 CEA timing) | bandwidth ample |
| EDID bit-depth declaration | VideoInput=0xA5, bit-depth field=5 (no 10bit declared, so 8bit+FRC) | VideoInput=0x80, bit-depth field=0 (no deep colour declared, 8bit by default) | nothing abnormal |
| Colour compression | none | none (1080p60 needs far less bandwidth than HDMI 2.0 allows, so there is no trigger for a passive drop to YCbCr 4:2:0) | bandwidth compression eliminated |
Conclusion: both screens output full RGB; the secondary shows no sign of YCbCr 4:2:0 / 4:2:2 or a limited dynamic range. The three actual display values on the advanced display settings page cannot be read through the system API, so I checked them by hand and confirmed they were not the direction of the root cause.
Layer 3: ruling out an HDR / WCG misdetection
| Check | Internal (eDP) | Secondary (HDMI) | Verdict |
|---|---|---|---|
| EDID HDR static metadata (CTA-861-HDR) | none | none (128-byte base block, no extension block) | neither declares HDR |
| EDID Features | standard sRGB / RGB444 / YCbCr444 | 0xEE: sRGB / RGB444 / YCbCr444 | standard gamut only |
| System AdvColor / HDR / ColorPrimaries / Bpc registry entries | none | none | no trace of HDR being enabled |
| ICC/ICM binding | only the system-level D65.camp and gmmp | same, no per-monitor ICC binding | no wide-gamut/custom profile bound |
Conclusion: neither Windows nor the driver sees the secondary as an HDR/WCG display, and the system has not enabled the advanced colour path, so an HDR/WCG misdetection is ruled out.
Info
This secondary does not support HDR colour modes to begin with, so that conclusion is within expectations.
Layer 4: ruling out an NVIDIA colour override
Queried the driver class key (HKLM\...\Class\{4d36e968-...}\0001), the Session / VolatileSettings subkeys and HKCU\Software\NVIDIA Corporation:
Result: no colour override of any kind in the registry (no ColorFormat / RGB / YCbCr / Range / Depth / DigitalVibrance values), so nothing has explicitly set the secondary to YCbCr / 4:2:0 / 4:2:2 or a limited output range, and the driver should be on the default full-range RGB path.
Conclusion: no abnormal override on NVIDIA's output colour path. Ruled out.
Layer 5: checking the EDID capabilities
- The secondary's EDID only declares sRGB / RGB444 / YCbCr444 capability bits, with no deep colour, no HDR and no wide gamut, so it is a standard-gamut device just like the internal screen.
Conclusion: at the level of EDID declarations the two screens do not differ, so a conflict between the screens' declared colour capabilities is ruled out.
Layer 6: the DPI scaling difference (the breakthrough)
| Item | Internal (eDP, primary) | Secondary (HDMI/HC-L156A) |
|---|---|---|
| System scaling percentage | 125% | 100% |
| Corresponding DPI value | 120 | 96 |
| Registry storage | DpiValue=0 under the internal screen's PerMonitorSettings key (falls back to the system default) | not stored separately |
Per-monitor scaling state confirmed:
Win8DpiScaling = 0→ the system does not force "all displays use the same scaling", so per-screen scaling is in effect;DpiScalingVer = 4096 (0x1000)→ using the newer per-monitor DPI scheme (per-monitor DPI).
Finding: the two screens' scaling values disagree (125% vs 100%), and moving a window across screens triggers DPI re-layout and a switch of compositing path. That difference lines up in time and in position with the banding, which established it as the direction of the root cause.
4. Root cause
With per-monitor DPI (independent per-display scaling) enabled, the two screens' actual DPI scaling disagrees (internal 125% / secondary 100%), which changes the cross-screen compositing path.
The mechanism:
- When a window moves across screens, Windows DWM (Desktop Window Manager) has to composite the content across two different scaling ratios;
- A GIF is by nature a low-resolution, low-bit-depth indexed-colour bitmap with few levels, so the colour transition edges are hard chroma boundaries;
- When DWM resamples that kind of low-bit-depth bitmap at a different ratio, the sampling kernel produces overshoot / ringing artefacts at the hard chroma edges, and the overshoot in the blue and yellow channels stacks up into blue-and-yellow banding;
- The GIF's low resolution and low bit depth act as an amplifier of that resampling distortion, but are not the root cause. The real trigger is the mismatch in DPI scaling between the screens plus the change of cross-screen compositing path.
In one line: with per-monitor DPI, showing a low-bit-depth bitmap on screens with different scaling ratios makes DWM's resampling produce ringing artefacts at hard chroma edges, which on particular GIFs shows up as blue-and-yellow banding.
5. Verification experiments
| Experiment | Action | Result |
|---|---|---|
| Experiment 1 | Set the secondary's system scaling to 125%, matching the internal (125%) | after the change the banding on the secondary disappeared |
| Experiment 2 | Keep both screens at the same scaling (125%) and drag the GIF window back and forth across screens | the banding no longer appears, the cross-screen compositing path is back to normal |
| Experiment 3 (regression) | Set the secondary's scaling back to 100% | the banding came back |
Conclusion: experiments 1 and 2 confirm that "matching the DPI scaling of both screens" makes the banding disappear, and experiment 3 makes it come back, so the causal chain is closed.
6. Impact and advice
- Workaround: keep the secondary at 125% scaling to match the internal screen, and the artefact is gone completely; it costs almost nothing and does not affect daily use.
- Regression risk: set the secondary back to 100% and the banding returns — that is expected behaviour, not a new fault.
- For future hunts: under the same physical conditions, if you run into "colour overshoot / ringing artefacts when the same content is shown across screens, and the content is a low-resolution, low-bit-depth bitmap (GIF, thumbnail, etc.)", check first whether the two screens' DPI scaling matches, and only then consider physical factors such as gamut and cables.
Appendix: comparison table of the key data
| Dimension | Internal (eDP / LG LP156WFG-SPP1) | Secondary (HDMI / HC-L156A) | Any difference |
|---|---|---|---|
| Resolution / refresh rate | 1920×1080 @ 144Hz | 1920×1080 @ 60Hz | refresh differs (timing only) |
| Pixel clock | 346.5 MHz | 148.5 MHz | different bandwidth source, both ample |
| Output pixel format | 32bpp RGB | 32bpp RGB | none |
| EDID HDR/WCG declaration | none | none | none |
| EDID bit-depth declaration | field=5 (8bit+FRC) | field=0 (8bit default) | declarations differ, actual output does not |
| NVIDIA colour override | none | none | none |
| ICC binding | system-level default | system-level default | none |
| System scaling | 125% (120 DPI) | 100% (96 DPI) | yes (where the root cause lies) |
| per-monitor DPI | enabled (DpiScalingVer=4096 / Win8DpiScaling=0) | same | none (both screens are governed) |
Note
85% of this content was generated by Marvis calling an LLM; it has been proofread by hand, but is still for reference only
Important
This article was translated by Hermes Agent; the original text can be found at here. The translation is for reference only. Translation time: 2026-11-05
