Skip to content

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

Merged
merged 13 commits into from
Jun 2, 2017
Merged

EGL Rework #17

merged 13 commits into from
Jun 2, 2017

Conversation

Drakulix
Copy link
Member

@Drakulix Drakulix commented May 18, 2017

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.

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 }
Copy link
Member

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

Copy link
Member Author

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"]
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

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

See comment above.

Copy link
Member

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 ?

Copy link
Member Author

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.

@@ -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)
Copy link
Member

Choose a reason for hiding this comment

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

unclosed delimiter ( 😛

Copy link
Member

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?

Copy link
Member Author

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.

/// `044e651edf67a2029eecc650dd42546af1501414`
///
/// It therefor falls under glutin's Apache 2.0 license
/// (see https://github.com/tomaka/glutin/blob/master/LICENSE)
Copy link
Member

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.

Copy link

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.

pub enum Native {
X11(ffi::NativeDisplayType, ffi::NativeWindowType),
Wayland(ffi::NativeDisplayType, ffi::NativeWindowType),
Gbm(ffi::NativeDisplayType, ffi::NativeWindowType),
Copy link
Member

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?

Copy link
Member Author

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.

/// 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
Copy link
Member

Choose a reason for hiding this comment

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

dispatch_new_events

@elinorbgr
Copy link
Member

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. 😉

@Drakulix
Copy link
Member Author

Thanks for the first review. Typos, Docs and Travis are definitely my main priority today.

@Drakulix
Copy link
Member Author

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.

@Drakulix Drakulix changed the title [WIP] First EGL Rework draft First EGL Rework draft May 21, 2017
@Drakulix Drakulix changed the title First EGL Rework draft EGL Rework May 21, 2017
@elinorbgr
Copy link
Member

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?

match event {
WindowEvent::Resized(x, y) => {
window.set_inner_size(x, y);
if let Some(wl_surface) = surface.as_ref() {
Copy link
Member

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

@elinorbgr
Copy link
Member

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.

@Drakulix
Copy link
Member Author

Alright, I will hunt it.
No segfault, it just closes and returns a bad error code. Maybe we should integrate dispatch_new_events into the event_loop somehow. Probably with a timer.

@elinorbgr
Copy link
Member

elinorbgr commented May 22, 2017

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...

@Drakulix
Copy link
Member Author

Drakulix commented May 22, 2017

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.

@elinorbgr
Copy link
Member

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.

@Drakulix
Copy link
Member Author

Drakulix commented May 22, 2017

What I do, is I run weston as an X11 client, and then start my wayland apps as weston clients.

Good idea. Will try that.

I can try to run your code like this this evening on my computer, if you want.

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.

Copy link
Member Author

@Drakulix Drakulix left a 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.

color_bits: Some(24),
alpha_bits: Some(8),
..Default::default()
})?
Copy link
Member Author

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 ?

Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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?

Copy link
Member Author

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.

version: None,
profile: None,
debug: cfg!(debug_assertions),
robustness: Robustness::TryRobustLoseContextOnReset,
Copy link
Member Author

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.

Copy link
Member

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 😅

Copy link
Member Author

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")));
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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
};
Copy link
Member

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). :)

Copy link
Member

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 😅

Drakulix added 6 commits June 2, 2017 13:54
- 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
@elinorbgr
Copy link
Member

👍

@elinorbgr elinorbgr merged commit 1925dc9 into Smithay:master Jun 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants