libdrm_amdgpu_sys/drm_mode/
mode_info.rs

1use crate::bindings;
2pub use bindings::drmModeModeInfo;
3use bindings::{
4    DRM_MODE_TYPE_PREFERRED,
5    DRM_MODE_TYPE_USERDEF,
6    DRM_MODE_TYPE_DRIVER,
7};
8use bindings::{
9    DRM_MODE_FLAG_PHSYNC,
10    DRM_MODE_FLAG_NHSYNC,
11    DRM_MODE_FLAG_PVSYNC,
12    DRM_MODE_FLAG_NVSYNC,
13    DRM_MODE_FLAG_INTERLACE,
14    DRM_MODE_FLAG_DBLSCAN,
15    DRM_MODE_FLAG_CSYNC,
16    DRM_MODE_FLAG_PCSYNC,
17    DRM_MODE_FLAG_NCSYNC,
18    DRM_MODE_FLAG_HSKEW,
19    DRM_MODE_FLAG_DBLCLK,
20    DRM_MODE_FLAG_CLKDIV2,
21};
22
23macro_rules! impl_mode_info {
24    ($name: tt, $flag: expr_2021) => {
25        pub fn $name(&self) -> bool {
26            (self.type_ & $flag) != 0
27        }
28    }
29}
30
31macro_rules! impl_flag {
32    ($name: tt, $flag: expr_2021) => {
33        pub fn $name(&self) -> bool {
34            (self.flags & $flag) != 0
35        }
36    }
37}
38
39impl drmModeModeInfo {
40    pub fn name(&self) -> String {
41        super::c_char_to_string(&self.name)
42    }
43
44    // ref: https://gitlab.freedesktop.org/mesa/drm/-/blob/main/tests/modetest/modetest.c
45    pub fn refresh_rate(&self) -> f32 {
46        let mut num = self.clock as f32;
47        let mut den = self.htotal as f32 * self.vtotal as f32;
48
49        if self.is_interlace() {
50            num *= 2.0;
51        }
52
53        if self.is_dblscan() {
54            den *= 2.0;
55        }
56
57        if self.vscan > 1 {
58            den *= self.vscan as f32;
59        }
60
61        (num * 1000.0) / den
62    }
63
64    impl_mode_info!(type_is_preferred, DRM_MODE_TYPE_PREFERRED);
65    impl_mode_info!(type_is_userdef, DRM_MODE_TYPE_USERDEF);
66    impl_mode_info!(type_is_driver, DRM_MODE_TYPE_DRIVER);
67    impl_flag!(is_phsync, DRM_MODE_FLAG_PHSYNC);
68    impl_flag!(is_nhsync, DRM_MODE_FLAG_NHSYNC);
69    impl_flag!(is_pvsync, DRM_MODE_FLAG_PVSYNC);
70    impl_flag!(is_nvsync, DRM_MODE_FLAG_NVSYNC);
71    impl_flag!(is_interlace, DRM_MODE_FLAG_INTERLACE);
72    impl_flag!(is_dblscan, DRM_MODE_FLAG_DBLSCAN);
73    impl_flag!(is_csync, DRM_MODE_FLAG_CSYNC);
74    impl_flag!(is_pcsync, DRM_MODE_FLAG_PCSYNC);
75    impl_flag!(is_ncsync, DRM_MODE_FLAG_NCSYNC);
76    impl_flag!(is_hskew, DRM_MODE_FLAG_HSKEW);
77    impl_flag!(is_dblclk, DRM_MODE_FLAG_DBLCLK);
78    impl_flag!(is_clkdiv2, DRM_MODE_FLAG_CLKDIV2);
79}