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 #2272

Closed
wants to merge 142 commits into from

Conversation

StratusFearMe21
Copy link

@StratusFearMe21 StratusFearMe21 commented Apr 29, 2022

  • 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

What's this?

This is the start of a kmsdrm backend for winit! Essentially, if wayland and X.org are not available, this PR makes winit create a gbm device and a libinput listener to send the device window events.

KMS/DRM

KMS/DRM is the system that wayland compositors and X use to draw things to the screen. It's an abstraction over the graphics card essentially. In order to render a framebuffer to the screen, you must

  1. Open the global DRM file descriptor
  2. Select a connector (monitor)
  3. Select a CRTC
  4. Add a framebuffer
  5. Add a plane
  6. Commit all previous changes to the DRM file descriptor

My PR does steps 1-4 and 6. Steps 5 is where the user will come in and initialize a framebuffer for their graphics library of choice.

Event Handling

KMS/DRM mode does not have a traditional input system, in fact it has none at all. It requires that you grab the raw input file descriptors from /dev/input and read those. This is where libinput comes in. This is the same library that smithay and many wayland compositors use to complete this task. It even provides an event based interface which integrates very well with winit. I chose this library because it melds very well with winit, and it handles every type of input that winit supports out of the box, however

  • I heard talk in Implement kms backend? #1006 about using a Rust crate to handle raw input, libinput is not written in Rust
  • libinput supports multi-touch given that you are not performing a gesture. In this case libinput will produce gesture events and only tell you when the gesture begins, moves, and ends. These gestures do not provide finger ids either.
  • The way that my backend is implemented, it produces both WindowEvents and DeviceEvents even if a window has not been initialized.

Also, I should probably mention, there is an invisible virtual cursor that my KMS/DRM backend simulates which takes deltas from libinput and produces DeviceEvents for the raw mouse deltas and WindowEvents for the virtual location of the cursor on screen.

It it possible to access the gbm device mutex via the gbm_device(), the current connector via gbm_connector() and the current crtc via the gbm_crtc() method in the EventLoopWindowTargetExtUnix trait

Note

  • I'm positively stumped on what to do about these warnings
warning: use of deprecated field `event::KeyboardInput::modifiers`: Deprecat
ed in favor of WindowEvent::ModifiersChanged
   --> src/platform_impl/linux/drm/event_loop.rs:529:88
    |
529 | ...                   }, virtual_keycode: CHAR_MAPPINGS[k as usize], m
odifiers: self.modifiers } , is_synthetic: false }}, &mut ());
    |                                                                      ^
^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(deprecated)]` on by default

warning: associated function is never used: `dummy`
  --> src/platform_impl/linux/drm/mod.rs:49:25
   |
49 |     pub const unsafe fn dummy() -> Self {
   |                         ^^^^^
   |
   = note: `#[warn(dead_code)]` on by default

warning: associated function is never used: `dummy`
   --> src/platform_impl/linux/drm/mod.rs:138:25
    |
138 |     pub const unsafe fn dummy() -> Self {
    |                         ^^^^^

warning: `winit` (lib) generated 3 warnings

In the future

I could add an actual cursor and render it to the screen using the cursor framebuffer.

Thanks for considering my PR!

@maroider maroider added the C - waiting on maintainer A maintainer must review this code label Apr 29, 2022
@maroider
Copy link
Member

maroider commented Apr 29, 2022

Wow! This is neat. I'll be sure to look closer at this when I can, but for now, I just have to note that I think your editor's autoformatting bungled up our CHANGELOG.md, FEATURES.md (all instances of - for bullet-points have become *), and Cargo.toml (4-space indentation has become tab-based indentation).

@StratusFearMe21
Copy link
Author

Wow! This is neat. I'll be sure to look closer at this when I can, but for now, I just have to note that I think your editor's autoformatting bungled up our CHANGELOG.md, FEATURES.md (all instances of - for bullet-points have become *), and Cargo.toml (4-space indentation has become tab-based indentation).

Whoops! Sorry about that. I'm using remark and taplo for my formatting, I'll go back and fix the formatting on the documents you mentioned

@maroider
Copy link
Member

maroider commented May 3, 2022

Cargo.toml and FEATURES.md both still have what looks like unintentional formatting changes.

@StratusFearMe21
Copy link
Author

Sorry about that, I fixed the formatting again

@StratusFearMe21
Copy link
Author

StratusFearMe21 commented May 3, 2022

Forget about the raw-window-handle issue, I've confirmed myself that gbm is indeed thread-safe. You'll see the PR I made to raw-window-handle above

Any system level (syscall) file descriptor access is thread safe in all mainstream UNIX-like OSes. Though depending on the age they are not necessarily signal safe.

If you call read, write, accept or similar on a file descriptor from two different tasks then the kernel's internal locking mechanism will resolve contention.

For reads each byte may be only read once though and writes will go in any undefined order.

The stdio library functions fread, fwrite and co. also have by default internal locking on the control structures, though by using flags it is possible to disable that.

(I don't know what being "signal safe" is, but I don't think it matters)

@Drakulix
Copy link

Drakulix commented May 3, 2022

One of the maintainers of drm-rs/gbm.rs/input.rs/smithay here, this looks very well put together and I cannot spot any obvious mistakes. (But obviously I don't know a lot about winit internals.)

One nitpick: The mode selection is likely copied from some outdated example code. drm-rs gained the option to read out mode-types recently. Most monitors have a "Preferred" mode, which is likely what winit should select. (https://docs.rs/drm/latest/drm/control/struct.Mode.html#method.mode_type).

Additionally, I think there was an earlier attempt to do something like this for glutin, I think(?): Smithay/gbm.rs#2
I am not in the loop at the great scheme of things here, but if there is any way, I can help with reviewing or adjusting the code of any of these libs, please let me know. I would be glad to support such an endeavour, even if I don't have much time to write code for it myself. Given our wayland-compositor project smithay might also contain some code, that could be useful in the future, I would like to avoid code duplication where possible and rather build a shared foundation, if that is of any interest. I also see it as a net positive, that drm-rs/gbm.rs/input.rs might get some more usage in the future with this implementation.

Thanks for working on this! 👍

@StratusFearMe21
Copy link
Author

StratusFearMe21 commented May 11, 2022

I'm literally stumped. Unfortunately, I'm not knowledgable enough with Github workflows to solve this problem. If someone could fix the ci.yml for me, that would be very helpful (the Rust code no longer produces any warnings so it's just problems with dependencies now)

@madsmtm
Copy link
Member

madsmtm commented Sep 2, 2022

Hey @StratusFearMe21, are you still interested in working on this?

In the spirit of moving this forward, maybe CI could be dropped for now, and we could create an issue to tackle that later?

Also, when (if, but hopefully when) we merge this, would you be up for taking the role as maintainer of the platform? That is, review PRs for kmsdrm, have the final say in what gets merged and what doesn't, and generally help out maintaining winit.

@StratusFearMe21
Copy link
Author

StratusFearMe21 commented Sep 2, 2022

Wow! I'm absolutely honored, it would be my pleasure to help maintain winit, and this platform @madsmtm

@madsmtm
Copy link
Member

madsmtm commented Sep 2, 2022

An extra maintainer would be very welcome!

I've sent you an invite to the @rust-windowing organization, for now you'll have write access to winit and glutin, but not administrator rights; the process for granting you higher permissions is not really existing, see this for a bit of background; but I digress, if you need it, it'll probably happen at some point.

If, when you fix the merge conflicts, could add yourself to .github/CODEOWNERS and the testers and contributors table, then you'll get pinged when people change the backend.

A few notes on how we work: While we technically have a policy for when things can be merged (2 maintainers must have reviewed), it is rarely followed because of lack of manpower - try to have a few people review your own PRs before merging them, but remember that it is better to merge a PR than have it sitting around forever. Re platforms that no-one support (currently Web), any maintainer may merge PRs here.

Are you on Matrix / IRC? Would be nice if you were, I find that's a good way to stay in touch; feel free to ask any questions if you're uncertain about something!

@StratusFearMe21
Copy link
Author

Okay, so it seems I've left this PR alone for too long. At this point I think I'll have to re-write this PR from Scratch. In the meantime though I'm gonna wait until this PR (rust-windowing/glutin#1435) is merged before doing that.This PR has been in the works for ~5 months now and I think I can do a better job now than I could then anyway. Thanks for understanding

@madsmtm
Copy link
Member

madsmtm commented Sep 2, 2022

No worries, I hope you can at least reuse some of the work you've done in this PR!

@@ -17,36 +17,38 @@ default-target = "x86_64-unknown-linux-gnu"
targets = ["i686-pc-windows-msvc", "x86_64-pc-windows-msvc", "i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-apple-darwin", "wasm32-unknown-unknown"]

[features]
default = ["x11", "wayland", "wayland-dlopen"]
default = ["x11", "wayland", "wayland-dlopen", "kms"]
Copy link
Member

Choose a reason for hiding this comment

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

IMO drmkms should be opt-in rather than opt-out

@madsmtm
Copy link
Member

madsmtm commented Jan 23, 2023

@StratusFearMe21 there's some people on Matrix wondering what your plans with this are?

@StratusFearMe21
Copy link
Author

StratusFearMe21 commented Jan 23, 2023

@madsmtm , yeah, I havent been on Matrix lately since my server conked out. School has been way harder than I originally anticipated when I accepted your invite to be a maintainer, and thats why I havent made any progress on this PR. If you'd like to take me off the team as a maintainer, I would completely understand

@madsmtm
Copy link
Member

madsmtm commented Jan 23, 2023

Thanks for the update! And don't worry, it's fine, we all have a life to tend to outside open source ;). Take the time you need!

@mraerino
Copy link

mraerino commented May 7, 2023

I took the liberty of picking up this PR and doing the grunt-work of merging current master into it and making it compile: #2795

@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
C - waiting on maintainer A maintainer must review this code
Development

Successfully merging this pull request may close these issues.