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

Idiomatic OpenGL context directly on EGL #3468

Closed
kvark opened this issue Nov 6, 2020 · 1 comment · Fixed by #3470
Closed

Idiomatic OpenGL context directly on EGL #3468

kvark opened this issue Nov 6, 2020 · 1 comment · Fixed by #3470

Comments

@kvark
Copy link
Member

kvark commented Nov 6, 2020

Intro

Looking more at our current issues with GL presentation (#3353), at surfman code (servo/surfman#202), and around, I think we need to approach this from the ground up again.

First of all, surfman (used in #3375) brings a lot of friction:

We contributed a bit to it, but it takes a lot of effort to truly become fluent enough to land the changes we need. But we know what OpenGL backend of gfx-rs needs. What if we could reduce the scope of work here?

On Windows, we have Vulkan, D3D12 and D3D11. There is no need for OpenGL there. On macOS, OpenGL has been deprecated for a while already, and Metal is widely supported. This leaves us with only non-Apple unix systems, including Android. All of them, if I understand correctly, are designed to support EGL as the main context/window manager for GL.

Proposal

Therefore, what if we can just directly depend on EGL unconditionally (on non-wasm targets)? No need for optional glutin, surfman, etc, features. Just make it so our GL backend uses EGL for context creation.

  • Instance = egl::Display, created by eglGetDisplay. We could choose the default one - I think this is the most tricky part in the proposal so far.
  • Surface = egl::Surface, created by eglCreateWindowSurface
  • Adapter = egl::Config. When enumerate_adapters is called, we could get all the contexts supported by the display, and then query their attributes to find out which are software renderers, which support presentation, etc
  • Device = egl::Context, created by eglCreateContext.

Note: this elaboration doesn't include WebGL target. I don't know how to properly fit it in here, just yet.

@kvark
Copy link
Member Author

kvark commented Nov 6, 2020

More on Instance to egl::Display mapping. I think we can multiplex this: an Instance contains multiple egl::Display instances, one per platform-supported API. I.e. one for X11, one for Wayland, one for Android, etc.

When we create_surface, it matches the RawWindowHandle, and it can pick the relevant display to what the raw handle has, creating a platform surface from it.

The enumerated adapters are also a mix of the framebuffer configurations of different sub-APIs. The ability to present to a particular surface is still easy to query in supports_queue_family.

I think this is a non-compromise solution that's possible to implement, all under EGL.

@kvark kvark mentioned this issue Nov 9, 2020
3 tasks
bors bot added a commit that referenced this issue Nov 9, 2020
3470: [gl] replace Surfman by EGL r=grovesNL a=kvark

Fixes #3468

This is a BIG change. It re-architects WSI of the GL backend to unconditionally use EGL (via `khronos-egl` crate atm, but we can change that). This means the backend is *only* supported on Linux/BSD/Android, it's no longer supported on Apple and Microsoft platforms.

One of the consequences - we throw Surfman away. There was too much complication and too little benefit from it anyway.

Another consequence - we are locked to GLES, given that I experienced issues trying to get a desktop GL context via EGL. We can revisit this, but really I think going with GLES 3.1 makes total sense for the backend, unconditionally. if the target platform is powerful above what GLES 3.1 offers, it should just support Vulkan.

Most importantly, it solves GL context sharing, so presentation is much more robust. However, it doesn't solve the extra copy - #3469. For this, we'll need to follow-up by directly using platform extensions, such as [EGL_WL_create_wayland_buffer_from_image](https://www.khronos.org/registry/EGL/extensions/WL/EGL_WL_create_wayland_buffer_from_image.txt).

PR checklist:
- [x] `make` succeeds (on *nix)
- [x] `make reftests` succeeds
- [x] tested examples with the following backends: Linux


Co-authored-by: Dzmitry Malyshau <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant