Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Empty discovered displays #72

Closed
fflores97 opened this issue Apr 26, 2023 · 3 comments
Closed

[Bug]: Empty discovered displays #72

fflores97 opened this issue Apr 26, 2023 · 3 comments

Comments

@fflores97
Copy link

Steps for reproducing the issue

Hi, I'm not able to see my displays on the Discovered displays array when running wluma. At first I thought it might be permissions-related so I added my user to the video and i2c groups such that running ddcutil detect shows:

Display 1
   I2C bus:  /dev/i2c-6
   DRM connector:           card0-DP-1
   EDID synopsis:
      Mfg id:               LEN - Lenovo Group Limited
      Model:                LEN T2224dA
      Product code:         ********
      Serial number:        ********
      Binary serial number: *******
      Manufacture year:     2019,  Week: 26
   VCP version:         2.2

Display 2
   I2C bus:  /dev/i2c-9
   DRM connector:           card0-DP-3
   EDID synopsis:
      Mfg id:               LEN - Lenovo Group Limited
      Model:                G27q-20
      Product code:         ******
      Serial number:        *******
      Binary serial number: *********
      Manufacture year:     2021,  Week: 31
   VCP version:         2.2

(I've crossed out some info)

Since I can see this without sudo I'm wondering what's going on that the ddc Rust code can't read the output. Would love any help!

What is the buggy behavior?

Cannot find displays

What is the expected behavior?

Something like Discovered displays: ["SERIAL_NUMBER"]

Logs

RUST_LOG=debug wluma

[2023-04-26T06:55:31Z DEBUG wluma] Using Config {
        als: Time {
            thresholds: {
                7: "dark",
                9: "dim",
                18: "dark",
                20: "night",
                0: "night",
                13: "bright",
                11: "normal",
                16: "normal",
            },
        },
        output: [
            DdcUtil(
                DdcUtilOutput {
                    name: "card0-DP-3",
                    capturer: Wlroots,
                    min_brightness: 1,
                },
            ),
        ],
    }
[2023-04-26T06:55:31Z DEBUG wluma::brightness::ddcutil] Discovered displays: []
[2023-04-26T06:55:31Z WARN  wluma] Skipping 'card0-DP-3' as it might be disconnected: Unable to find display
[2023-04-26T06:55:31Z INFO  wluma] Continue adjusting brightness and wluma will learn your preference over time.

Version

4.2.0-1 through AUR/yay

Environment

lsb_release -a; uname -a; pgrep -l sway; pacman -Q | egrep "(wlroots|vulkan|sway|clang|rust)"; dpkg -l | egrep "(wlroots|vulkan|sway|clang|rust)"

LSB Version:	n/a
Distributor ID:	EndeavourOS
Description:	EndeavourOS Linux
Release:	rolling
Codename:	rolling
Linux my-pc 6.2.12-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 20 Apr 2023 16:11:55 +0000 x86_64 GNU/Linux
clang 15.0.7-2
clang-format-static-bin 9.1d7ec53d-1
lib32-vulkan-icd-loader 1.3.245-1
vulkan-headers 1:1.3.246-1
vulkan-icd-loader 1.3.245-1
@fflores97
Copy link
Author

Hi again, would love some help with this

@maximbaz
Copy link
Owner

maximbaz commented May 6, 2023

Hey, sorry for the lack of response. The truth is, ddc part of the project is driven entirely by community and folks like you, I'll do my best to guide you but I have no way to test or reproduce things.

Your log Discovered displays: [] means that at this point here, there are no displays discovered:

log::debug!(
"Discovered displays: {:?}",
displays.iter().map(|(name, _)| name).collect_vec()
);

There are two activities that lead to the creation of that list:

  1. Enumerating the displays:

let displays = ddc_hi::Display::enumerate()
.into_iter()

  1. Filtering them by the ones that can report their capabilities:

.filter_map(|mut display| {
display.update_capabilities().ok().map(|_| {

The first idea would be for you to check if the empty list is already produced at step 1, or the first step finds your displays, only to be discarded at the second step. Could you try to figure this out, for example by adding some log lines?

In the former case, I'm not sure if it's actually solvable, but judging by the fact that you are able to use ddcutil, my bet is on the latter case.

There were some reasons for adding the filter, one that I remember was that a docking station can report several outputs, one for each input port it has, regardless of whether there was any display plugged into them, and all those reported displays were indistinguishable except for one interesting case: update_capabilities was failing for all "fake" outputs, and succeeding for the real plugged ones. Getting the capabilities obviously serves us another purpose, of actually getting the make and model of the screen.

If it is the update_capabilities that is failing on your devices, it would be interesting to perform two additional experiments:

  1. Get the specific error. .ok() eats the error, but you can use e.g. unwrap() to let the app crash and print the error to stderr.
  2. See if you can comment out the update_capabilities code altogether, make that function return the display (for example, keep only one screen connected, and make that function return the first element of displays unconditionally, without any filters), and see if wluma is actually able to operate with it (it's quite likely, that wluma can't get capabilities of your screens, it will also fail to update the brightness value...).

I hope this (untested) code could be a good starting point for you:

let displays = ddc_hi::Display::enumerate();
log::debug!("Enumerated: {:?}", displays);

let displays = displays.into_iter()
        .filter_map(|mut display| {
            display.update_capabilities().unwrap(); // this will crash and show you the error
            let empty = "".to_string();
            let merged = format!(
                "{} {}",
                display.info.model_name.as_ref().unwrap_or(&empty),
                display.info.serial_number.as_ref().unwrap_or(&empty)
            );
            Ok((merged, display))
        })
        .collect_vec();

return Some(displays[0].1);

A completely different idea is for you to have a look into https://gitlab.com/ddcci-driver-linux/ddcci-driver-linux - I haven't used this either, I like the idea of it allowing wluma to not use ddc-specific code, but a recent report mentions that the driver is possibly not working anymore.

Let me know how it goes or if you struggle with anything!

@fflores97
Copy link
Author

Thank you for your input!

Unfortunately, it seems like the problem is in the enumeration of displays. Something as simple as

ddc_hi::Display::enumerate().len()

returns a value of 0, so we never even go into the filter_map. Every other experiment I tried points to the same thing. This is way beyond the scope of what you can do for me, so no worries, it's clearly not a problem with wluma. There must be something funky in the way ddc is interacting with the kernel, maybe at the ddc_hi Rust library level, or maybe deeper down the dependencies.

Either way, thank you for your help. I'll try wluma on a different computer if I get the chance and best of luck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants