-
-
Notifications
You must be signed in to change notification settings - Fork 8.1k
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
linux-capture: proper DMA-BUF capability negotiation via PipeWire #5131
linux-capture: proper DMA-BUF capability negotiation via PipeWire #5131
Conversation
c3b4375
to
3ca3f28
Compare
3ca3f28
to
cb1a709
Compare
ff618eb
to
43b0718
Compare
Updated this MR with simpler EGL extension checks and dropping modifiers when we can't import them (issue: PipeWire won't trigger renegotiation on the compositor side, test https://github.com/columbarius/obs-studio/tree/egl-modifiers-vN-failure) |
43b0718
to
cc4f248
Compare
cc4f248
to
cdcbf60
Compare
Removed the last commit, since removing a EnumFormat didn't retrigger the format negotiation. This is expected to work as good as pre MR, since the importing wasn't touched, while negotiation from our side is more correct. Should I open a pipewire-dmabuf-next MR Draft, or just link the development branch? |
cdcbf60
to
fe5f6c6
Compare
cc: @GeorgesStavracas |
fe5f6c6
to
d1cb804
Compare
d1cb804
to
e22bc69
Compare
Updated the flatpak build and now it worked. This MR can be tested with flathub/com.obsproject.Studio#148 |
e22bc69
to
b862a30
Compare
b862a30
to
0264081
Compare
Rebased onto #5394 including some cleanup commits from @GeorgesStavracas. |
+1 Tested it with Plasma 5.23 and it's working seemingly okay and using the right path (unlike stable which is not going through dmabuf because of changes in pipewire handling of dmabuf). |
libobs-opengl/gl-egl-common.c
Outdated
query_dmabuf_modifiers(egl_display, drm_format, &modifier_list); | ||
|
||
brealloc(modifier_list, (num_modifiers + 1) * sizeof(uint64_t)); | ||
modifier_list[num_modifiers] = DRM_FORMAT_MOD_INVALID; |
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 feels somewhat like a thing that should be handled in another layer, e.g. in build_format()
in linux-capture: Announce supported modifiers via PipeWire
.
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 can't be done in build_format()
. The plugin doesn't have any clue which renderer is used. If obs would add a vulkan renderer in the future adding the token for implicit modifier would be false. So we either add it at the end of the list returned by query_modifiers or we need another call to the renderer to query if implicit modifiers are supported.
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.
My personal choice would be to let the renderer tell whether implicit modifiers are supported, so that the PipeWire bits can deal with this particularity.
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 tried minimizing the change in the renderer API, but I'm totally fine with adding a separate call returning a bool for implicit modifier supported, keeping the query function modifier aware only.
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.
Maybe best consult maintainers, I'm just a fly-by reviewer here :P
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.
Generally I would prefer we export with the same semantics as the egl/gl functions we are calling unless we have a good reason to modify them for keeping state consistent in libobs. For these platform specific bits I think theres even more reason to not introduce our own semantics.
While it seems convenient to build the whole list of formats and their modifiers, its probably safest to simply export the QueryFormat and QueryModifier functions separately on the graphics subsystem and build these lists in the pipewire code.
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.
Ok so I'll design the API to be close to the egl functions and add additional bool functions to check for available extensions.
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.
Do we need to provide a way to query extensions? If we return no modifiers when obs detects the extensions are not available then users can fallback to modifierless gracefully without the additional check? Or is there still a need to know if the driver supports the modifier extensions?
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.
Support for implicit modifiers in EGL is defined by the existence of an extension. But I think a bool function _implicit_modifier_available
would be better, checking that required extension internally.
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 the new API with 3 functions close enough to the EGL functions or do you want the same signature?
Which commits are specific to this PR? At this point there are so many prs for this in flight im not sure what is associated with what. |
plugins/linux-pipewire/pipewire.c
Outdated
uint8_t params_buffer[1024]; | ||
const struct spa_pod **params = NULL; | ||
uint32_t n_params; | ||
uint8_t params_buffer[2048]; |
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.
How many format x modifiers can we fit in this?
libobs-opengl/gl-egl-common.c
Outdated
query_dmabuf_modifiers(egl_display, drm_format, &modifier_list); | ||
|
||
brealloc(modifier_list, (num_modifiers + 1) * sizeof(uint64_t)); | ||
modifier_list[num_modifiers] = DRM_FORMAT_MOD_INVALID; |
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.
Looking at the previous commits, it seems that modifierless is already handled in the pipewire code separately as suggested. Is the point here to try and merge the modifierless and modifierfull code paths? If so we should remove the modifierless checks in the pipewire code.
c861537
to
a059e50
Compare
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.
Some more comments. This is shaping up nicely!
a059e50
to
4997142
Compare
Note: dbus decided to strike today and every screencast request is ended by a |
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.
One more round
4997142
to
c3b702a
Compare
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.
There is one question / comment, the rest is just nitpicking.
One question: with this pull request, what would happen if the host system has PipeWire 0.3.40, but the compositor still negotiates DMA-BUFs the "old" way (i.e. without explicit / implicit modifiers)? |
The old way should still work as before. I removed the strict checking at some point and I would like to reintroduce it again and force everyone to do it correctly (insert evil laughter), but unless it creates problems, we should just announce both. (See https://github.com/obsproject/obs-studio/pull/5131/files#diff-ede22eaf772c418b60991eed2e7a76f8dcb41ee8400f188d8ca1cb5fb0de7a6fR783) |
c3b702a
to
d029d53
Compare
It was naive to add these defines here to avoid a direct include when the entire platform already depends on the DRM subsystem. Just include it and let it provide the image formats.
When sharing DMA-BUFs it is required the announce the underlying hardware capabilities via supported modifiers. Add new device_query_dmabuf_capabilities vfunc to gs_exports and connect it to the egl implementation stubs in the supported render platforms. Add a new public method gs_query_dmabuf_capabilities() that calls the vfunc above. Add new device_query_dmabuf_modifiers vfunc to gs_exports and connect it to the egl implementation in the supported render platforms. Add a new public method gs_query_dmabuf_modifiers() that calls the vfunc above.
Implement device_query_dmabuf_capabilities and device_query_dmabuf_modifiers for EGL/Wayland and EGL/X11.
We require PipeWire 0.3.33 or later to make use of the introduces flags `SPA_POD_PROP_FLAG_MANDATORY` and `SPA_POD_PROP_FLAG_DONT_FIXATE`, which are required for the negotiation process introduced in the following commits.
Sharing DMA-BUFs via PipeWire requires the client to announce all formats together with their supported modifiers. [1] [1] https://docs.pipewire.org/page_dma_buf.html
We require PipeWire 0.3.40 or later in preparation for proper DMA-BUF handling, which includes negotiation of modifier lists and dropping of single modifiers. This commit should be reverted as soon as the Freedesktop Flatpak SDK contains this or a newer PipeWire version.
Importing a DMA-BUF can fail even if the renderer announces support for the used format modifier pair. This can be caused by a number of reasons specific to the underlying hardware and api [1]. In that case we want to remove that modifier from our list of supported ones and renegotiate. This feature was added in PipeWire 0.3.40. On previous versions the best we can do is drop all modifiers an fallback to DMA-BUF with another format or directly to the SHM buffer transport. This mechanism is demonstrated in [2]. [1] https://xdc2020.x.org/event/9/contributions/615/attachments/704/1301/XDC_2020__Allocation_Constraints.pdf [2] https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/src/examples/video-play-fixate.c
Proper DMA-BUF format and modifier negotiation is possible with PipeWire 0.3.40. This commit adds checks for older versions and allows to build against them. These are classified as follows: * PipeWire server older than 0.3.24: Restrict to SHM only * PipeWire server between 0.3.24 (incl.) and 0.3.40: Announce modifiers along with the old method. On failed import drop all modifiers. * PipeWire server 0.3.40 and newer: Announce modifiers along with the old method. On failed import drop only a single modifier.
Ubuntu 21.10 provides PipeWire 0.3.32 which is missing the `SPA_POD_PROP_FLAG_DONT_FIXATE` required for proper DMA-BUF negotiation. Since this isn't implemented in the DE's of this Ubuntu version just defining this flag won't have any impact. Revert after support for Ubuntu 21.10 ended.
d029d53
to
4e587a0
Compare
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.
Took the liberty to push a small tweak, and I think this is good to go now
Fine with that! We are currently using the PipeWire default value and it seamed to work, so the thing underneath might just behave fine. One last thing: could you please check what the "default" value for the modifier (as received in the old negotiation style) is? https://github.com/obsproject/obs-studio/pull/5131/files#diff-ede22eaf772c418b60991eed2e7a76f8dcb41ee8400f188d8ca1cb5fb0de7a6fL572 For the old negotiation style we should force that value to be either linear or implicit modifier. |
My bad, I see there was a stable xdp release and it's working fine 💪 |
Description
This MR implements the negotiation for sharing of DMA-BUFs via PipeWire as described in https://docs.pipewire.org/page_dma_buf.html.
This MR follows up on #5221 by adding capabilities to query all modifiers supported by the renderer.
This query was implemented for EGL based renderers.
Motivation and Context
For proper DMA-BUF capability negotiation it is important, that both clients announce there capabilities by the means of a list of supported modifiers for a given format. Since PipeWire 0.3.33 we have the possibility to announce such a list per format and assure that it will not be mixed up with the capabilities of SHM buffer transport, which is distinguished by not announcing the modifier key.
This MR is required for obs to be able to use DMA-BUF transport via PipeWire with Wayland compositors after the mentioned MRs in the tested section have been merged.
How Has This Been Tested?
This can/will (be able to) be tested with:
Types of changes
Checklist:
Requires: #5221
Requires: #5585
Requires: PipeWire 0.3.33
Split into 3 Feature sets wrt. PipeWire version: