-
Notifications
You must be signed in to change notification settings - Fork 341
Renderer redesign v6 #1352
Comments
What about software renderers?
Note that some clients don't want DMA-BUFs, because they need data in main memory. For grim for instance, DMA-BUFs would be a burden. |
Agreed. Otherwise this idea looks pretty solid, I like it. |
Daniel Stone said on IRC it's not a good idea to use GBM for shm.
|
fwiw i like the idea as well. It would indeed match the way things can be done (hopefully soon that is) with vulkan more naturally and allow to share more code between vulkan/gl but i'm not sure things are ready for this yet and that good abstractions justifiy the drawbacks. Software renderers and using wlroots on weird platforms may be theoretical now but shouldn't we try to keep everything as easily extendable as possible? E.g. for vulkan, do we know that |
I thought I would go over some of the things that I've currently added in my PR and a bit of the rationale behind them. wlr_allocator + wlr_imageInstead of going straight GBM, this is a type that loosely wraps over it (and other allocators). All it does it "allocate" and "deallocate", and Renderers would directly create and use one of the types below, as they really need to know about the details of what allocator they're using. This is basically required so wlr_gbm_allocator(I'm thinking of renaming this to just This could be used by either an OpenGL or Vulkan renderer, or anything that can deal with dmabufs. Some new backend functions were added specifically for this type:
wlr_shm_allocatorThis is just a possible type we can add, but I'm not going to do it as part of the PR. Some new allocator-specific functions would be added to the backend (also not part of the PR).
We'd only support linear XRGB8888 or ARGB8888 for this allocator. Supporting anything else seems like it'd be a huge pain. It would be possible to write an OpenGL/Vulkan renderer which uses this allocator, but it would be suboptimal and probably pointless. wlr_eglThis has been "demoted" to a pure utility type for writing OpenGL renderers. If you're not writing exactly that, you would not be touching this type. Much of the generality has been removed and it is now GBM specific. A nice little consequence of the new design is now that we're doing surfaceless rendering, we don't need to deal with EGLConfigs anymore. I hated those damn things. Since we're dealing with non-default framebuffers in OpenGL, people writing their own renderers are free to attach their own depth or stencil buffers, making wlr_output_presentReplaces the old "swap buffers" thing. Asks the output to use our buffer, and it will notify us when we're free to use it again. I also want this to become the point where direct-scanout or anything similar happens. If we want to scan something out, we just take a Damage still needs to be added to this interface. wlr_format_setJust a set of formats + modifiers. I'll also add a function which takes the union of this set. Other notes
|
I think it makes sense to keep the |
Right.
'release' and 'frame' aren't quite the same thing, so they're currently separate. |
"Release" belongs to the "Frame" really means "please draw". On Wayland this is
|
Ok, that makes sense. |
Forgot to say: overall this looks good™.
This would be kind of inconsistent with our other naming conventions (e.g. we have
+1, it has already become more-or-less this.
Instead of a list of lists, an alternate design would be to have a list of (format, modifier). Maybe this can simplify the interface.
+1
Rationale? Maybe it'll become possible to write a renderer-less compositor? A use-case would be to use wlroots to build a display manager (or anything else that already has a buffer ready for presentation).
+1, the explicit synchronization protocol will be merged soon in wayland-protocols
+1 |
I've always wanted |
I thought I'd go into more detail about something I want to do as part of this, which I briefly mentioned on IRC. Basically, I was thinking that we could move all of the This isn't actually that different to how it currently works, since the renderer handles
With all of this living inside the renderer, // It doesn't matter how this buffer was made; the renderer knows about it.
struct wlr_texture *wlr_texture_from_wl_buffer(struct wlr_renderer *renderer, struct wl_resource *buffer);
void wlr_texture_apply_damage(struct wlr_texture, pixman_region32_t *damage); |
After more thought and investigation about how struct wlr_texture *wlr_texture_from_surface(struct wlr_renderer *renderer, struct wlr_surface *surface); and the Although there are a few things that probably need to be thought out more, particularly involving buffer releases and possibly using older versions of a client's buffer. |
Can you speak to some of the rationale behind that constraint? |
The explicit sync protocol works per-commit and is defined in terms of a wl_surface. Perhaps something like /*
* Texture is no longer something we render directly with, but is really a container for dealing with
* the rendering part of a wlr_surface. We could change the name.
*/
struct wlr_texture *wlr_texture_from_surface(struct wlr_renderer *renderer, struct wlr_surface *surface);
/*
* This is what we actually render with. It's not the same as the wlr_buffer which currently exists,
* but I like this name, because it corresponds to a wl_buffer.
* It will return the latest frame ready for rendering. All older frames that aren't referenced are also released.
* It's reference counted.
*/
struct wlr_buffer *wlr_texture_get_buffer(struct wlr_texture *tex);
struct wlr_buffer *wlr_buffer_ref(struct wlr_buffer *buffer);
// -1 if there is no fence
void wlr_buffer_release(struct wlr_buffer *buffer, int release_fence); |
sway and waymonad at the very least already have a "last usable buffer" kinda concept for the atomic tree update stuff. |
Initial renderer v6 redesign merged for DRM and headless. Will work on Wayland and X11. |
The cursor surface still uses a wl_egl_window. References: swaywm#1352
The cursor surface still uses a wl_egl_window. References: swaywm#1352
Now that I've done the (yet-to-be-merged) work to convert all backends to For this to happen, we need a few things to happen:
I hope we can at some point get rid of the per-plane formats getters and replace them with per-layer feedback the backend could send. That way this could be useful for regular clients too via dmabuf-hints. |
The cursor surface still uses a wl_egl_window. References: swaywm#1352
The cursor surface still uses a wl_egl_window. References: swaywm#1352
The cursor surface still uses a wl_egl_window. References: swaywm#1352
The cursor surface still uses a wl_egl_window. References: swaywm#1352
The cursor surface still uses a wl_egl_window. References: swaywm#1352
I've started implementing the plan outlined above in #2507 and #2505. Unfortunately because of multi-GPU support it doesn't seem like we'll be able to completely remove the renderer bits from the DRM backend. The compositor only uses the primary GPU for rendering. Someone needs to blit the buffers to the secondary GPUs. We'll need a new plan once we expose everything to compositors. Maybe expose the secondary GPUs, let the compositors handle the blit, and integrate the logic into a helper? |
The cursor surface still uses a wl_egl_window. References: swaywm#1352
The cursor surface still uses a wl_egl_window. References: #1352
Just another part of swaywm#2624 and swaywm#1352 that I felt needed to be done. Breaking change: Both EGLint *config_atrribs and egl->config no longer exist.
Just another part of swaywm#2624 and swaywm#1352 that I felt needed to be done. Breaking change: Both "EGLint *config_attribs" and "egl->config" no longer exist.
Just another part of swaywm#2624 and swaywm#1352 that I felt needed to be done. Breaking change: Both "EGLint *config_attribs" and "egl->config" no longer exist.
Just another bit of EGL housekeeping done for swaywm#1352 and swaywm#2624. Breaking changes: "wlr_egl_context->draw_surface" and "wlr_egl_context->read_surface" have been deleted and no longer exist.
Just another part of swaywm#2624 and swaywm#1352 that I felt needed to be done. Breaking change: Both "EGLint *config_attribs" and "egl->config" no longer exist.
Just another bit of EGL housekeeping done for swaywm#1352 and swaywm#2624. Breaking changes: "wlr_egl_context->draw_surface" and "wlr_egl_context->read_surface" have been deleted and no longer exist.
Just another bit of EGL housekeeping done for swaywm#1352 and swaywm#2624. Breaking changes: "wlr_egl_context->draw_surface" and "wlr_egl_context->read_surface" have been deleted and no longer exist.
Just another bit of EGL housekeeping done for swaywm#1352 and swaywm#2624. Breaking changes: "wlr_egl_context->draw_surface" and "wlr_egl_context->read_surface" have been deleted and no longer exist.
Just another bit of EGL housekeeping done for swaywm#1352 and swaywm#2624. Breaking changes: "wlr_egl_context->draw_surface" and "wlr_egl_context->read_surface" have been deleted and no longer exist.
This is now done. |
I've been doing some casual research into some DRM/Vulkan related stuff and came up with an idea.
With the changes required to the renderer for Vulkan etc., there is going to be a very significant difference between the rendering paths of the DRM backend and the rest of them, where we need to handle buffers ourselves in DRM, and use a provided swapchain (EGLSurface or VkSurface+VkSwapchain) for the others.
Having two code paths is kind of crap, so why don't we just use one?
Basically, we throw EGLSurfaces/VkSurface/VkSwapchains out entirely, and instead write our own swapchain.
We allocate two (or more?) GBM buffers, wrap them in our swapchain, and use the appropriate backend-specific way to display it. This can work for all backends, not just DRM.
Wayland
Use
zwp_linux_dmabuf_v1
and maybewp_presentation
directly.This does require the DRM render node to be given to us, which is supposed to come in the next version of the protocol.
zwp_linux_explicit_syncronization
would also be relevant, whenever that ends up being done.X11
Use the
dri3
andpresent
extension directly. The dri3 extension can give us the DRM render node.DRM
Business as usual.
Headless
Just pick some arbitrary render node and use that.
Potential future backends
GBM buffers are essentially dmabufs, so any backend which can handle dmabufs can work.
They're also mmapable, so this doesn't exclude purely software based backends and renderers.
Advantages
Disadvantages
I've already done some investigation to how to do it on X11, and it doesn't seem that hard. I'm sure everyone also understands Wayland, so that's easy too.
The text was updated successfully, but these errors were encountered: