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

Laggy mouse when screen sharing on 4K resolution #66

Closed
zsolt-donca opened this issue Nov 11, 2020 · 17 comments · Fixed by #74
Closed

Laggy mouse when screen sharing on 4K resolution #66

zsolt-donca opened this issue Nov 11, 2020 · 17 comments · Fixed by #74
Assignees
Labels
enhancement New feature or request

Comments

@zsolt-donca
Copy link
Contributor

When starting screen sharing from a browser with WebRTC, the mouse cursor gains a significant lag on the display that is being shared. My other screen doesn't seem to be affected, the mouse cursor works just fine over there, even while the screen sharing is being active. Stopping the screen sharing makes the lag disappear.

I am using two 4K displays. This is probably related to the 4K resolution, as if I switch the resolution of one of the displays to 1920x1080 and share that display, the mouse cursor is moving perfectly smooth.

This lag also feels when typing on the keyboard, so I think it's a general input lag problem, and not just specific to the mouse.

I made a screenshot of htop with the screen sharing being active on the other screen. It It shows sway, firefox, xdg-desktop-portal-wlr being the biggest CPU users:

screenshot_2020-11-09_19-30-31_735861790

For comparison, the mouse is not laggy when on GNOME in Wayland mode (tested with a Fedora 33 live image), nor in Xorg mode. I wouldn't mind the relatively high CPU usage if there wasn't this input lag.

Another related question: why can I share only one of my displays? When the browser prompts, there is only a single display being available. It happens to be my "main" display, so actually it's fine for me, I'm just curious.

I also mentioned this in #65 .

@emersion
Copy link
Owner

Screen sharing disables hw cursors.

swaywm/wlroots#2091 may help wrt. Sway CPU usage.

@zsolt-donca
Copy link
Contributor Author

zsolt-donca commented Nov 11, 2020

I see, I guess making the operations asynchronous will help also with the input lag issue. I wonder in what stage that ticket and the associated MR is, but I will ask in there.

Just for the record, GNOME's Wayland compositor (Mutter, I think) doesn't have this issue. I guess somebody could take a look at how this problem is solved over there, maybe the same solution applies here as well.

What about the fact that there is only a single monitor available for screen share? Is that a known limitation? If not, I would happily open another ticket with that issue also.
UPDATE: In the meantime I've found #12 which I believe is exactly about this inability to select the output for sharing.

I'll keep this questions open for a couple of days, incase some further insight comes with regards to the input lag issue.

@emersion
Copy link
Owner

Maybe GNOME never disables hw cursors when screensharing, but I don't think it should make that big of a difference...

@solarkraft
Copy link

solarkraft commented Nov 23, 2020

I have the same issue and while I don't understand much about the technology behind it I've made some observations that may be note worthy:

  • The cursor on the other screen is only smooth until something on the shared screen changes (for the amount of time there is change).

  • Recording using wf-recorder is much smoother

  • Neither CPU nor GPU usage (measured with intel_gpu_top) increase noticeably when the screen is shared (wf-recorder seems to use a full core)

I don't really care much about sharing my screen at full 4K resolution, by the way, it only worsens the compression when the video goes through the network. Maybe there is any way to do down scaling early to improve performance?

@danshick
Copy link
Collaborator

  • Recording using wf-recorder is much smoother

wf-recorder may default to export-dmabuf these days. Or ratelimit the screen capture. Not sure. We request frames as fast as the compositor can give them (after we copy them for pipewire). Could be a performance bottleneck. It would be a good idea to add some debugging output regarding framerate.

Maybe there is any way to do down scaling early to improve performance?

You could always change your output geometry first. That's probably the best option for performance. We're trying to do minimal video processing in xdpw (all we do now is y_invert the frames as they come in upside down)

@emersion
Copy link
Owner

wf-recorder may default to export-dmabuf these days

No, wf-recorder can only pump out shm frames from the compositor.

@zsolt-donca
Copy link
Contributor Author

Sorry for insisting on this subject, but I still don't get it: what is causing the mouse lag? If there is no significant CPU nor GPU usage, then what is it? Is there a way for me to do debugging (maybe active some debug logs), or some kind of profiling to figure it out?

Also, if it's related to the disabling of the hardware mouse cursor, is there any way of working around it? Also, what is the reason for it? Is it that otherwise the cursor wouldn't appear on the recording?

@danshick
Copy link
Collaborator

danshick commented Dec 3, 2020

My only guess would be that calling screencopy with a software cursor and no rate limiting is slowing down the rendering loop, but I honestly have no idea. I don't have any 4k displays and I can't reproduce at 1920x1080. You could try adding an artificial delay between frames. I'm pretty sure wayvnc does this if you are looking for an example.

You can enable debug (or even trace) logging if you like. You need to start xdpw manually as described in the FAQ and the help text will tell you what options you have. Trace logs do print on every single frame, but we don't include timing information, so you' have to do something clever to determine a frame rate. You could also add some code to calculate a running frame rate. Again, something similar is done in wayvnc.

@zsolt-donca
Copy link
Contributor Author

@danshick You are probably right on this one: I just tried wayvnc, and the mouse lag is almost non-existing (maybe it's not even there at all and I'm just imagining it). I checked out the source code also, and the delay seems to be implemented in a pretty straightforward way. I will give it a try.

@danshick
Copy link
Collaborator

... the delay seems to be implemented in a pretty straightforward way. I will give it a try.

Let me know how it goes. We'd happily accept a PR to rate limit the frames if it helps.

zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to rate-control the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to control the rate of the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.

Added code to measure the average FPS every 5 seconds and print it with
DEBUG level.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Dec 25, 2020
The goal is to control the rate of the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.

Added code to measure the average FPS every 5 seconds and print it with
DEBUG level.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Jan 10, 2021
The goal is to control the rate of the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.

Added code to measure the average FPS every 5 seconds and print it with
DEBUG level.
@scutze
Copy link

scutze commented Jan 24, 2021

I had the same problem with input from a wacom pen. Drawing whilst screen sharing on 4K led to lag and jerky lines. zsolt-donca's implementation seems to solve the issue for me.

@danshick
Copy link
Collaborator

Thanks for the feedback. As soon as one of us has time to review that PR, it will be considered for merging.

@nagisa
Copy link

nagisa commented Jan 28, 2021

Adding some more information – my screen is not quite 4k, but has higher resolution than 2k. I found that when just one webrtc capturing session is active (via pipewire/wlr portal) then the slowdown is not very noticeable, but gets worse as more capture sessions are started.

My very naive guess, without looking at the code, would be that the frame buffers are being re-acquired anew for each stream/session/whatever they are called, thus slowing down sway. It that is indeed the case, I imagine that this could be mitigated to an extent by copying buffers inside the portal for each session?

@emersion
Copy link
Owner

Ah, that's a lot of pixels for CPU copies.

swaywm/wlroots#2091 should help the compositor.

@danshick
Copy link
Collaborator

My very naive guess, without looking at the code, would be that the frame buffers are being re-acquired anew for each stream/session/whatever they are called, thus slowing down sway. It that is indeed the case, I imagine that this could be mitigated to an extent by copying buffers inside the portal for each session?

Actually, in xdpw, as long as you are streaming the exact same output with the exact same settings (at the moment, this just means pixel format and cursor on or off, until output selection is implemented) we only push the contents of the buffer to pipewire once. Each new session that is started shares the exact same pipewire node, so there is no additional copying on our side with each additional session.

That said, what the downstream apps do with those buffers is likely to add latency regarding how quickly pipewire can recycle those buffers. I wouldn't expect this to cause noticeable jitter in your compositor though. That's surprising.

Thanks for the info.

@danshick danshick added the bug Something isn't working label Feb 2, 2021
@danshick danshick added the enhancement New feature or request label Feb 2, 2021
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Feb 12, 2021
The goal is to control the rate of the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.

Added code to measure the average FPS every 5 seconds and print it with
DEBUG level.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Feb 16, 2021
The goal is to control the rate of the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.

Added code to measure the average FPS every 5 seconds and print it with
DEBUG level.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Mar 4, 2021
The goal is to control the rate of the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.

Added code to measure the average FPS every 5 seconds and print it with
DEBUG level.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Mar 5, 2021
The goal is to control the rate of the capturing, as it can represent a
performance issue and can cause a laggy mouse; see emersion#66.

The delay for the current frame is based on the time it took to capture
the previous frame. The targeted frame rate is a constant.

Added code to measure the average FPS every 5 seconds and print it with
DEBUG level.
zsolt-donca added a commit to zsolt-donca/xdg-desktop-portal-wlr that referenced this issue Mar 8, 2021
The goal is to control the rate of capture while in screencast, as it
can represent a performance issue and can cause input lag and the
feeling of having a laggy mouse.

This commit addresses the issue reported in emersion#66.

The code measures the time elapsed to make a single screen capture, and
calculates how much to wait for the next capture to achieve the targeted
frame rate. To delay the capturing of the next frame, the code
introduces timers into the event loop based on the event loop in
https://github.com/emersion/mako

Added a command-line argument and an entry in the config file as well
for the max FPS. The default value is 0, meaning no rate control.

Added code to measure the average FPS every 5 seconds and print it with
DEBUG level.
emersion pushed a commit that referenced this issue Mar 8, 2021
The goal is to control the rate of capture while in screencast, as it
can represent a performance issue and can cause input lag and the
feeling of having a laggy mouse.

This commit addresses the issue reported in #66.

The code measures the time elapsed to make a single screen capture, and
calculates how much to wait for the next capture to achieve the targeted
frame rate. To delay the capturing of the next frame, the code
introduces timers into the event loop based on the event loop in
https://github.com/emersion/mako

Added a command-line argument and an entry in the config file as well
for the max FPS. The default value is 0, meaning no rate control.

Added code to measure the average FPS every 5 seconds and print it with
DEBUG level.
@zsolt-donca
Copy link
Contributor Author

To anybody affected by this issue: #74 was merged that allows you to control the rate with which the frames are captured, reducing the load on the compositor and thus mitigating this issue. It is not a proper solution, as you sacrifice the ability to faithfully capture your screen.

To apply the rate control, you either need to manually start xdg-desktop-portal-wlr with the -f N argument, where N is the desired frames per seconds value, e.g. -f 10 for 10 frames per second. Alternatively, you can create a config file at ~/.config/xdg-desktop-portal-wlr/config with something similar:

[screencast]
output_name=
max_fps=10

@danshick
Copy link
Collaborator

danshick commented Mar 8, 2021

Thanks @zsolt-donca for your great work! I'll close this issue as this is the best solution we could ask for until #9 is resolved.

@danshick danshick closed this as completed Mar 8, 2021
@danshick danshick removed the bug Something isn't working label Mar 8, 2021
@danshick danshick linked a pull request Mar 8, 2021 that will close this issue
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

Successfully merging a pull request may close this issue.

6 participants