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

Support XDG Desktop Portal / Pipewire screencasting #16

Open
5 of 10 tasks
Ferdi265 opened this issue Jan 7, 2023 · 13 comments
Open
5 of 10 tasks

Support XDG Desktop Portal / Pipewire screencasting #16

Ferdi265 opened this issue Jan 7, 2023 · 13 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@Ferdi265
Copy link
Owner

Ferdi265 commented Jan 7, 2023

This is the "standard" screencasting method for wayland. It's less convenient than the two sway-specific protocols in that you cannot specify the monitor or region directly, but it is the only method that will work on all compositors.

Tasks related to less direct selection of capture targets:

  • allow specifying no monitor if xdg-portal backend is chosen
  • research how region selection could work with xdg-portal
  • allow selecting a window to capture if supported by the portal implementation

Implementation Tasks:

  • Add DBus library (sd-bus / basu)
  • Add Screencast portal client code
  • add libpipewire
  • add PipeWire client code for creating a stream
  • implement PipeWire format negotiation
    • partially implemented, advertised formats are no longer hardcoded, but the number of advertised formats still is hardcoded due to issues with spa_pod_builder
  • add dmabuf code for taking stream frames and passing them to EGL
    • code for dmabuf is there, basic PoC works
  • add SHM code for taking screen frames and passing them to EGL (as fallback)
@Ferdi265 Ferdi265 added the enhancement New feature or request label Jan 7, 2023
@Ferdi265 Ferdi265 self-assigned this Jan 7, 2023
@Ferdi265
Copy link
Owner Author

Ferdi265 commented Jan 7, 2023

Current progress tracked in branch feature-xdg-portal

@Ferdi265
Copy link
Owner Author

Current status: the initial codebase is there, but rendering the imported DMA-BUF still seems to fail in some way (the resulting texture is black).

Currently unimplemented are stream format negotiation and shm buffers. Of course this also needs to be cleaned up a whole lot and made more robust.

@Ferdi265 Ferdi265 added the help wanted Extra attention is needed label Jun 21, 2023
@Ferdi265
Copy link
Owner Author

Ferdi265 commented Oct 27, 2023

I'm currently at a dead end; none of the debug info provided by MESA / GL is of any help to me right now (most debug flags don't output anything, since there aren't any GL errors, and the driver specific debug flags vomit out endless parameter dumps that aren't very useful), and the import of the DMA-BUF from pipewire succeeds, but drawing results in a black screen.

I am not sure where the problem is, but so far I have only tested this on an Intel system. If you would like to test this, use these commands:

git checkout feature-xdg-portal
cmake . -B build -DWITH_XDG_PORTAL_BACKEND=ON
cd build
make
./wl-mirror -v -b xdg-portal eDP-1

If this results in anything other than a black screen on your system, please let me know.

@Ferdi265
Copy link
Owner Author

Ferdi265 commented Nov 2, 2023

I recently found some ugly use after free bugs in my pipewire feature branch, but after fixing those the black screen is still there, so that was not the cause it seems.

@Kaboom22
Copy link

Kaboom22 commented Jan 1, 2024

Just compiled this branch (feature-xdg-portal) and tried this on my all AMD system

OS: Pop!_OS 22.04 LTS x86_64
Kernel: 6.6.6-76060606-generic
DE: GNOME 44
WM: Mutter
CPU: AMD Ryzen 9 7950X3D (32) @ 5.759GHz
GPU: AMD Radeon 5700 XT
Wayland

the only unlisted requirement i needed to compile was "libdrm-dev". When running ./wl-mirror -v -b xdg-portal HDMI-A-1 (or anything else for that matter) i get:

debug: main::main(): initializing stream
debug: main::main(): initializing wayland
debug: wayland::on_registry_add(): wl_compositor (version = 5, id = 1)
debug: wayland::on_registry_add(): wl_drm (version = 2, id = 2)
debug: wayland::on_registry_add(): wl_shm (version = 1, id = 3)
debug: wayland::on_registry_add(): wl_output (version = 2, id = 4)
error: wayland::on_registry_add(): wl_output received before xdg_output_manager
debug: main::cleanup(): deallocating resources
debug: wayland::cleanup(): destroying wayland objects
Segmentation fault (core dumped)

If i put the block with comment "// create xdg_output object" before the block with "// check for xdg_output_manager" i get:

debug: main::main(): initializing stream
debug: main::main(): initializing wayland
debug: wayland::on_registry_add(): wl_compositor (version = 5, id = 1)
debug: wayland::on_registry_add(): wl_drm (version = 2, id = 2)
debug: wayland::on_registry_add(): wl_shm (version = 1, id = 3)
debug: wayland::on_registry_add(): wl_output (version = 2, id = 4)
Segmentation fault (core dumped)

But I'm not sure if that's any better. Happy to test anything you can do to get Gnome working 👍

@Ferdi265
Copy link
Owner Author

Ferdi265 commented Jan 2, 2024

Hi! Thanks for testing that branch!

the only unlisted requirement i needed to compile was "libdrm-dev"

Yes, the XDG portal branch AFAIK depends on the headers for libdrm for the drm_fourcc.h header file for format codes. I need to either replace that or document the dependency.

error: wayland::on_registry_add(): wl_output received before xdg_output_manager

This is mainly because the registry event handling code was written very early on when I understood little about Wayland's object system. I need to rewrite that code significantly in order to make it more robust. GNOME sends globals in a different order than sway and wl-mirror currently does not handle that gracefully (on the TODO list).

This branch sadly doesn't work yet, even on sway, because of a really weird black screen issue with EGL / pipewire / DMA-BUFs that I haven't been able to figure out the cause of.

Also, even if this branch works, you probably won't be able to move/resize the window on GNOME, since wl-mirror does not have client-side window decorations (yet). This is fixed in the feature-libdecor branch though, which will be merged soon.

TL;DR: There is still lots to do and a lot of stuff to fix, but progress is being made, and I hope I can get this to work in the near-ish future, but I can't guarantee anything since I'm pretty stuck with a basically undebuggable bug (the black screen).

@Kaboom22
Copy link

Kaboom22 commented Jan 2, 2024

A lack of move/resize or decor isn't a problem for me, my use case is copying a fake 4800X1200 monitor onto three real 1600X1200 monitors to create a Eyefinity setup that is robust without having to do a variety of tweaks and hacks for each game or doing weird X11 things that won't be future proof. Wl-mirror seems perfect for that as i can fit the window to the three monitors and copy the fake, and run the game in exclusive full screen to capture the input.

But anyway i won't hijack your thread, let me know if you need to test a debug build or something.

This was referenced Jan 31, 2024
@Ferdi265
Copy link
Owner Author

Ferdi265 commented Feb 9, 2024

My best guess for what is going wrong with the black screen in the feature-xdg-portal branch is the hacked-up format "negotiation" (hardcoded formats copied from OBS).

I need to rewrite that whole code to actually negotiate formats since that is likely what's causing the issues.

Documentation: https://docs.pipewire.org/page_dma_buf.html

@Ferdi265
Copy link
Owner Author

Ferdi265 commented Aug 6, 2024

I'm not sure what happened, but as of today, with sway-git 1.10.r7384.05e895c-1, wlroots-git 0.19.0.r7159.775817e27-1, and pipewire 1.2.2-1, the xdg-portal branch has magically started working!

I need to go back and clean it up, and also verify what the first versions are this works with, as well as test on more different GPU setups (testing this on my AMD integrated graphics right now).

@Ferdi265
Copy link
Owner Author

Ferdi265 commented Aug 6, 2024

Tested this together with Libdecor now, also works on KDE and Gnome (see #17)

@Ferdi265 Ferdi265 removed the help wanted Extra attention is needed label Aug 6, 2024
@Ferdi265 Ferdi265 added this to the v0.17.0 milestone Aug 6, 2024
@Ferdi265 Ferdi265 modified the milestones: v0.17.0, v0.18.0 Oct 14, 2024
@shiro
Copy link

shiro commented Dec 17, 2024

Just a random question since I was curious, would it be possible to specify a window as a source and only display a part of it (crop using region)?
This would allow showing just a portion of a window that's on another workspace, which as far as I know isn't possible without some overkill solutions like OBS.

@Ferdi265
Copy link
Owner Author

Ferdi265 commented Dec 17, 2024

Just a random question since I was curious, would it be possible to specify a window as a source and only display a part of it (crop using region)? This would allow showing just a portion of a window that's on another workspace, which as far as I know isn't possible without some overkill solutions like OBS.

with the XDG portal screenshare backend this should technically be possible (if the compositor supports window capture, which sway currently doesn't, but others do), though that's not finished yet. The main issue is that AFAIK we don't get the coordinates of the target window, so we can't easily know how to transform region coordinates from slurp(1) into the window's coordinate space. I'll try to find a workaround for this though, since region capture is an important feature IMO.

@Ferdi265
Copy link
Owner Author

quick development update on this: I don't currently have a lot of time for wl-mirror, so I'm falling a bit behind on actually rewriting this to be in a state that I can release, but at least it's no longer blocked on black-screen bugs that I don't understand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants