Closed nemosupremo closed 3 years ago
So, quickly, the code works (as in it actually renders quad.rs), but as you can imagine it hacks the API.
Alright, so we have 2 major issues so far:
wl_display
from winit
is not compatible with wl_display
that we could create in Instance::new
. We need to figure out why exactly this is the case. If it just happens to be that your platform has the default WL display different from winit window, we should just make it so the surface (created from this window) can't be rendered to by the physical adapter from our Instance, so we'll never need to stitch the two wl_display
things together.RawWindowHandle
, and we should file an issue accordingly and discuss this.Edit: filed https://github.com/rust-windowing/raw-window-handle/issues/61
For (1) if we fail to use the default wl_display, we could also write the Wayland window integration in a way similar to the Web:
Instance
by itself doesn't initialize anythingcreate_surface
, which needs to be called before the enumerate_adapters
, and needs to be only done oncewrt (2), I don't think this is an issue. You can call egl_window_create
with some dummy resolution (I just call it with VGA 640×480), then when you configure the swap chain, you call egl_window_resize
.
(1) seems to be the tricky one - I suspect wayland's design doesn't support intermixing of resources by two different wl_displays
, so when we get our wl_surface
from winit
and try to use it libwayland
hits an error. I don't think this has anything to do with the physical display (after all I only have one display), but something inherent with wayland's "secure by design" architecture. I'm going to try and take a deep dive into what the Vulkan instance does.
Digging up a bit... here is where winit
establishes a Wayland display - https://docs.rs/wayland-client/0.28.2/wayland_client/struct.Display.html#method.connect_to_env
For (1) if we fail to use the default wl_display, we could also write the Wayland window integration in a way similar to the Web:
This seems like the most successful path forward, but because we don't have a mutable reference to self, it would require wrapping everything in a mutex to get interior mutability. My plan was to leave eveerything as is (so enumerate_adapters
still works) but then recreate the context once create_surface
was called with a display other than our own. The downside of this would be calls to create_surface
, enumerate_adapters
and destroy_surface
would be mutex protected even in X11 - would that cause an undue performance hit?
There is no performance concern about mutexing this :) I was wondering if the logic can all be tight in src/window/wayland.rs
without affecting the main window/egl.rs
module, but in the end you see this more clearly since you are writing the code. So I defer to your judgement on how to best roll this out.
The wl_display from winit is not compatible with wl_display that we could create in Instance::new. We need to figure out why exactly this is the case. If it just happens to be that your platform has the default WL display different from winit window, we should just make it so the surface (created from this window) can't be rendered to by the physical adapter from our Instance, so we'll never need to stitch the two wl_display things together.
You must use the same wl_display
; objects such as wl_surface
are not shareable between different instances of wl_display
. The ID namespace is completely private to each client connection.
Ok, taking into the account the design of wayland with the current API, I've gone the route of interior mutability. What I've done is move the create
function largely into an Inner
struct - that way it can easily be dropped/created in create_surface
once we detect a new display. Under wayland when are asked to create a surface, we drop the previous context and recreate it. The X11 implementation is largely untouched from a functionality standpoint.
The OpenGL renderer seems to work on wgpu using the gl renderer on a pi under wayland
bors retry
This PR isn't meant to be merged in the current state, but to illustrate what changes were need to get it working.I've been trying to get the OpenGL backend working with wayland. The current device I'm targeting doesn't currently support Vulkan so I'm trying to get the wayland renderer working. During my tests I'm hitting some blockers with the
hal::Instance
API and I'm wondering if I'm doing something wrong, or if the API just wasn't developed with this in mind.I'm hitting the following roadblocks:
get_platform_display
. Both creating a new connection and usingegl::DEFAULT_DISPLAY
results in the window not working or rendering in thequad
example. To get around this I'm passing a pointer to the create function via theversion
parameter.To createI think this can be done by callingwl_egl_window_create
I need to pass in a window size. I don't think this is a show stopper as long as there was some way get resize events so I could callwl_egl_window_resize
.wl_egl_window_resize
inPresentationSurface::configure_swapchain
Another thing I had to remove the
GL_COLORSPACE
. This attribute is only supported in EGL 1.5, but currently are only testing 1.4. Seeing how the default value isGL_COLORSPACE_SRGB
, then I just removed this attribute entirely.Is there a proper way to overcome these hurdles without drastically modifying gfx's api?