Commit Graph

1796 Commits

Author SHA1 Message Date
Geoffrey McRae
8974ae4fb5 [client] add SVG loading support and use icons for status display
This brings nanosvg into the project for SVG loading and rendering.
Unfortunatly we can not at this time use a submodule for this project
until https://github.com/memononen/nanosvg/pull/214 is merged.
2022-05-26 04:11:31 +10:00
Geoffrey McRae
8aa36144dc overlay: move init/free to the context of the render thread
This is done to allow overlays to make use of the renderer during
init/free.
2022-05-26 00:46:13 +10:00
Geoffrey McRae
6384a8d006 [client] main: fix race condition on usage of events 2022-05-24 11:06:47 +10:00
Geoffrey McRae
d1e421f8a8 [client] spice: delay showing the spice display until spice is ready 2022-05-24 09:48:54 +10:00
Geoffrey McRae
6cbfa6e734 [client] egl: add spice display support 2022-05-24 06:57:33 +10:00
Geoffrey McRae
faae785c44 [client] spice: initialize new surfaces to black 2022-05-24 00:17:08 +10:00
Geoffrey McRae
b2221b114e [client] spice: more fixes to video source transition 2022-05-24 00:05:22 +10:00
Geoffrey McRae
47b2a26898 [client] app: better handling of transition to/from spice display 2022-05-23 22:35:27 +10:00
Geoffrey McRae
b5dfbcb5a2 [client] egl: added missing case from texture init 2022-05-23 20:55:02 +10:00
Geoffrey McRae
247e867f18 [client] egl: implemented SPICE display support 2022-05-22 18:19:58 +10:00
Geoffrey McRae
6699018ed1 [client] egl: check for null before free 2022-05-22 12:05:02 +10:00
Geoffrey McRae
947db38bc9 [client] egl: fix mistake in rect clamping 2022-05-22 11:53:46 +10:00
Geoffrey McRae
16f39450b5 [client] spice: added initial framework for spice display fallback 2022-05-22 11:45:11 +10:00
Geoffrey McRae
ffd27ac82c [client] update PureSpice submodule 2022-05-22 11:14:48 +10:00
Geoffrey McRae
1fcdcc8725 [client] egl: allow for partial texture updates 2022-05-21 21:21:16 +10:00
Geoffrey McRae
2901e7aec5 [client] egl: only upload the damage rects if they actually changed
Profiling shows that a considerable amount of time is spent in
glBindBuffer and glBufferSubData when the damage rects are updated.
Since the amount of data here is quite small it's far faster to check if
it's different then to just blindly overwrite the buffer on each call.

Profiled on an Intel CPU with UHD P630 Graphics using magic-trace
2022-05-17 00:51:13 +10:00
matthewjmc
53c843d9dd [common] Update framebuffer metadata + references 2022-05-16 20:01:09 +10:00
Geoffrey McRae
d7704b13c0 [client] x11: set window posision before entering fullscreen
This fixes an issue where the window position would be ignored if the
application was launched in full screen mode from the command line
causing the client to enter full screen on the wrong monitor in
multi-monitor configurations.
2022-05-15 20:41:06 +10:00
Geoffrey McRae
81aa24d4d3 [client] overlay/config: general UX changes
* Moved the LG license and version onto a seperate tab.
* Added general donation section and link to the website donation page
* Removed donation details under gnif's section
2022-05-15 17:16:07 +10:00
Geoffrey McRae
3b55ac5420 [client] x11: check for null data from XGetWindowProperty
This fixes a reported segfault when a window manager fails to provide
valid EWMH values.

Fixes #987
2022-05-15 16:38:17 +10:00
Geoffrey McRae
32fbcaffd2 [client] spice: fix spice shutdown race
Fixes #960
2022-05-15 16:28:37 +10:00
Geoffrey McRae
0a9a9ed57e [client] config: enhance input:escapeKey to accept a KEY_* string value
This makes it possible to define the escape key by name rather then just
it's integer code, while still allowing fallback to using an integer
value for codes that may not be defined.

Example: `input:escapeKey=KEY_F1`

An invalid string value will also print a list of all valid string
values.
2022-05-15 16:11:33 +10:00
Geoffrey McRae
0a768a5a7f [client] main: add new option for integer only upscaling
The new option `win:intUpscale` will limit upscaling to integer sizes
only if enabled.
2022-05-09 18:23:53 +10:00
Geoffrey McRae
6afd262a27 [client] egl: update AMD FSR to 1.0.2 2022-05-04 15:29:21 +10:00
Geoffrey McRae
7b7a06b63f [client] fix invalid bitwise comparison 2022-05-04 11:02:02 +10:00
Geoffrey McRae
eae559b4c9 [client/obs] update to support downscaled frames coming from the host 2022-05-01 19:51:25 +10:00
Netboy3
132d0e3c42 [client] audio/pw: pw_stream_get_time() deprecated
pw_stream_get_time() is deprecated in PipeWire 0.3.50.
Use pw_stream_get_time_n() instead based on PipeWire
library version.
2022-04-14 01:47:34 +10:00
Babbaj
6d06320fb2 [client] audio/pw: fix muting
Pipewire documents the mute parameter as a bool, however `pw_stream_set_control` expects a float value and converts it to a bool.

6ad6300ec6/src/pipewire/stream.c (L2063)
2022-04-09 16:19:11 +10:00
Quantum
f3fe774f69 [client] overlay/record: do not invalidate window during shutdown 2022-03-19 18:52:07 +11:00
Quantum
e053c014f7 [client] audio: display record indicator when necessary 2022-03-19 18:52:07 +11:00
Quantum
9c8a8a1b44 [client] config: add new option audio:micShowIndicator
This will be used to control the display of the microphone recording
indicator.
2022-03-19 18:52:07 +11:00
Quantum
1685249f3a [client] overlay: add record indicator 2022-03-19 18:52:07 +11:00
Quantum
97cef000fd [client] audio: avoid prompting when changing record format
If a recording is already in progress, we should not prompt again.
2022-03-19 15:10:39 +11:00
Quantum
8f45290beb [client] audio: cancel confirm dialog when a new recording starts 2022-03-19 10:04:23 +11:00
Quantum
9afe170413 [client] audio: prompt before allowing audio
If the user clicks no, the guest only receives silence.
2022-03-19 10:04:23 +11:00
Quantum
dd6d9c44df [client] config: add new audio:micAlwaysAllow option
This will be used to always grant access to microphones instead of
prompting every time.
2022-03-19 10:04:23 +11:00
Quantum
fb5a71c47e [client] audiodevs/pipewire: implement proper recording stop/restart
Before, pipewire_recordStop did nothing since pw.record.active was
always false.
2022-03-19 10:04:23 +11:00
Quantum
75370e464d [client] overlay/msg: fix type for app_msgBoxClose
It should not be taking a pointer to MsgBoxHandle.

Also changed the type of MsgBoxHandle to prevent similar bugs.
2022-03-19 10:04:23 +11:00
Quantum
c55d0a82f2 [client] overlay: add support for confirmation dialogs 2022-03-19 10:04:23 +11:00
Quantum
f28084e653 [client] core: remove state tracking in core_updateOverlayState
The state is never updated when a message box is dismissed, so the
cursor is never displayed when a second message box shows up.

The only other caller, app_setOverlay, has state tracking already.
2022-03-19 10:04:23 +11:00
Geoffrey McRae
3a8cb6a613 [client/common] fixes for issues detected through static analysis. 2022-03-07 10:14:52 +11:00
Tudor Brindus
a3820536ab [client] overlay: make "Show timing graphs" checkbox consistent in case 2022-03-06 17:21:32 +11:00
Shootfast
48cf099638 [client] input: fix confine_pointer argument marshalling
Under Wayland, if the mouse pointer is disconnected whilst captured
(like say via KVM switch), the waylandWarpPointer code will be called
but the pointer will be NULL. This results in the cryptic message:

error marshalling arguments for confine_pointer (signature noo?ou): null value passed for arg 2
Error marshalling request: Invalid argument

This patch adds a check on the wlWm.pointer pointer before attempting
to warp the pointer, and avoids the crash.
2022-03-05 09:33:45 +11:00
Tudor Brindus
88d60d4b3d [client] enforce building with -Wstrict-prototypes 2022-02-28 11:56:26 +11:00
Tudor Brindus
3189c7bcd6 [client] kb: update for ImGui 1.87 2022-02-28 11:56:26 +11:00
Chris Spencer
72033f3822 [client] audio: reduce hardcoded minimum latency
The current minimum target latency is partially based upon the default qemu
behaviour whereby audio packets are delivered in a sawtooth pattern, with
packet timestamps drifting between 5ms above and below the measured clock.
This 5ms error is baked into the minimum target latency to avoid
underrunning.

This sawtooth pattern can be reduced by specifying a lower timer period in
the qemu configuration, so remove it from the hardcoded minimum latency and
add it to the default configurable buffer latency instead. This allows
users that have configured their VM appropriately to reduce the overall
latency.
2022-02-28 11:52:16 +11:00
Chris Spencer
c2523be4b4 [client] audio: reduce resampler latency
The best quality resampler has an intrinsic latency of about 3ms, and the
processing itself takes another 1-2ms per 10ms block. The faster setting
has an intrinsic latency of about 0.4ms, with about 0.04ms processing time.
This makes for an overall saving of about 4ms, with negligible loss in
quality.
2022-02-27 23:47:43 +11:00
Chris Spencer
7efc274e81 [client] audio: use block comments 2022-02-27 23:47:43 +11:00
Chris Spencer
7c2d493bb5 [client] audio: add latency tuning parameter
This adds a new `audio:bufferLatency` option which allows the user to
adjust the amount of buffering LG does over the absolute bare minimum. By
default, this is set large enough to absorb typical timing jitter from
Spice. Users may reduce this if they care more about latency than audio
quality.
2022-02-25 20:41:47 +11:00
Chris Spencer
9908b737b0 [client] audio: make the requested audio device period size configurable
This adds a new `audio:periodSize` option which defaults to 2048 frames.
For PipeWire, this controls the `PIPEWIRE_LATENCY` value. For PulseAudio,
the controls the target buffer length (`tlength`) value.
2022-02-25 20:41:47 +11:00
Chris Spencer
0dad9b1e76 [client] audio: fix latency calculation if audio device starts early
If the audio device starts earlier than required, we slew the read pointer
backwards to avoid underrunning. We need to apply this same offset to the
recorded device position, otherwise the Spice thread will think playback is
further ahead than it really is and inject unnecessary latency to
compensate.
2022-02-25 20:41:47 +11:00
Chris Spencer
a13c90bd27 [client] audio/pa: wait until stream is ready before starting playback
Uncorking the stream does not work if the stream is not ready yet.
2022-02-25 20:41:47 +11:00
Chris Spencer
84b5478b02 [client] audio/pa: fix assertion failure when keep alive playback stops
When the 'keep alive' playback times out, playback is stopped from the
audio callback, resulting in an assertion failure inside PulseAudio as we
try to lock the main loop thread while already inside it.
2022-02-25 20:41:47 +11:00
Tudor Brindus
91d6e3a82a [client] allow building with -Wstrict-prototypes
This is not yet turned on because cimgui does not build with it enabled.
2022-02-25 20:38:44 +11:00
Chris Spencer
d9dc399522 [client] audio/pw: request real-time priority
This is as per the PipeWire ALSA plugin [1]. The existing
`PW_STREAM_FLAG_RT_PROCESS` flag is misleading and doesn't really have
anything to do with real-time priority; it just tells PipeWire to pull data
from the application synchronously from its main processing thread. More
detail at [2].

[1] f5d47c079e/pipewire-alsa/alsa-plugins/pcm_pipewire.c
[2] https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2024
2022-02-14 15:11:43 +11:00
Chris Spencer
70158a64e7 [client] audio: open device earlier
The actual time between opening the device and the device starting to pull
data can range anywhere between nearly instant and hundreds of
milliseconds. To minimise startup latency, open the device as soon as the
first playback data is received from Spice. If the device starts earlier
than required, insert a period of silence at the beginning of playback to
avoid underrunning. If it starts later, just accept the higher latency and
let the adaptive resampling deal with it.
2022-02-14 15:09:13 +11:00
Geoffrey McRae
202116786c [client] main: fix invalid bit logic 2022-02-10 20:42:25 +11:00
Geoffrey McRae
8b4551c39c [all] convert KVMFR frame bools to flags in a bitfield
This will allow us to add additional flags in the future while remaining
backwards compatible with the host.
2022-02-10 20:32:38 +11:00
Geoffrey McRae
29698362ed [client] x11: added request activation support 2022-02-10 20:20:34 +11:00
Geoffrey McRae
f24db8d0cd Revert "[client] x11: check if the EWMH atoms exist before using them"
This reverts commit cfd2e6ff32.
2022-02-10 13:36:40 +11:00
Geoffrey McRae
cfd2e6ff32 [client] x11: check if the EWMH atoms exist before using them 2022-02-10 13:35:19 +11:00
Chris Spencer
e96311eb7b [client] audio: keep audio device open after playback
We can set the startup latency for the next playback far more precisely if
we have the device open already.

Only keep the device open with no playback for 30 seconds to avoid keeping
the device open unnecessarily forever.
2022-02-10 07:50:01 +11:00
Chris Spencer
0d97a51802 [client] audio: increase startup latency
Underruns can still happen quite easily at the beginning of playback,
particularly at very low latency settings. Further increase the startup
latency to avoid this.
2022-02-10 07:50:01 +11:00
Netboy3
e0c0451b52 [client] x11: Add inline icon
Many X11 window managers will present an application on their
taskbar as a combination of the application name and an icon
imagery pulled from the X-Property _NET_WM_ICON. Applications
built under frameworks such as Qt or GTK have this property
populated by the framework. This commit adds the Atom _NET_WM_ICON
and populates it with a 64x64 icon of Looking Glass.
2022-02-09 12:07:55 +11:00
Tudor Brindus
e1ac838796 [client] wayland: use wayland-protocols from submodule 2022-02-08 16:05:51 +11:00
Geoffrey McRae
1cfbcba813 [client] main: fix failure to check KVMFR udata at connect 2022-02-08 15:50:22 +11:00
Paul Hollinsky
3890c72159 [client] egl: use texture sampler for desktop
The desktop doesn't need its own sampler, there is already an identically
configured one in the `desktop->texture`.

For some reason, using the texture sampler fixes a black screen issue
with my GTX 660 using the 470.86 driver. Maybe hitting some limit
for how many samplers can be allocated?
2022-02-08 15:34:54 +11:00
Paul Hollinsky
4223a5e38f [client] egl: remove extra sampler from TextureBuffer
It was unused, there is a sampler in EGL_Texture (base).
2022-02-08 15:34:54 +11:00
Tudor Brindus
fd28d0604e [host/client] kvmfr: request activation based on guest state 2022-02-08 15:27:27 +11:00
Tudor Brindus
9cd8027901 [client] main: request WM activation on first frame 2022-02-08 14:54:55 +11:00
Tudor Brindus
969ac4d1d1 [client] wayland: activate our window if we're allowed 2022-02-08 14:54:55 +11:00
Tudor Brindus
da548e3858 [client] ds: expose activation requesting 2022-02-08 14:54:55 +11:00
Tudor Brindus
21a349343b [client] wayland: implement activation request 2022-02-08 14:54:55 +11:00
Tudor Brindus
4ee6bdf198 [client] wayland: bind xdg_activation_v1 when available 2022-02-08 14:54:55 +11:00
Tudor Brindus
b13582a911 [client] wayland: build xdg-activation-v1 header 2022-02-08 14:54:55 +11:00
Chris Spencer
05ca59ed48 [client] audio/pw: increase startup latency
PipeWire startup latency varies wildly depending on what else is, or was
last using the audio device. In the worst case, PipeWire can request two
full buffers within a very short period of time immediately at the start of
playback, so make sure we've got enough data in the buffer to support this.
2022-02-04 16:27:12 +11:00
Chris Spencer
e1e60fdaa6 [client] audio: tune target latency
The target latency is now based upon the device maximum period size
(which may be configured by setting the `PIPEWIRE_LATENCY` environment
variable if using PipeWire), with some allowance for timing jitter from
Spice and the audio device.

PipeWire can change the period size dynamically at any time which must be
taken into account when selecting the target latency to avoid underruns
when the period size is increased. This is explained in detail within the
commit body.
2022-02-04 16:27:12 +11:00
Chris Spencer
ca29fe80a6 Revert "[client] audio: tune the target latency based on the latency jitter"
This reverts commit febd081202.

This causes severe underruns when the quantum size increases.
2022-02-04 16:27:12 +11:00
Geoffrey McRae
febd081202 [client] audio: tune the target latency based on the latency jitter 2022-01-28 12:11:56 +11:00
Geoffrey McRae
5bbc1d44bf [client] audio/pw: get the period size to determine when to start audio
Previously this was hardcoded to 100ms which is far too high in most
instances, instead we get the initial period size and use whichever is
greater out of 50ms or the period size.

The idea is to reduce the amount of time it takes for the latency to
come down after initial stream start.
2022-01-28 12:08:58 +11:00
Geoffrey McRae
22b968ff53 [client] audio: change the audio latency graph sample point
This removes the need for locking while also giving a better result in
the graph output. Also when the graph is disabled via the overlay
options it will no longer cause redraws.
2022-01-28 10:59:12 +11:00
Geoffrey McRae
a0477466d2 Revert "[client] audio: allow the audiodev to return the periodFrames"
This reverts commit 41884bfcc5.

PipeWire can change it's period size on the fly on us making this
approach invalid.
2022-01-28 10:00:35 +11:00
Geoffrey McRae
c2a766c2ee [client] audio: fix setfault due to failure to properly reset 2022-01-27 19:20:16 +11:00
Geoffrey McRae
a560a610d9 [client] audio: allow building without any audio support 2022-01-27 18:03:11 +11:00
Geoffrey McRae
a7db3d3a0f [client] audio: check for malloc failure 2022-01-27 18:03:11 +11:00
Geoffrey McRae
016001da67 [client] audio: cosmetics 2022-01-27 18:03:11 +11:00
Geoffrey McRae
41884bfcc5 [client] audio: allow the audiodev to return the periodFrames
This change allows the audiodevs to return the minimum period frames
needed to start playback instead of having to rely on a pull to obtain
these details.

Additionally we are using this information to select an initial start
latency as well as to train the desired latency in order to keep it as
low as possible.
2022-01-27 18:03:11 +11:00
Chris Spencer
dd2d84a080 [client] audio: adjust playback speed to match audio device clock
This change is based on the techniques described in [1] and [2].

The input audio stream from Spice is not synchronised to the audio playback
device. While the input and output may be both nominally running at 48 kHz,
when compared against each other, they will differ by a tiny fraction of a
percent. Given enough time (typically on the order of a few hours), this
will result in the ring buffer becoming completely full or completely
empty. It will stay in this state permanently, periodically resulting in
glitches as the buffer repeatedly underruns or overruns.

To address this, adjust the speed of the received data to match the rate at
which it is being consumed by the audio device. This will result in a
slight pitch shift, but the changes should be small and smooth enough that
this is unnoticeable to the user.

The process works roughly as follows:
1. Every time audio data is received from Spice, or consumed by the audio
   device, sample the current time. These are fed into a pair of delay
   locked loops to produce smoothed approximations of the two clocks.
2. Compute the difference between the two clocks and compare this against
   the target latency to produce an error value. This error value will be
   quite stable during normal operation, but can change quite rapidly due
   to external factors, particularly at the start of playback. To smooth
   out any sudden changes in playback speed, which would be noticeable to
   the user, this value is also filtered through another delay locked loop.
3. Feed this error value into a PI controller to produce a ratio value.
   This is the target playback speed in order to bring the error value
   towards zero.
4. Resample the input audio using the computed ratio to apply the speed
   change. The output of the resampler is what is ultimately inserted into
   the ring buffer for consumption by the audio device.

Since this process targets a specific latency value, rather than simply
trying to rate match the input and output, it also has the effect of
'correcting' latency issues. If a high latency application (such as a media
player) is already running, the time between requesting the start of
playback and the audio device actually starting to consume samples can be
very high, easily in the hundreds of milliseconds. The changes here will
automatically adjust the playback speed over the course of a few minutes to
bring the latency back down to the target value.

[1] https://kokkinizita.linuxaudio.org/papers/adapt-resamp.pdf
[2] https://kokkinizita.linuxaudio.org/papers/usingdll.pdf
2022-01-27 18:03:11 +11:00
Chris Spencer
599fdd6ffd [common] ringbuffer: add unbounded mode
In unbounded mode, the read and write pointers are free to move
independently of one another. This is useful where the input and output
streams are progressing at the same rate on average, and we want to keep
the latency stable in the event than an underrun or overrun occurs.

If an underrun occurs (i.e., there is not enough data in the buffer to
satisfy a read request), the missing values with be filled with zeros. When
the writer catches up, the same number of values will be skipped from the
input.

If an overrun occurs (i.e., there is not enough free space in the buffer to
satisfy a write request), excess values will be discarded. When the reader
catches up, the same number of values will be zeroed in the output.

Unbounded mode is currently unused since our audio input and output
streams are not synchronised. This will be implemented in a later commit.

Also reimplemented as a lock-free queue which is safer for use in audio
device callbacks.
2022-01-27 18:03:11 +11:00
Chris Spencer
b34b253814 [client] audio: stop playback immediately if new playback is started
If a new playback is started while the previous playback is still flushing,
we simply allow the stream to continue playing and effectively cancel the
flush. In general this is not safe because there may not be enough data in
the buffer to avoid underrunning. We could handle this better later by
trying to insert the right number of silent samples into the buffer, but
for now just completely stop the previous stream before starting the new
one.
2022-01-27 18:03:11 +11:00
Chris Spencer
68b42e1c1a [client] audio/pw: drop restarting state
Automatically restarting playback once draining has completed could result
in playback starting too early (i.e., before there is enough data in the
ring buffer to avoid underrunning). `audio_playbackData` will keep invoking
`start` until it returns true anyway, so we can just allow draining to
complete normally and wait for `start` to be called again.
2022-01-27 18:03:11 +11:00
Chris Spencer
8580978321 [client] audio/pw: drop redundant flushing state
We do not stop the audio device until after the internal buffer has already
been flushed, so this state does nothing useful.
2022-01-27 18:03:11 +11:00
Geoffrey McRae
b0568ca404 [client] egl: use a sigmoid curve for nv 2022-01-26 23:03:35 +11:00
Geoffrey McRae
3c9b9e6370 [client] main: fix heap-buffer-overflow on cursor update 2022-01-26 20:05:51 +11:00
Geoffrey McRae
efa49391fc [client] fix race segfault on pointer queue unsubscribe/timeout 2022-01-26 17:20:12 +11:00
Geoffrey McRae
fb4bdaee2b [client] egl: set the active preset if specified at launch 2022-01-26 16:07:17 +11:00
Geoffrey McRae
c7389285f9 [client] egl: fix null pointer access when no preset is set 2022-01-26 16:04:15 +11:00
Geoffrey McRae
aa426d13a7 [client] egl: added egl:preset to load a default preset at startup 2022-01-26 16:00:07 +11:00
Geoffrey McRae
89c83dafc1 [client] egl: make egl less noisy unless debug is specified 2022-01-26 15:42:33 +11:00
Geoffrey McRae
05e363e009 [client] x11: cleanup duplicated code 2022-01-26 15:30:38 +11:00