-
Notifications
You must be signed in to change notification settings - Fork 51
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
Add connector_id to DrmWindowHandle #170
base: master
Are you sure you want to change the base?
Conversation
Changing the signature of Can we just add the field, as well as a doc comment if necessary, but not change any method signatures? |
I don't think that connector should go there, because connector is display and I don't think any one stops you from drawing into device without connectors attached and e.g. copy to other GPU which has connectors attached? Also, if multiples are present, which connector should be used? |
That's exactly why it should go here. If you want to draw to a display the only way is to get a connector otherwise you have no way to create something to draw too. If you want to copy to another gpu then you should use the Handle of that gpu. Without the connector there is no handle to a display because there is no display.
That is up to the provider of the handle to decide. To ensure we handle cases where programs rely on the device without a connector then we could specify the connect_id as an Option. This would also fix the problem mentioned above since we could just pass |
I also realized that instead of a u32 I should have used a NonZeroU32. Going with the above would also mean we get a nicely aligned layout since the size of |
But you can have lots of connectors per once device so it doesn't make much sense, and connector is also not required to create any drawing setups with OpenGL/Vulkan, etc, because you draw into So if anywhere connector could be an optional field on |
It appears I misunderstood the difference between the display and the window handle. Given this clarification, I agree that placing the connector in the window handle is more logical. To provide additional context, this change is necessary for adding support to wgpu. Specifically, Vulkan requires a connector_id when creating the surface. You can see how this is used here: gfx-rs/wgpu#5908 |
I'd say just move it to the I personally always used |
@@ -239,6 +239,7 @@ impl DrmDisplayHandle { | |||
pub struct DrmWindowHandle { | |||
/// The primary drm plane handle. | |||
pub plane: u32, | |||
pub connector_id: Option<NonZeroU32>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should document what is it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also ideally with links to other documentation explaining it, if such docs exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also need a CHANGELOG entry.
@@ -255,7 +257,10 @@ impl DrmWindowHandle { | |||
/// let handle = DrmWindowHandle::new(plane); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update this example to also set the connector_id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I mean here is something like:
/// let handle = DrmWindowHandle::new(plane); | |
/// # connector_id = unsafe { NonZeroU32::new_unchecked(1) }; | |
/// let mut handle = DrmWindowHandle::new(plane); | |
/// handle.connector_id = Some(connector_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my side it's good. Docs are indirectly linked via the description of the struct itself since it's all on the DRM docs, as well as plane stuff.
/// # connector_id = unsafe { NonZeroU32::new_unchecked(1) }; | ||
/// let handle = DrmWindowHandle::new_with_connector_id(plane, connector_id); | ||
/// ``` | ||
pub fn new_with_connector_id(plane: u32, connector_id: NonZeroU32) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This doesn't really match what's exposed for the other platforms, there, the user would just do:
let mut handle = DrmWindowHandle::new(...);
handle.connector_id = Some(...);
But perhaps this approach is indeed better? In any case, might make sense to not do such a change in this PR, as it's somewhat inconsistent with the other platforms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the _with_*
suffix aligns better with rust's coding guidelines, promoting more idiomatic code. If there is a consensus that this requires further discussion, I can amend the changes and open a separate pr. However, I believe this approach is the most appropriate for exposing the api and that similar constructors should be considered for other platforms as well.
Implementing these constructors will not compromise backwards compatibility, as the only scenario requiring their removal would be the elimination of the corresponding fields. In such a case, a breaking change would be inevitable regardless.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Furthermore, implementing a separate constructor prevents unnecessary mutability of the created handle, which typically does not require any kind of modification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm generally against constructors like that in this crate because they are prone to factorial growth. So if you want to add one more optional field you'd need to add permutations, since you don't generally require all the things to be present.
Unless you just stuck constructors with Option
but I don't see a point in it given that you can just build with WindowHandle { }
syntax because it's a pod
with all fields being pub
.
I'm also not that much in love with ::new
methods, but it's more of a shorthand for essential stuff, I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The primary justification for introducing a new constructor is that it is not feasible to manually instantiate a handle due to the struct being marked as non_exhaustive. This is not merely a matter of convenience or shorthand. Structs marked as non_exhaustive cannot be instantiated outside of their originating crate. A dedicated function to construct one is mandatory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They can as long as they have
Default
but I forgot that we don't have it because we can not really provideDefault
. I still don't like the constructor because factorial growth.
The proper solution would be to only have one constructor that takes all the parameters but that would break backwards compatibility and require a version bump. My understanding was that we should avoid that if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The connector is optional though, since not all APIs require it and some APIs may require a list of connectors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The connector is optional though, since not all APIs require it and some APIs may require a list of connectors.
Which perfectly translates into the new constructor. A new constructor like this would only be necessary for an optional field.
I am also not aware of any API that requires a least of connectors that would also consume a window handle. Do you have any examples? If that's the case then maybe the signature of field should be reconsidered. My main use case for this is implementing a drm backend for wgpu which afaik would require only a specific connector, at least for the vulkan backend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have any examples? If that's the case then maybe the signature of field should be reconsidered. My main use case for this is implementing a drm backend for wgpu which afaik would require only a specific connector, at least for the vulkan backend.
I know that drm
APIs accept an array IIRC, at least smithay uses arrays of connectors a lot. Though, they unlikely to use the raw-window-handle
for that typo of things and if Vulkan needs just a single connector than it's fine the way it is.
In general I won't block on adding a constructor, it's just I don't really like it, though, I'm not sure there will be more fields to add.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like @Lokathor's opinion - but as stated in my first comment, this is very much nitpicking ;)
Could you please provide an update on the possibility of merging this PR? |
Ah, sorry this one slipped out of my attention. I will double check later but in general we probably want as many optional fields to be supported as possible so this is likely to be approved. |
Based on the discussion in this comment, I am reconsidering whether this patch is the most effective approach to achieve my final objective. I'm currently unsure how to mark the pull request as not ready for merging on my end, but for now, it should be treated as such. |
To relay some of my comment over at that WGPU PR, Vulkan doesn't specifically require the connector ID especially because Because the way you plan to use this now seems to rely on the receiver of the As a side-note, regardless of how we continue, let's replace |
@morr0ne there's some sort of "draft" status a PR can be set to, but that's not necessary, we can just hold off on a merge until you're confident about the direction of things |
This pull request introduces a new field to the DRM display handle to specify the connector id.
Rationale:
Without a connector, the file descriptor may point to a DRM device that lacks any connected displays, rendering it non-functional and arguably not a valid handle. By adding the connector_id field, we ensure that the display handle accurately represents a connected and usable display.