diff --git a/Cargo.lock b/Cargo.lock index 971472c4d2..bfcbc0d70b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2569,6 +2569,7 @@ dependencies = [ "daemon", "driver-graphics", "drm-sys", + "edid", "futures", "graphics-ipc", "inputd", diff --git a/drivers/graphics/virtio-gpud/Cargo.toml b/drivers/graphics/virtio-gpud/Cargo.toml index 50194c890d..ab34a0a258 100644 --- a/drivers/graphics/virtio-gpud/Cargo.toml +++ b/drivers/graphics/virtio-gpud/Cargo.toml @@ -6,6 +6,8 @@ authors = ["Anhad Singh "] [dependencies] drm-sys = "0.8.0" +#TODO: edid is abandoned, fork it an maintain? +edid = "0.3.0" log = "0.4" static_assertions = "1.1.0" futures = { version = "0.3.28", features = ["executor"] } diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index c9efd130b9..b8b4396626 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -7,7 +7,7 @@ use driver_graphics::{ modeinfo_for_size, CursorFramebuffer, CursorPlane, Framebuffer, GraphicsAdapter, GraphicsScheme, StandardProperties, }; -use drm_sys::DRM_MODE_DPMS_ON; +use drm_sys::{DRM_MODE_DPMS_ON, DRM_MODE_TYPE_PREFERRED}; use graphics_ipc::v1::Damage; use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; use inputd::DisplayHandle; @@ -307,6 +307,41 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { }; if self.has_edid { + let edid = edid::parse(&display.edid).unwrap().1; + + let first_detailed_timing = edid + .descriptors + .iter() + .find_map(|descriptor| match descriptor { + edid::Descriptor::DetailedTiming(detailed_timing) => Some(detailed_timing), + _ => None, + }) + .unwrap(); + connector.mm_width = first_detailed_timing.horizontal_size.into(); + connector.mm_height = first_detailed_timing.vertical_size.into(); + + connector.modes = edid + .descriptors + .iter() + .filter_map(|descriptor| { + match descriptor { + edid::Descriptor::DetailedTiming(detailed_timing) => { + // FIXME extract full information + Some(modeinfo_for_size( + u32::from(detailed_timing.horizontal_active_pixels), + u32::from(detailed_timing.vertical_active_lines), + )) + } + _ => None, + } + }) + .collect::>(); + + // First detailed timing descriptor indicates preferred mode. + for mode in connector.modes.iter_mut().skip(1) { + mode.flags &= !DRM_MODE_TYPE_PREFERRED; + } + let blob = objects.add_blob(display.edid.clone()); objects.set_object_property(id, standard_properties.edid, blob.into()); }