-
Notifications
You must be signed in to change notification settings - Fork 183
EGL Rework #17
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
EGL Rework #17
Conversation
nix = "0.7.0" | ||
xkbcommon = "0.2.1" | ||
tempfile = "2.1.5" | ||
slog = { version = "2.0.0" } | ||
slog-stdlog = "2.0.0-0.2" | ||
glutin = { version = "~0.7.4", optional = true } | ||
libloading = "0.4.0" | ||
wayland-client = { version = "~0.8.6", optional = true } |
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.
Having wayland-client 0.8 and wayland-server 0.9 actually compiles? O.o
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.
Yes when I set both to use dlopen.
And wayland-client 0.8 is sadly required, as winit is still expecting that.
Cargo.toml
Outdated
default = ["backend_glutin", "backend_libinput", "renderer_glium"] | ||
backend_glutin = ["glutin", "wayland-server/dlopen"] | ||
default = ["backend_winit", "backend_libinput", "renderer_glium"] | ||
backend_winit = ["winit", "wayland-server/dlopen", "wayland-client", "wayland-client/dlopen"] |
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 don't think we need both wayland-client
and wayland-client/dlopen
here, do we?
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.
See comment above.
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.
But, don't wayland-client/dlopen
imply wayland-client
?
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.
Not sure, good point. I will test that.
src/backend/glutin.rs
Outdated
@@ -21,7 +21,7 @@ use std::rc::Rc; | |||
/// Create a new `GlutinHeadlessRenderer` which implements the `OpenglRenderer` graphics | |||
/// backend trait | |||
pub fn init_headless_renderer() -> Result<GlutinHeadlessRenderer, CreationError> { | |||
init_headless_renderer_from_builder(HeadlessRendererBuilder::new(1024, 600)) | |||
init_headless_renderer_from_builder(HeadlessRendererBuilder::new(1024, 600) |
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.
unclosed delimiter (
😛
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.
Actually, is this file needed at all now?
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.
No, I just forgot to remove it.
src/backend/graphics/egl.rs
Outdated
/// `044e651edf67a2029eecc650dd42546af1501414` | ||
/// | ||
/// It therefor falls under glutin's Apache 2.0 license | ||
/// (see https://github.com/tomaka/glutin/blob/master/LICENSE) |
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.
"therefore"
Also I guess this should be good enough. But to be safe, let's ask @tomaka his opinion on the matter.
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.
Well, yeah, I don't see a problem with this.
src/backend/graphics/egl.rs
Outdated
pub enum Native { | ||
X11(ffi::NativeDisplayType, ffi::NativeWindowType), | ||
Wayland(ffi::NativeDisplayType, ffi::NativeWindowType), | ||
Gbm(ffi::NativeDisplayType, ffi::NativeWindowType), |
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.
Is this what will be used for the native/modesetting backed?
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.
Yes. This was the main motivation of doing this change now, as this is essential to make anything useful out of the drm implementation I am working on.
src/backend/winit.rs
Outdated
/// input events will be received by a set `InputHandler`. | ||
/// | ||
/// Returns an error if the `Window` the window has been closed. Calling | ||
/// `process_new_events` again after the `Window` has been closed is considered an |
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.
dispatch_new_events
I don't have much to say other than this. This is quite a lot of boilerplate to plug everything together, not the easiest thing to review. I'll try to give a few more passes on it. Also, making the travis build pass would be a good thing to do as well. 😉 |
Thanks for the first review. Typos, Docs and Travis are definitely my main priority today. |
Alright, I should have addressed most of the things. The example is still not working right (immediately closes on wayland and panics on x11), but its getting somewhere. |
Closes without panicking on wayland? Well, that's weird, is it some segfault or stuff like that? |
src/backend/winit.rs
Outdated
match event { | ||
WindowEvent::Resized(x, y) => { | ||
window.set_inner_size(x, y); | ||
if let Some(wl_surface) = surface.as_ref() { |
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.
To avoid confusion, this is a wl_egl_surface
, not a wl_surface
I'd like to have the example running without crashing before merging, as this is likely some weird bug somewhere and we'll probably regret not hunting it if we merge it now. |
Alright, I will hunt it. |
I mean, given the source of this example, it finishing by an other way than panicking is very weird, and likely not a good sign at all... |
Well testing on wayland is quite painful right now for me, because I need to switch my DE (see Cloudef/wlc#235), which is why I was hoping, that you might have an idea. |
What I do, is I run weston as an X11 client, and then start my wayland apps as weston clients. I can try to run your code like this this evening on my computer, if you want. |
Good idea. Will try that.
This will probably be a rather nasty bug, so if you are willing to help debugging (even just by testing), that would be highly appreciated. |
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.
Debugged it. Basically context creation is failing currently, which breaks both (X11 & Wayland), but a possible bug in wayland-client
lets the wayland variant segfault.
src/backend/winit.rs
Outdated
color_bits: Some(24), | ||
alpha_bits: Some(8), | ||
..Default::default() | ||
})? |
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.
Okay I have debugged it. This line causes a segfault, if context creation fails (why it fails is a different story, see other comment). The reason is, that the wl_egl_surface
is dropped, which causes the segfault in this specific case. Any thoughts @vberger ?
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.
if the wl_egl_surface
is dropped, this destroys the EGL surface, and the pointer you retrieve line 82 becomes invalid. Could this be the reason?
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 crash happens in wl_egl_window_destroy
though.
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.
Uh. So, that means the EGL surface ends up in an invalid state following the failed initialization, and then it blows up when it is destroyed, I'd 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.
Probably. I will check, what kind of cleanup should be done in this case.
src/backend/winit.rs
Outdated
version: None, | ||
profile: None, | ||
debug: cfg!(debug_assertions), | ||
robustness: Robustness::TryRobustLoseContextOnReset, |
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.
This causes context creation to fail, because apparently my EGL implementation reports, that it supports robustness, but creation later fails with BadAttribute
, if it is set to any other value then NotRobust
.
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.
Okay, this is far beyond my knowledge of EGL 😅
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.
It just sounds like a typical driver bug. I have changed it to default to NotRobust
now.
}; | ||
|
||
if surface.is_null() { | ||
return Err(CreationError::OsError(String::from("eglCreateWindowSurface failed"))); |
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.
This check should be done in the Gbm
branch of the match, otherwise providing a null pointer in input with one of the others backend may trigger it...
An other assert checking that they are not null can be added to replace this one, too.
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.
Are you aware, that the match statement, does the same for all backend types? The rustfmt format might have tricked you there.
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.
Oh! Right, indeed. My bad. 😅
return Err(CreationError::OsError(String::from("eglCreateWindowSurface failed"))); | ||
} | ||
surface | ||
}; |
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.
Good news, I found the cause for the segfault!
The reason is, because of the reentrancy of this function(see the match on line 146, it calls itself), this par ends up called twice. Especially, egl.CreateWindowSurface()
is called twice on the same native surface, and apparently this is not good.
The simplest fix is to move this whole let surface = { .... }
block down in the function, right before the end, until after the EGL context has been successfully created (so line 500 of this diff). :)
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.
Note it only solves the segfault, not the panic 😅
- Don't initialize a surface twice, if context creation fails for one version - Don't let the loaded egl library go out of scope and thus invalidating the function pointers
👍 |
Alright, it is late and I am not sure, if I did not miss anything important.
Docs are also largely missing.
Other then that, I think this is good for review/first feedback.
Partly addresses #12.