LG OLED with a Linux computer: Getting that pitch black
Introduction
So I got myself an LG OLED65B9. It’s huge and a really nice piece of electronics. I opted out the bells and whistles, and connected it via HDMI to my already existing media computer, running Linux Mint 18.1. All I wanted was a plain (yet very high quality) display.
However at some point I noticed that black wasn’t displayed as black. I opened GIMP, drew a huge black rectangle, and it displayed as dark grey. At first I thought that the screen was defective (or that I was overly optimistic expecting that black would be complete darkness), but then I tried an image from a USB stick, and reassured myself that black is displayed as complete darkness. As it should. Or why did I pay extra for an OLED?
Because I skipped the “play with the new toy” phase with this display, I’m 100% it’s with its factory settings. It’s not something I messed up.
I should mention that I use plain HD resolution of 1920x1080. The screen can do much better than that (see list of resolutions below), and defaults at 3840x2160 with my computer, but it’s quite pointless: Don’t know about you, I have nothing to show that goes higher than 1080p. And the computer’s graphics stutters at 4k UHD. So why push it?
I have a previous post on graphics modes, and one on the setup of the Brix media center computer involved.
So why is black displayed LCD style?
The truth is that I don’t know for sure. But it seems to be a problem only with standard 16:9 graphics modes. When switching to modes that are typical for computers (5:4 and 4:3 aspect ratios), the image was stretched to the entire screen, and black areas showed as pitch black. I’m not sure about this conclusion, and even less do I have an idea why this would happen or why a properly designed display would “correct” a pixel that arrives as RGB all zeros to something brighter.
Also, the black level on text consoles (Ctrl-Shift-F1 style) is horrible. But I’m not sure about which resolution they use.
An idea that crossed my mind is that maybe the pixels are sent as YCbCr in some modes or maybe the computer goes “Hey, I’m a TV now, let’s do some color correction nobody asked for” when standard HDTV aspect ratios are used. If any, I would go for the second possibility. But xrandr’s verbose output implies that both brightness and gamma are set to 1.0 for the relevant HDMI output, even when black isn’t black.
The graphics adapter is Intel Celeron J3160′s on-chip “HD Graphics” processor (8086:22b1) so nothing fancy here.
Update, 24.2.21: It actually seems like there’s an explanation. The computer uses the i915 module on a Linux kernel 4.4.0-53-generic. Why is that important? Well, look at the output of xrandr below. It says “Broadcast RGB: Automatic”. That means that the color range is set automatically by the driver. And indeed one of the options is “Limited 16:235″ which means that the darkest black is actually level 16 out of 255, as mentioned here, and passionately discussed here and here.
The automatic mode was added to the driver in kernel commit 55bc60db5988c8366751d3d04dd690698a53412c.
The interesting part seems to be this change in drivers/gpu/drm/i915/intel_hdmi.c (became drivers/gpu/drm/i915/display/intel_hdmi.c later):
+ if (intel_hdmi->color_range_auto) { + /* See CEA-861-E - 5.1 Default Encoding Parameters */ + if (intel_hdmi->has_hdmi_sink && + drm_mode_cea_vic(adjusted_mode) > 1) + intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; + else + intel_hdmi->color_range = 0; + }
The call to drm_mode_cea_vic() apparently says, that if there’s a known Video Identification Code (VIC) for the timing parameters in use (i.e., there’s a standard mode corresponding what is used), then the limited color range is applied. Why? Because. I don’t know if this was fixed since.
Thanks to Nate Long for pointing out the discussions on the kernel module.
The fix
This just worked for me, and I didn’t feel like playing with it further. So I can’t assure that this is a consistent solution, but it actually seems that way.
The idea is that since the problem arises with standard 16:9 modes, maybe make up a non-standard one?
Unlike the case with my previous TV, using cvt to calculate the timing parameters turned out to be a good idea.
$ cvt 1920 1080 60 # 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz Modeline "1920x1080_60.00" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync $ xrandr -d :0 --newmode "try" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync $ xrandr -d :0 --addmode HDMI3 try $ xrandr -d :0 --output HDMI3 --mode try
At this point I got a proper 1920x1080 on the screen, with black pixels as dark as when the display is powered off. The output of xrandr after this was somewhat unexpected, yet functionally what I wanted:
$ xrandr -d :0 --verbose
1280x720 (0x4b) 74.250MHz +HSync +VSync +preferred h: width 1280 start 1390 end 1430 total 1650 skew 0 clock 45.00KHz v: height 720 start 725 end 730 total 750 clock 60.00Hz 1920x1080 (0x141) 173.000MHz -HSync +VSync *current h: width 1920 start 2048 end 2248 total 2576 skew 0 clock 67.16KHz v: height 1080 start 1083 end 1088 total 1120 clock 59.96Hz 1920x1080 (0x10c) 148.500MHz +HSync +VSync h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.50KHz v: height 1080 start 1084 end 1089 total 1125 clock 60.00Hz [ ... ] try (0x13e) 173.000MHz -HSync +VSync h: width 1920 start 2048 end 2248 total 2576 skew 0 clock 67.16KHz v: height 1080 start 1083 end 1088 total 1120 clock 59.96Hz
So the mode in effect didn’t turn out the one I generated (“try”), but a replica of its parameters, marked as 0x141 (and 0x13a on another occasion). This mode wasn’t there before.
I’m don’t quite understand how this happened. Maybe Cinnamon’s machinery did this. It kind of gets in the way all the time, and at times it didn’t let me set just any mode I liked with xrandr, so maybe that. This whole thing with graphics modes is completely out of control.
I should mention that there is no problem with sound in this mode (or any other situation I tried). Not that there should be, but at some point I thought maybe there would be, because the mode implies a computer and not a TV-something. But no issues at all. Actually, the screen’s loudspeakers are remarkably good, with a surprisingly present bass, but that’s a different story.
As for making this special mode permanent, that turned out to be a problem in itself. This post shows how I eventually solved it.
List of graphics modes
Just in case this interests anyone, this is the output of a full resolution list:
$ xrandr -d :0 --verbose
[ ... ]
HDMI3 connected primary 3840x2160+0+0 (0x1ba) normal (normal left inverted right x axis y axis) 1600mm x 900mm
Identifier: 0x48
Timestamp: -1469585217
Subpixel: unknown
Gamma: 1.0:1.0:1.0
Brightness: 1.0
Clones:
CRTC: 0
CRTCs: 0
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
EDID:
00ffffffffffff001e6da0c001010101
011d010380a05a780aee91a3544c9926
0f5054a1080031404540614071408180
d1c00101010104740030f2705a80b058
8a0040846300001e023a801871382d40
582c450040846300001e000000fd0018
781e871e000a202020202020000000fc
004c472054560a20202020202020012d
02035af1565f101f0413051403021220
212215015d5e6263643f403209570715
07505707016704033d1ec05f7e016e03
0c001000b83c20008001020304e200cf
e305c000e50e60616566eb0146d0002a
1803257d76ace3060d01662150b05100
1b304070360040846300001e00000000
0000000000000000000000000000008b
aspect ratio: Automatic
supported: Automatic, 4:3, 16:9
Broadcast RGB: Automatic
supported: Automatic, Full, Limited 16:235
audio: auto
supported: force-dvi, off, auto, on
3840x2160 (0x1ba) 297.000MHz +HSync +VSync *current +preferred
h: width 3840 start 4016 end 4104 total 4400 skew 0 clock 67.50KHz
v: height 2160 start 2168 end 2178 total 2250 clock 30.00Hz
4096x2160 (0x1bb) 297.000MHz +HSync +VSync
h: width 4096 start 5116 end 5204 total 5500 skew 0 clock 54.00KHz
v: height 2160 start 2168 end 2178 total 2250 clock 24.00Hz
4096x2160 (0x1bc) 296.703MHz +HSync +VSync
h: width 4096 start 5116 end 5204 total 5500 skew 0 clock 53.95KHz
v: height 2160 start 2168 end 2178 total 2250 clock 23.98Hz
3840x2160 (0x1bd) 297.000MHz +HSync +VSync
h: width 3840 start 4896 end 4984 total 5280 skew 0 clock 56.25KHz
v: height 2160 start 2168 end 2178 total 2250 clock 25.00Hz
3840x2160 (0x1be) 297.000MHz +HSync +VSync
h: width 3840 start 5116 end 5204 total 5500 skew 0 clock 54.00KHz
v: height 2160 start 2168 end 2178 total 2250 clock 24.00Hz
3840x2160 (0x1bf) 296.703MHz +HSync +VSync
h: width 3840 start 4016 end 4104 total 4400 skew 0 clock 67.43KHz
v: height 2160 start 2168 end 2178 total 2250 clock 29.97Hz
3840x2160 (0x1c0) 296.703MHz +HSync +VSync
h: width 3840 start 5116 end 5204 total 5500 skew 0 clock 53.95KHz
v: height 2160 start 2168 end 2178 total 2250 clock 23.98Hz
1920x1080 (0x1c1) 297.000MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 135.00KHz
v: height 1080 start 1084 end 1089 total 1125 clock 120.00Hz
1920x1080 (0x1c2) 297.000MHz +HSync +VSync
h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 112.50KHz
v: height 1080 start 1084 end 1094 total 1125 clock 100.00Hz
1920x1080 (0x1c3) 296.703MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 134.87KHz
v: height 1080 start 1084 end 1089 total 1125 clock 119.88Hz
1920x1080 (0x16c) 148.500MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.50KHz
v: height 1080 start 1084 end 1089 total 1125 clock 60.00Hz
1920x1080 (0x1c4) 148.500MHz +HSync +VSync
h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 56.25KHz
v: height 1080 start 1084 end 1089 total 1125 clock 50.00Hz
1920x1080 (0x16d) 148.352MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.43KHz
v: height 1080 start 1084 end 1089 total 1125 clock 59.94Hz
1920x1080i (0x10c) 74.250MHz +HSync +VSync Interlace
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 33.75KHz
v: height 1080 start 1084 end 1094 total 1125 clock 60.00Hz
1920x1080i (0x10d) 74.250MHz +HSync +VSync Interlace
h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 28.12KHz
v: height 1080 start 1084 end 1094 total 1125 clock 50.00Hz
1920x1080 (0x1c5) 74.250MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 33.75KHz
v: height 1080 start 1084 end 1089 total 1125 clock 30.00Hz
1920x1080 (0x1c6) 74.250MHz +HSync +VSync
h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 28.12KHz
v: height 1080 start 1084 end 1089 total 1125 clock 25.00Hz
1920x1080 (0x1c7) 74.250MHz +HSync +VSync
h: width 1920 start 2558 end 2602 total 2750 skew 0 clock 27.00KHz
v: height 1080 start 1084 end 1089 total 1125 clock 24.00Hz
1920x1080i (0x10e) 74.176MHz +HSync +VSync Interlace
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 33.72KHz
v: height 1080 start 1084 end 1094 total 1125 clock 59.94Hz
1920x1080 (0x1c8) 74.176MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 33.72KHz
v: height 1080 start 1084 end 1089 total 1125 clock 29.97Hz
1920x1080 (0x1c9) 74.176MHz +HSync +VSync
h: width 1920 start 2558 end 2602 total 2750 skew 0 clock 26.97KHz
v: height 1080 start 1084 end 1089 total 1125 clock 23.98Hz
1280x1024 (0x1b5) 108.000MHz +HSync +VSync
h: width 1280 start 1328 end 1440 total 1688 skew 0 clock 63.98KHz
v: height 1024 start 1025 end 1028 total 1066 clock 60.02Hz
1360x768 (0x4b) 85.500MHz +HSync +VSync
h: width 1360 start 1424 end 1536 total 1792 skew 0 clock 47.71KHz
v: height 768 start 771 end 777 total 795 clock 60.02Hz
1152x864 (0x1ca) 81.579MHz -HSync +VSync
h: width 1152 start 1216 end 1336 total 1520 skew 0 clock 53.67KHz
v: height 864 start 865 end 868 total 895 clock 59.97Hz
1280x720 (0x110) 74.250MHz +HSync +VSync
h: width 1280 start 1390 end 1430 total 1650 skew 0 clock 45.00KHz
v: height 720 start 725 end 730 total 750 clock 60.00Hz
1280x720 (0x111) 74.250MHz +HSync +VSync
h: width 1280 start 1720 end 1760 total 1980 skew 0 clock 37.50KHz
v: height 720 start 725 end 730 total 750 clock 50.00Hz
1280x720 (0x112) 74.176MHz +HSync +VSync
h: width 1280 start 1390 end 1430 total 1650 skew 0 clock 44.96KHz
v: height 720 start 725 end 730 total 750 clock 59.94Hz
1024x768 (0x113) 65.000MHz -HSync -VSync
h: width 1024 start 1048 end 1184 total 1344 skew 0 clock 48.36KHz
v: height 768 start 771 end 777 total 806 clock 60.00Hz
800x600 (0x115) 40.000MHz +HSync +VSync
h: width 800 start 840 end 968 total 1056 skew 0 clock 37.88KHz
v: height 600 start 601 end 605 total 628 clock 60.32Hz
720x576 (0x116) 27.000MHz -HSync -VSync
h: width 720 start 732 end 796 total 864 skew 0 clock 31.25KHz
v: height 576 start 581 end 586 total 625 clock 50.00Hz
720x576i (0x117) 13.500MHz -HSync -VSync Interlace
h: width 720 start 732 end 795 total 864 skew 0 clock 15.62KHz
v: height 576 start 580 end 586 total 625 clock 50.00Hz
720x480 (0x118) 27.027MHz -HSync -VSync
h: width 720 start 736 end 798 total 858 skew 0 clock 31.50KHz
v: height 480 start 489 end 495 total 525 clock 60.00Hz
720x480 (0x119) 27.000MHz -HSync -VSync
h: width 720 start 736 end 798 total 858 skew 0 clock 31.47KHz
v: height 480 start 489 end 495 total 525 clock 59.94Hz
640x480 (0x11c) 25.200MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.50KHz
v: height 480 start 490 end 492 total 525 clock 60.00Hz
640x480 (0x11d) 25.175MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.47KHz
v: height 480 start 490 end 492 total 525 clock 59.94Hz
720x400 (0x1cb) 28.320MHz -HSync +VSync
h: width 720 start 738 end 846 total 900 skew 0 clock 31.47KHz
v: height 400 start 412 end 414 total 449 clock 70.08Hz
So it even supports fallback mode with a 25.175 MHz clock if one really insists.