From adc05b66548d10ad8c4a400fb8e8b072a2fd8e2c Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Wed, 2 Nov 2022 16:12:00 +0000 Subject: kmsprint: Decode bitfields for flags and type of hdmi mode Decode the bitfields for the mode type and flags of Videomode Use short names for type as it allows for consise formatting (excluding the deprecated options, that are not expected to be seen) I've swapped order of flags and types as the type is expected to be shorted so can fit in a fixed size field Signed-off-by: Dom Cobley Signed-off-by: Tomi Valkeinen --- kms++/src/videomode.cpp | 117 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 6 deletions(-) diff --git a/kms++/src/videomode.cpp b/kms++/src/videomode.cpp index b039059..0e5acf6 100644 --- a/kms++/src/videomode.cpp +++ b/kms++/src/videomode.cpp @@ -110,18 +110,123 @@ static char sync_to_char(SyncPolarity pol) } } +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +template +std::string join(const T& values, const std::string& delim) +{ + std::ostringstream ss; + for (const auto& v : values) { + if (&v != &values[0]) + ss << delim; + ss << v; + } + return ss.str(); +} + +static const map mode_type_map = { + // the deprecated ones don't care about a short name + { DRM_MODE_TYPE_BUILTIN, "builtin" }, // deprecated + { DRM_MODE_TYPE_CLOCK_C, "clock_c" }, // deprecated + { DRM_MODE_TYPE_CRTC_C, "crtc_c" }, // deprecated + { DRM_MODE_TYPE_PREFERRED, "P" }, + { DRM_MODE_TYPE_DEFAULT, "default" }, // deprecated + { DRM_MODE_TYPE_USERDEF, "U" }, + { DRM_MODE_TYPE_DRIVER, "D" }, +}; + +static const map mode_flag_map = { + // the first 5 flags are displayed elsewhere + { DRM_MODE_FLAG_PHSYNC, "" }, + { DRM_MODE_FLAG_NHSYNC, "" }, + { DRM_MODE_FLAG_PVSYNC, "" }, + { DRM_MODE_FLAG_NVSYNC, "" }, + { DRM_MODE_FLAG_INTERLACE, "" }, + { DRM_MODE_FLAG_DBLSCAN, "dblscan" }, + { DRM_MODE_FLAG_CSYNC, "csync" }, + { DRM_MODE_FLAG_PCSYNC, "pcsync" }, + { DRM_MODE_FLAG_NCSYNC, "ncsync" }, + { DRM_MODE_FLAG_HSKEW, "hskew" }, + { DRM_MODE_FLAG_BCAST, "bcast" }, // deprecated + { DRM_MODE_FLAG_PIXMUX, "pixmux" }, // deprecated + { DRM_MODE_FLAG_DBLCLK, "2x" }, + { DRM_MODE_FLAG_CLKDIV2, "clkdiv2" }, +}; + +static const map mode_3d_map = { + { DRM_MODE_FLAG_3D_NONE, "" }, + { DRM_MODE_FLAG_3D_FRAME_PACKING, "3dfp" }, + { DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE, "3dfa" }, + { DRM_MODE_FLAG_3D_LINE_ALTERNATIVE, "3dla" }, + { DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL, "3dsbs" }, + { DRM_MODE_FLAG_3D_L_DEPTH, "3dldepth" }, + { DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH, "3dgfx" }, + { DRM_MODE_FLAG_3D_TOP_AND_BOTTOM, "3dtab" }, + { DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF, "3dsbs" }, +}; + +static const map mode_aspect_map = { + { DRM_MODE_FLAG_PIC_AR_NONE, "" }, + { DRM_MODE_FLAG_PIC_AR_4_3, "4:3" }, + { DRM_MODE_FLAG_PIC_AR_16_9, "16:9" }, + { DRM_MODE_FLAG_PIC_AR_64_27, "64:27" }, + { DRM_MODE_FLAG_PIC_AR_256_135, "256:135" }, +}; + +static string mode_type_str(uint32_t val) { + vector s; + for (const auto & [k, v] : mode_type_map) { + if (val & k) { + if (!v.empty()) + s.push_back(v); + val &= ~k; + } + } + // any unknown bits + if (val != 0) + s.push_back(fmt::format("{:#x}", val)); + return join(s, "|"); +} + +static string mode_flag_str(uint32_t val) { + vector s; + for (const auto& [k, v] : mode_flag_map) { + if (val & k) { + if (!v.empty()) + s.push_back(v); + val &= ~k; + } + } + auto it = mode_3d_map.find(val & DRM_MODE_FLAG_3D_MASK); + if (it != mode_3d_map.end()) { + if (!it->second.empty()) + s.push_back(it->second); + val &= ~DRM_MODE_FLAG_3D_MASK; + } + it = mode_aspect_map.find(val & DRM_MODE_FLAG_PIC_AR_MASK); + if (it != mode_aspect_map.end()) { + if (!it->second.empty()) + s.push_back(it->second); + val &= ~DRM_MODE_FLAG_PIC_AR_MASK; + } + // any unknown bits + if (val != 0) + s.push_back(fmt::format("{:#x}", val)); + return join(s, "|"); +} + string Videomode::to_string_long() const { string h = fmt::format("{}/{}/{}/{}/{}", hdisplay, hfp(), hsw(), hbp(), sync_to_char(hsync())); string v = fmt::format("{}/{}/{}/{}/{}", vdisplay, vfp(), vsw(), vbp(), sync_to_char(vsync())); - string str = fmt::format("{} {:.3f} {} {} {} ({:.2f}) {:#x} {:#x}", + string str = fmt::format("{} {:.3f} {} {} {} ({:.2f}) {} {}", to_string_short(), clock / 1000.0, h, v, vrefresh, calculated_vrefresh(), - flags, - type); + mode_type_str(type), + mode_flag_str(flags)); return str; } @@ -131,13 +236,13 @@ string Videomode::to_string_long_padded() const string h = fmt::format("{}/{}/{}/{}/{}", hdisplay, hfp(), hsw(), hbp(), sync_to_char(hsync())); string v = fmt::format("{}/{}/{}/{}/{}", vdisplay, vfp(), vsw(), vbp(), sync_to_char(vsync())); - string str = fmt::format("{:<16} {:7.3f} {:<18} {:<18} {:2} ({:.2f}) {:#10x} {:#6x}", + string str = fmt::format("{:<16} {:7.3f} {:<18} {:<18} {:2} ({:.2f}) {:<5} {}", to_string_short(), clock / 1000.0, h, v, vrefresh, calculated_vrefresh(), - flags, - type); + mode_type_str(type), + mode_flag_str(flags)); return str; } -- cgit v1.2.3