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

Initial kmsdrm support [forked + updated] #2795

Closed
wants to merge 155 commits into from

Conversation

mraerino
Copy link

@mraerino mraerino commented May 7, 2023

I forked #2272 and updated it to resolve merge conflicts and so it compiles with the current dependencies.


  • Tested on all platforms changed
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality
  • Updated feature matrix, if new features were added or implemented

@mraerino mraerino mentioned this pull request May 7, 2023
5 tasks
@mraerino mraerino mentioned this pull request May 7, 2023
Copy link
Member

@notgull notgull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through this PR. I know most of this wasn't you, but it should still be fixed before merging.

Since we have to wait until after #2789 merges, it might be useful to base on that for now?


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Comment on lines +47 to +48
kms = ["drm", "input", "xkbcommon", "udev", "parking_lot"]
kms-ext = ["libseat"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it still necessary for split the feature into kms and kms-ext like this? I forget what the original rationale for this was.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kms-ext uses (libseat)[https://sr.ht/~kennylevinsen/seatd/].

Seat management takes care of mediating access to shared devices (graphics, input), without requiring the applications needing access to be root.

So this lib links/uses existing methods such as logind to create a user "seat" and allow access to various things. The lib is also a good intermediate step between winit and systemd-logind (plus others).

In our case this would allow anyone using this feature to run via TTY without requiring root. Standard kms here does require root access.

Unfortunately this feature is broken in this PR.

❯ cargo run --example window --no-default-features --features=kms-ext
   Compiling libseat-sys v0.1.7
   Compiling slog v2.7.0
   Compiling libseat v0.1.7
   Compiling winit v0.28.4 (/home/luke/Projects/winit-drm)
error: The platform you're compiling for is not supported by winit
  --> src/platform_impl/mod.rs:68:1
   |
68 | compile_error!("The platform you're compiling for is not supported by winit");

input = { version = "0.7.1", optional = true }
libseat = { version = "0.1.4", optional = true }
udev = { version = "0.6.3", optional = true }
xkbcommon = { version = "0.5.0", optional = true }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth it to just use xkbcommon-dl instead, since that's what #2789 is using.

Comment on lines +39 to +64
pub struct EventLoopWindowTarget<T> {
/// Drm Connector
pub connector: connector::Info,

/// Drm crtc
pub crtc: crtc::Info,

/// Drm plane
pub plane: plane::Handle,

/// Allows window to edit cursor position
pub(crate) cursor_arc: Arc<Mutex<PhysicalPosition<f64>>>,

/// Drm device
pub device: Card,

/// Event loop handle.
pub event_loop_handle: calloop::LoopHandle<'static, EventSink>,

pub(crate) event_sink: EventSink,

/// A proxy to wake up event loop.
pub event_loop_awakener: calloop::ping::Ping,

_marker: std::marker::PhantomData<T>,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if all of the fields were either pub or pub(crate), instead of this mix.

Comment on lines +150 to +155
let mut enumerator = Enumerator::new().map_err(|e| {
os_error!(OsError::KmsError(format!(
"failed to open udev enumerator: {}",
e
)))
})?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to use a combinator like we have in softbuffer to avoid duplicating this map_err block`.

Ok(PostAction::Continue)
}

fn register(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> calloop::Result<()> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe instead of using poll directly, we can wrap the libinput handling in the calloop::Generic type and use that to handle things?

Comment on lines +27 to +33
/// Implementing `AsRawFd` is a prerequisite to implementing the traits found
/// in this crate. Here, we are just calling `as_raw_fd()` on the inner File.
impl unix::io::AsRawFd for Card {
fn as_raw_fd(&self) -> unix::io::RawFd {
*self.0
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modern versions of the drm crate use AsFd, maybe we should use that instead?

Comment on lines +35 to +39
impl Drop for Card {
fn drop(&mut self) {
unsafe { std::fs::File::from_raw_fd(*self.0) };
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look sound to me. Since the i32 can still be used outside of the Card (thanks to AsRawFd), couldn't it still be used after a free? It might be better to define Card as a wrapper around an OwnedFd and then wrap that in an Arc.

Copy link
Member

@ids1024 ids1024 May 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this isn't right because drop is closing this every time you drop a Card, even if you cloned it. The dropping needs to be within the Arc.

Winit currently requires Rust 1.64.0, so it would be correct and require less code to use struct Card(Arc<OwnedFd>).

Comment on lines +72 to +76
pub fn new<T>(
event_loop_window_target: &super::event_loop::EventLoopWindowTarget<T>,
_attributes: WindowAttributes,
_platform_attributes: platform_impl::PlatformSpecificWindowBuilderAttributes,
) -> Result<Self, error::OsError> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth considering #33 here. Maybe, if a window has already been created, it's better to just return an error instead of returning another window?

@@ -204,13 +226,15 @@ pub enum MonitorHandle {
/// }
/// ```
/// The result can be converted to another enum by adding `; as AnotherEnum`
macro_rules! x11_or_wayland {
macro_rules! x11_or_wayland_or_drm {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Especially if we add more backends in the future, it might be better to change the name of this (maybe platform_specific!)?

@flukejones
Copy link

I don't mean to be a bother, but is there a timeframe for merging this? It's exactly what I'm looking for to be used with slint and in embedded environment (STM32MP157). I can test this later on.

@kchibisov
Copy link
Member

I don't mean to be a bother, but is there a timeframe for merging this? It's exactly what I'm looking for to be used with slint and in embedded environment (STM32MP157). I can test this later on.

No timeline for changes like that, you might look into smithay project instead if you want to. It's not only about wayland in the end of the day.

@flukejones
Copy link

I don't mean to be a bother, but is there a timeframe for merging this? It's exactly what I'm looking for to be used with slint and in embedded environment (STM32MP157). I can test this later on.

No timeline for changes like that, you might look into smithay project instead if you want to. It's not only about wayland in the end of the day.

Yeah been looking at a few options. It would be great to get this in winit as it means a few projects would gain it for free. SDL2 also has a similar DRM method and I've used that for my room4doom (as example).

@flukejones
Copy link

No timeline for changes like that, you might look into smithay project instead if you want to. It's not only about wayland in the end of the day.

The reason I wondered about this is because if winit implements KMS backend, then many many other projects gain KMS ability for free. Especially nice for GUI toolkits in embedded applications.

@daxpedda
Copy link
Member

Closing due to inactivity.
See #1006.

@daxpedda daxpedda closed this Feb 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

7 participants