evdi icon indicating copy to clipboard operation
evdi copied to clipboard

Add support for gamma ramp

Open dol opened this issue 7 years ago • 24 comments

When using a tool like RedShift the gamma ramp via randr is modified. It would be nice if this feature could be added. Is this even possible?

dol avatar Sep 27 '16 22:09 dol

It has been one year now. Any word on this feature request?

i2000s avatar Oct 24 '17 07:10 i2000s

I bought a USB display based on DisplayLink chipset 41xx (Mobile Pixels Duex). I was surprised how easy the initial setup was on Ubuntu 18.04, but the lack of brightness control is a major problem.

So after looking into the discussions on the internet as I can see, DisplayLink doesn't implement a proper I2C interface for these controls, it is even emulated by the driver on Windows. No MCCS. The only option would be to implement the software gamma control for the framebuffer interface.

  1. Do I understood right that the DisplayLink drivers use the modesetting driver on the xorg side? This driver lacked gamma controls, but it is at least fixed in the master after this bug fix:

https://bugs.freedesktop.org/show_bug.cgi?id=104811

I patched my xorg, xrandr changes the brightness/gamma values in the driver, but no effect on the actual DisplayLink screen.

  1. Obviously, after the modesetting driver is enabled for the gamma control, it still does not work because it is not implemented in libevdi and the kernel driver. I checked how usually the drm kernel drivers for different chipsets work, but I found that almost all the time they call some hardware register what is not available for DisplayLink. I added the minimal support in the kernel driver, but I don't set gamma value for the device:
diff --git a/module/evdi_modeset.c b/module/evdi_modeset.c
index 73ee271..6125956 100644
--- a/module/evdi_modeset.c
+++ b/module/evdi_modeset.c
@@ -176,6 +176,7 @@ static struct drm_crtc_helper_funcs evdi_helper_funcs = {
 };
 
 static const struct drm_crtc_funcs evdi_crtc_funcs = {
+       .gamma_set              = drm_atomic_helper_legacy_gamma_set,
        .reset                  = drm_atomic_helper_crtc_reset,
        .destroy                = evdi_crtc_destroy,
        .set_config             = drm_atomic_helper_set_config,
@@ -395,6 +396,11 @@ static int evdi_crtc_init(struct drm_device *dev)
        EVDI_DEBUG("drm_crtc_init: %d p%p\n", status, primary_plane);
        drm_crtc_helper_add(crtc, &evdi_helper_funcs);
 
+       uint gamma_lut_size = 256;
+
+       drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size);
+       drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size);
+
        return 0;
 }
  1. My current suspicion that the only possible way to implement the gamma controls to catch the crtc events in libevdi by

void (crtc_state_handler)(int state, void user_data);

And do the gamma modification of the pixels in evdi_grab_pixels() ?

  1. If I am in a very wrong path, if you just give some directions where is the right place to apply software gamma correction after the xorg filled a buffer, but before it is passed to the device, it would be appreciated. I read all the documentation, but it is not completely clear how the actual framebuffer is painted and passed to the device inbetween xorg <-> kernel drm <-> kernel udl <-> kernel evdi driver <-> libevdi <-> binary DisplayLink blob <-> actual device.

@displaylink-mlukaszek @displaylink-dkurek Please can you comment?

kecsap avatar Feb 27 '19 08:02 kecsap

Hi @kecsap

  1. Yes, we suggest to use modesetting driver as we found out that it is the most stable to use with EVDI. Good to know they are adding gamma ramps support :)

  2. To be honest I don't know how other drivers do the gamma correction. Can you provide some link so I could take a look? From this patch it seems that drm should handle it by itself? Probably not as the color corrections are meant to be applied by the monitor.

  3. According to https://lwn.net/Articles/660329/

  1. To set color correction values, userspace: a. creates a blob using the create_blob_ioctl in standard palette_correction structure format, with the correction values b. calls the set_property_ioctl with the blob_id as value for the property
  2. Driver refers to the blob, gets the correction values and applies the correction in HW.

So it should be in property, also driver should be notified that it has been set/modified/removed.

grab_pixels would be probably good place to do it in SW on the module side. Best only on the rects we copy to userspace.

  1. So the path is xorg <-> kernel drm <-> kernel evdi driver <-> libevdi <-> DisplayLinkManager <-> device The UDL driver is fully kernel side driver for DisplayLink USB 2.0 devices and isn't in use for USB 3 or EVDI.

Let me start from where not to put it ;) libevdi is the worst place for it as it is simply thin layer between kernel and userspace. Good start would be kernel module, as you already said evdi_grab_pixels seems to be good place. Later if we want to move it to userspace (or device) we would need to add a way to pass it through libevdi. Probably as a notification, similarly as e.g. evdi_cursor_set is done.

displaylink-dkurek avatar Feb 28 '19 07:02 displaylink-dkurek

I for one will never voluntarily use any screen without ramping the color temperature way down. DisplayLink on Linux not supporting this is an immediate no. Sad to see this issue lying around here for so long.

reitzig avatar Aug 27 '19 18:08 reitzig

@reitzig Especially, my DisplayLink monitor does not even support color temperature changes on Windows. You can change only the brightness and contrast via a 3rd party app what is funny.

kecsap avatar Aug 27 '19 18:08 kecsap

@reitzig Especially, my DisplayLink monitor does not even support color temperature changes on Windows. You can change only the brightness and contrast via a 3rd party app what is funny.

Ugh, that sucks. The screens I've tried all behave as expected when connected directly to my laptop via HDMI.

reitzig avatar Aug 27 '19 18:08 reitzig

@reitzig You must use DisplayLink monitor only if you have a specific need. E.g. powering and connecting a monitor with a single cable. Anyway these monitors are a compromise because streaming the screen updates to the device cause CPU load while this is no-op via HDMI cable.

kecsap avatar Aug 27 '19 19:08 kecsap

@kecsap Yea well, the idea of using the monitor effectively as docking station is an attractive one. There are models that act as KVM switch already (if via separate cables); add charging via USB-C and WiFi and you get a workable home- or shared-office solution.

But this is besides the point. As far as I can tell, there is no technical reason why changing gamma/temperature couldn't be supported through DisplayLink. It's just that it hasn't been implemented.

reitzig avatar Aug 27 '19 19:08 reitzig

Another year later, is there any new support for this? The fact that redshift is not supported is really hurting my eyes ...

@displaylink-mlukaszek @displaylink-dkurek

~ Joe G.

JPGlaser avatar Nov 17 '20 20:11 JPGlaser

This is also a popular issue in the display link forums: https://support.displaylink.com/forums/287786-displaylink-feature-suggestions/suggestions/20221153-allow-gamma-custom-ranges-in-the-ubuntu-driver-to

JohannesBe avatar Mar 08 '21 08:03 JohannesBe

hi there! Any plans to include this request? Thanks!

cdonatom avatar Nov 30 '21 17:11 cdonatom

FYI: here's the AMD's implementation -> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

I am taking a quick look to implement this on Displaylink but no guarantees, it lies out of my expertise.

cdonatom avatar Dec 01 '21 15:12 cdonatom

hi there! Any plans to include this request? Thanks!

@cdonatom It's not like we don't want to. We're being stretched thin and there's a bunch of different projects/priorities. I'll bring it up. Although, there's a few features I'd like to see more. :)

displaylink-emajewsk avatar Dec 02 '21 06:12 displaylink-emajewsk

@cdonatom It's not like we don't want to. We're being stretched thin and there's a bunch of different projects/priorities. I'll bring it up. Although, there's a few features I'd like to see more. :)

Thx, I am taking a look at this taking as reference the AMD driver. I am not sure if I will be able to implement it since my knowledge about DRM infra is near 0 :) It'll take too much of my spare time to have something functional. It would be more than welcome if you guys can do it, as far as I can see, doing it in the proper way, you can even enable HDR since everything is based on color management.

Thanks again!

cdonatom avatar Dec 02 '21 08:12 cdonatom

fwiw, gnome-shell allows to change RGB values of any window. There is even an extension which inverts colors https://github.com/jackkenney/gnome-true-color-invert

I modified that extension's extension.js to set window colors to e.g. 4000K c = vec4( c.r , c.g*0.82854786 , c.b*0.64816570 , c.a); //4000K

For other temperatures, this table can be consulted: https://askubuntu.com/questions/1003101/how-to-use-xrandr-gamma-for-gnome-night-light-like-usage/1061304#1061304

Now, I click Super+I on a window on my USB-connected displaylink monitor and its colors are adjusted and my eyes are grateful.

themighty1 avatar Feb 07 '22 17:02 themighty1

fwiw, gnome-shell allows to change RGB values of any window.

i gave a try to kwin recently and was disappointed, because i think only inverting of individual windows worked, not inverting of whole screens. It's the same with what you're describing, correct? When you right-click something, how is a pop-up menu rendered?

Do you have the desktop theme set to a dark taskbar + dark window decorations?

And how does gnome-shell handle multiple monitors these days? Last time i checked it was a disaster.

And any idea how well it supports focus-follows-mouse these days ? :)

koo5 avatar Feb 10 '22 19:02 koo5

yes, it is the same here - only per window RGB change. all pop up menus are not changed, unfortunately. I only keep one window fullscreen with a dark theme on displaylink monitor.

I know that gnome-shell still doesnt have 1 monitor per 1 workspace, so all monitors are always on the same workspace. This is annoying when you press the Super button and the preview is shown on all monitors.

themighty1 avatar Feb 10 '22 20:02 themighty1

i gave a try to kwin recently and was disappointed, because i think only inverting of individual windows worked, not inverting of whole screens. It's the same with what you're describing, correct? When you right-click something, how is a pop-up menu rendered?

On Ubuntu 20.04 inverting the color of all screens works fine under KDE. I have enabled it under System Settings -> Desktop effects -> Invert .

zoltanp avatar Feb 11 '22 09:02 zoltanp

On Ubuntu 20.04 inverting the color of all screens works fine under KDE.

Thanks. turns out that it's just finicky/buggy about keyboard shortcuts, but the functionality itself works

koo5 avatar Feb 12 '22 01:02 koo5

Hi guys, it has been 7 years since this issue was created. Is there any update? I am willing to fund this issue.

skopz356 avatar Jul 17 '23 19:07 skopz356

I'm willing to add to the funding of this issue. Can we get any update?

Soheilsdgh avatar Jul 28 '23 03:07 Soheilsdgh

I am also willing to fund this issue!

k8e avatar Aug 11 '23 15:08 k8e

I am willing to fund too.

vggscqq avatar Nov 29 '23 21:11 vggscqq

Hi guys, if some of you are using gnome. I changed the gnome-true-color extension, so it works almost as night shift. (It applies that filter on every window even popup etc) https://github.com/skopz356/gnome-true-color-invert

skopz356 avatar Feb 12 '24 21:02 skopz356