Commit Graph

370 Commits

Author SHA1 Message Date
Geoffrey McRae
947325e00d [host] dxgi: fix failure to copy to texture with sub resources
`CopyResource` will silently fail when trying to copy from a texture
with no subresources to one with. Instead we must use `ResolveSubresource`
2022-05-02 15:53:20 +10:00
Geoffrey McRae
3134ec84de [host] dxgi: add support for downsampling the capture before sending
This is an experimental & incomplete feature for those using
supersampling. Anything > 1200p will be downsampled by 50% before
copying out of the GPU to save on memory bandwidth.

Unfinished! Has issues with damage tracking and currently can not
be configured. Only dx11 has been tested at this point, everything
else will likely have problems/crash.
2022-05-01 19:45:44 +10:00
vmfortress
36f97f08ad [host] dxgi: add nanosecond-scale sleep capability to d3d12
The nsleep() call lets d3d12 sleep for a more precise amount of
time while maintaining the current millisecond-scale sleep
interface in the configuration file.
2022-03-06 17:21:14 +11:00
Tudor Brindus
eeefc15e46 [host] build with -Wstrict-prototypes 2022-02-25 20:38:44 +11:00
Tudor Brindus
9ddfa585ec [host] cleanup some missing (void) parameters 2022-02-08 16:37:17 +11:00
Tudor Brindus
809e1095bd [host] windows: plumb guest activation request to host 2022-02-08 15:27:27 +11:00
Quantum
75ec3c0478 [host] nvfbc: shorten nvfbc_getName() result
To avoid client showing "Using    : NVFBC (NVidia Frame Buffer Capt".
This happens because the string is truncated to 31 characters to fit
in the char capture[32]; member of KVMFRRecord_VMInfo.
2022-01-26 23:06:47 +11:00
Quantum
e85fd68d82 [host] windows: read ProductName from registry if possible
For Windows 10, it so happens that the major.minor is 10.0. This is not
usually a given, e.g. on Windows 7 where it would read 6.1, on
Windows 8 it would read 6.2, and on Windows 8.1 it would read 6.3.

This is obviously undesirable, so we should just read the ProductName
from registry if possible. This results in something like:

    OS Name: Windows 10 Pro for Workstations (Build: 19043)
2022-01-26 23:06:14 +11:00
Geoffrey McRae
db3d20f935 [host] windows: report windows version information 2022-01-26 19:58:46 +11:00
Geoffrey McRae
ccdf7b7c0e [host] app: report the full capture name to the client 2022-01-26 19:32:55 +11:00
Geoffrey McRae
99536eaf9d dxgi: check for memory leaks in d3d12 2022-01-19 09:58:14 +11:00
Geoffrey McRae
f8b4874799 dxgi: cosmetics 2022-01-19 09:58:14 +11:00
Geoffrey McRae
cff64ee7d3 dxgi: cache shared handles instead of re-creating them
This will cache up to 10 handles, in practice I have never seen DXGI
return anything but the same resource each time but we allow for more
anyway should MS change something in the future.

Should the cache get over filled it is disabled entirely and we revert
to the original behaviour.
2022-01-19 09:58:07 +11:00
Quantum
afd5e2d057 [host] dxgi: remove duplicate AcquireLock print 2022-01-17 15:12:54 +11:00
Quantum
508c491967 [host] dxgi: allow the debug layer to be turned on via config 2022-01-17 15:12:54 +11:00
Quantum
b117bbafe5 [host] dxgi: add ability to capture OutputDebugMessage
This is how Direct3D 12's debug layer outputs messages. Normally, these
are read by the debugger, but we want them logged instead.
2022-01-17 15:12:54 +11:00
Quantum
4c271f8744 [host] dxgi: move d3d12.h to vendor/directx 2022-01-17 15:12:54 +11:00
Chris Spencer
3d0a8f6987 [host] dxgi: fix frame damage method parameters
The buffer input sizes to the `IDXGIOutputDuplication` methods are measured
in bytes. This dramatically increases the number of dirty/move rects that
can be handled.
2022-01-13 09:34:14 +11:00
Chris Spencer
f145225dbc [host] dxgi: fix d3d11 assertion failure
`DEBUG_ASSERT(!this)` in `d3d11_create` is firing on the second
instantiation because we are not clearing `this` in `d3d11_free`.
2022-01-13 08:17:59 +11:00
vmfortress
7da2becfbd [host] dxgi: Replace standard asserts with DEBUG_ASSERT 2022-01-11 11:11:42 +11:00
Quantum
042a7d0925 [host] dxgi: add configurable sleep before D3D12 copy 2022-01-10 14:45:51 +11:00
Quantum
c69b19e68f [host] dxgi: add option to disable damage-aware copies 2022-01-10 14:45:51 +11:00
Quantum
cf7d501bc4 [host] dxgi: allow copy backend selection 2022-01-10 14:45:51 +11:00
Quantum
68e5b812a9 [host] dxgi: add preRelease callback
This is meant to avoid freeing the texture before the copy has finished.
2022-01-10 14:45:51 +11:00
Quantum
5a93f1e00c [host] dxgi: implement Direct3D 12 texture copy backend 2022-01-10 14:45:51 +11:00
Quantum
891f00a011 [host] dxgi: add d3d12.h from latest MinGW
This header was added in late 2020 and hasn't made its way into the GitHub
Actions image yet.
2022-01-10 14:45:51 +11:00
Quantum
137171a8a2 [host] dxgi: refactor to support additional copy backends 2022-01-10 14:45:51 +11:00
Quantum
a391e271c3 [host] dxgi: damage all textures when skipping frame 2022-01-09 16:36:26 +11:00
Johnathon Weaver
0f998582b9 [host] nvfbc: Fix dwmapi linking error
Fixed linking for DwmFlush and also rearranged as per how DXGI is.
2022-01-07 01:46:35 +11:00
Geoffrey McRae
34e5f7e968 [host] windows: fix usage of MCSS and try to get priority "Capture" 2022-01-06 20:14:55 +11:00
Geoffrey McRae
2f8b139131 [host] windows: set DwmFlush default to off
This new feature while helps on some systems, others using freesync or
higher refresh rates where the capture can't keep up will limit to
fractions of the refresh rate. Better to disable and allow users to
opt-in.
2022-01-06 19:20:08 +11:00
Geoffrey McRae
b058cbe9fe [host] nvfbc: add DwmFlush here too as it makes a large difference 2022-01-06 19:01:29 +11:00
Geoffrey McRae
443f98d2fa [host] windows: opt into the Multimedia Class Schedule Service
This improves overall application performance as windows will give this
process higher priority for low latency multimedia tasks.
2022-01-06 18:41:48 +11:00
Geoffrey McRae
92f27cc0f0 [host] dxgi: use DwmFlush to sync to presentation interval
This change reduces the host GPU and CPU load by a large margin
improving guest system performance along with removing latency spikes
when moving the mouse. This is default enabled but can be disabled with
the new option `dxgi:dwmFlush=no` as it limits the capture rate to the
refresh rate of the guests output which may not be desireable.
2022-01-06 18:39:08 +11:00
Geoffrey McRae
5bb1f01dea [host] windows: parse the UUID from the SMBIOS 2022-01-06 14:22:38 +11:00
Geoffrey McRae
fdb38a227e [host] app: implement stubs for platform specific guest information 2022-01-05 21:04:57 +11:00
Geoffrey McRae
952ebea2c5 [all] refresh copyright dates 2022-01-05 19:42:46 +11:00
Geoffrey McRae
ebf20dd108 [host] nvfbc: fix failure to startup 2022-01-05 19:31:47 +11:00
Geoffrey McRae
ba9f2b85b6 [host/client] kvmfr: update to include extra user data about the VM
This change allows the host to provide information to the client about
how the VM is configured, information such as the UUID, CPU
configuration and capture method both for informational display in the
client as well as debugging in the client's logs.

The format of the records allows this to be extended later with new
record types without needing to bump the KVMFR version.
2022-01-05 19:18:43 +11:00
Quantum
6f8745a89b [host] installer: enable DPI awareness
This should make the installer look less blurry on high DPI displays.
2021-12-26 11:34:43 +11:00
Quantum
3d1eedd4ef [host] installer: add ability to install IVSHMEM driver
To use this, run makensis with -DIVSHMEM with the driver files in the
ivshmem subdirectory under the build directory.
2021-12-26 11:31:32 +11:00
Quantum
d073f9969c [host] installer: clean up trailing whitespace 2021-12-26 11:31:32 +11:00
WYF
b21d842f0e [host] nvfbc: add an option to specify adapter 2021-12-26 11:14:17 +11:00
Tudor Brindus
9872d2e407 [host] dxgi: fix typo in debug log message 2021-12-26 09:49:03 +11:00
Quantum
12461196c3 [host] nvfbc: fix comments in updateDamageRects 2021-12-24 15:30:04 +11:00
Geoffrey McRae
b515fa80d5 [host] nvfbc: be more intellegent when unionizing disjointed sets 2021-10-27 00:00:38 +11:00
Quantum
13fabc2e4a [host] windows: fix NSIS install directory on 64-bit builds
This is probably an NSIS bug.
2021-10-18 16:17:36 +11:00
Quantum
1f24ab0742 [host] nvfbc: avoid waking up pointer thread for no reason
If the wait times out, we used to simply restart the loop, which causes
it to check this->stop and exit if set to true. However, nvfbc_stop
already calls lgSignalEvent, which would wake up the pointer thread to
perform the check, so there is no need to set a timeout on the wait.
2021-09-29 17:47:02 +10:00
Quantum
bc65de5987 [host] installer: build 64-bit NSIS installers
The host is a 64-bit application, so requiring 64-bit Windows isn't an
issue. However, not using 32-bit installers has an advantage: we don't
need to require WoW64.
2021-09-21 22:26:10 +10:00
Quantum
286da11172 [host] windows: don't register exit event when none exists 2021-09-04 13:25:06 +10:00
Quantum
4b3aaa7e0c [host] cmake: report capture backends enabled 2021-08-20 21:03:50 +10:00
Quantum
4ecf749f7e [host] remove all casts around malloc 2021-08-16 16:26:58 +10:00
Quantum
cdda89cef7 [host] use correct argument order for calloc 2021-08-16 16:25:59 +10:00
Tudor Brindus
982b4e6625 [host] use variable-relative sizeof where possible 2021-08-16 16:22:55 +10:00
Quantum
4f7ce91e7f [host] capture: switch all asserts to DEBUG_ASSERT 2021-08-14 12:19:07 +10:00
Quantum
10ee6cd031 [host] nvfbc: read nvfbc:diffRes option with the correct type 2021-08-14 09:21:34 +10:00
Quantum
e5d252290d [common] array: add ALIGN_PAD macro for common logic
ALIGN_PAD(x, a) returns x rounded up to the nearest multiple of a.
2021-08-14 08:05:29 +10:00
Quantum
acd5ce51db [host] dxgi: use FAILED macro instead of comparing against S_OK 2021-08-13 20:21:50 +10:00
Quantum
d3ea9662bf [host] nvfbc: remove rectangles that are entirely contained in others
This makes nvfbc report less useless damage and makes the client run faster.
2021-08-13 20:21:27 +10:00
Quantum
566c89e9d8 [host] dxgi: correctly count moved rectangles 2021-08-13 20:21:08 +10:00
Quantum
b3173bdddc [host] dxgi: include correct DXGI headers
The declarations in dxgi_extra.h are not missing, they are in dxgi1_2.h and
dxgi1_5.h, which exist in MinGW-w64 since 2017.
2021-08-12 12:35:45 +10:00
Quantum
61a4b0744d [host] dxgi: use standard MinGW libd3d11.a
MinGW has been shipping this file since 2014, and that version contains the
only function from the dll that we call: D3D11CreateDevice.
2021-08-12 11:58:34 +10:00
Quantum
9bded74543 [host] dxgi: use CopySubresourceRegion when possible
This commit adds damage tracking to the DXGI textures, and only copies the
damaged areas to the textures with ID3D11DeviceContext::CopySubresourceRegion.

The sleep logic in waitFrame makes it difficult for this to reduce the
latency, but removing it shows significant improvements (6-7 ms to ~3 ms)
when a tiny portion of the screen is damaged, while showing no difference on
full screen damage.
2021-08-11 19:01:52 +10:00
Quantum
5e13549f74 [host] windows: use DEBUG_WINERROR for MsgWaitForMultipleObjects 2021-08-09 17:07:25 +10:00
Quantum
87a21f5f5e [host] windows: use DEBUG_WINERROR for CallNtPowerInformation
We need to use the function RtlNtStatusToDosError to convert NTSTATUS to
Windows error codes.
2021-08-09 17:07:25 +10:00
Quantum
9246e00163 [host] windows: use DEBUG_WINERROR for exit event opening code 2021-08-09 17:07:25 +10:00
Quantum
cab95c5eed [common] rects: refactor rect buffer copy code to common module
This also fixes a bug of accidentally multiplying the stride by 4 when
the stride is already in bytes and not pixels.
2021-08-08 08:30:11 +10:00
Quantum
3d29967a8d [host] dxgi: copy only damaged regions to IVSHMEM
This implementation uses a line sweep algorithm to copy the precisely the
intersection of all accumulated damage rectangles, ensuring that every
pixel is copied exactly once, and no pixel is ever copied multiple times.
Furthermore, once a row has been swept, we update the framebuffer write
pointer immediately.
2021-08-06 22:55:15 +10:00
Quantum
3651852430 [host] nvfbc: round pitch to multiple of 128 for dmabuf import
Certain drivers do not support pitches that are not multiples of 128 bytes,
and instead just does some kind of rounding internally. On DXGI, this is not
a problem because the API rounds pixel pitch, but NvFBC does not. This causes
certain resolutions to simply not work with dmabuf, most notably 3440x1440,
which is 1440p ultrawide.

Since we are copying pixels with the CPU anyways, we might as well round the
pitch up to 128 bytes (32 pixels).
2021-08-06 22:48:33 +10:00
Geoffrey McRae
2856928b57 [host] windows: implement KVMFR_FEATURE_SETCURSORPOS 2021-08-05 22:35:22 +10:00
Quantum
4da0c64583 [host] nvfbc: make diff map size configurable
This commit adds a new host configuration option, nvfbc:diffRes, which
specifies the dimensions of every block in the diff map. This defaults to
128, meaning the default 128x128 block size.

Since block sizes other than 128x128 is not guaranteed to be supported by
NvFBC, the function NvFBCGetDiffMapBlockSize was introduced to query the
support and output the actual block size used.
2021-08-05 07:27:28 +10:00
Quantum
4e81c7f724 [host] windows: make copyright string in resource use © 2021-08-04 21:16:35 +10:00
Quantum
51b9cd4e5a [all] copyright: use unicode copyright sign ©
This is done for consistency with the license strings in appstrings.c.
2021-08-04 21:16:35 +10:00
arcnmx
c0aec7d8f4 [host] nvfbc: disable pointerThread when unused
fixes log spam that would occur when decoupleCursor=false
2021-08-03 21:05:39 +10:00
Quantum
7801575d99 [host] nvfbc: log error codes for various errors
This makes troubleshooting easier.

We also switch to use %d instead of 0x%x because all error codes in nvfbc.h
are negative decimal numbers.
2021-07-31 15:02:39 +10:00
Geoffrey McRae
5f5f497cbd [host/common] windows: provide delayExecution via nsleep
This change moves this platform specific sleep to `common` as the OS
agnostic `nsleep` function.

Ref PR #661
2021-07-26 16:36:56 +10:00
Quantum
8528969efd [host] nvfbc: clamp damage rectangles to screen size 2021-07-25 14:34:10 +10:00
arcnmx
2c745db544 [host] windows: use CMAKE_DLLTOOL if available
cmake automatically finds dlltool as of version 3.16
2021-07-24 14:52:32 +10:00
Quantum
3cf0257f34 [host] windows: do not complain about failed timer destruction at exit
When our window is destroyed, our timers are also destroyed. This causes our
attempt at destruction to fail. Instead, set MessageHWND to NULL in the
WM_DESTROY handler and don't try destroying the timers if the window is gone.
2021-07-23 15:52:45 +10:00
Quantum
4c60409aaf [host] windows: use WM_CLOSE to signal window destruction
DestroyWindow can only be invoked on the thread that created the window.
All other threads must use WM_CLOSE or another message to signal tell the
window to destroy itself.
2021-07-22 18:55:11 +10:00
Quantum
e58506f1a5 [all] copyright: refresh copyright notice for .nsi and .rc files 2021-07-21 18:19:46 +10:00
Quantum
f5dfc264ba [host] windows: trick MinGW into not using memcpy from ntdll
MinGW seems to decide at random whether it wants to use memcpy from
mscvrt.dll or ntdll.dll. Currently, on Debian buster, ntdll.dll is chosen,
while on sid, mscvrt.dll is chosen.

This commit declares a new .def file for ntdll containing only the
functions we want to link from ntdll.dll, and generates ntdll.a from it
with dlltool. This way, MinGW will never be tempted to link functions
like memcpy from ntdll.dll.
2021-07-21 15:45:59 +10:00
Quantum
8a70efafb5 [host] windows: use system thread pool to wait for exit event
This is much less annoying than creating our own thread just to wait on
a single event, then creating another event to signal that thread to exit.
2021-07-21 14:13:31 +10:00
Quantum
b1c26aaa95 [host] windows: log MsgWaitForMultipleObjects errors
This function is sometimes flaky and may fail for no apparent reason,
see https://stackoverflow.com/q/3945003. This has also been experienced
during the development of #610.

This commit adds logging so we may see if it ever fails for no reason
and work out some way to fix it.
2021-07-21 12:33:36 +10:00
Quantum
3400c2c141 [host] windows: add version resource
This allows friendly names and versions to be displayed in task manager
and other applications.
2021-07-21 12:32:41 +10:00
Quantum
80bc9604ba [host] windows: fix graceful exit
We were using an auto-reset event to signal the mousehook exit. This was
fine when there was only one thread, but with the addition of the update
thread, only one thread is signaled, causing the wait to last forever.

The fix is switching to a manual reset event and call ResetEvent after
the threads have exited.
2021-07-21 12:32:14 +10:00
Quantum
669148bca0 [host] service: respond to exit request while sleeping
Instead of Sleep, we can use WaitForSingleObject with a timeout to be
signalled when the service is exiting.
2021-07-21 12:30:27 +10:00
Quantum
26df3579a3 [host] windows/delay: cast to LONGLONG instead of int
The type of the QuadPart member of the LARGE_INTEGER union is actually
LONGLONG, so we should cast to LONGLONG instead of int.
This avoids truncation should (ms * 10000.0f) exceed 2^31-1.
2021-07-21 12:29:29 +10:00
Quantum
88fc1a6d24 [host] windows: directly invoke ChangeWindowMessageFilterEx
This requires bumping the minimum Windows version to Windows 7, but I
don't think we care about Vista anyways.
2021-07-20 12:16:49 +10:00
Quantum
28a67cad0d [host] windows: avoid compiling .rc file twice
a4f5ce08b9 has a regression that caused
the .rc file to be compiled twice. We do not want the version that's
added into the .a file.
2021-07-20 12:14:04 +10:00
Quantum
d82333519c [host] dxgi: use SDK versionhelpers.h to test for Windows version
Also, changed logic so that Windows versions before 8 is not treated as 10.
2021-07-20 11:34:57 +10:00
Quantum
5421bd8b1d [host] windows: declare Windows 10 support in manifest
This allows IsWindows10OrGreater from <versionhelpers.h> to work.
2021-07-20 11:34:57 +10:00
Quantum
f0c7e9bdfa [host] windows: declare high DPI support in manifest
This is the normal way of doing things, and it's easier and less sketchy
than GetProcAddress.
2021-07-20 11:34:45 +10:00
Quantum
f5ad14b109 [host] windows: directly link D3DKMTSetProcessSchedulingPriorityClass
This function is available since Windows Vista and can therefore be used
directly without going through GetProcAddress. Unfortunately, MinGW does
not have d3dkmthk.h, but we can declare the prototype ourselves and link
against gdi32.dll.
2021-07-20 11:32:41 +10:00
Quantum
323d321a77 [host] windows: correctly declare WINVER and _WIN32_WINNT
We wanted to target Windows Vista, which is 0x0600 not 0x6000.
0x6000 is in fact larger than Windows 10 which is 0x0a00.
2021-07-20 11:32:15 +10:00
Quantum
56833edae7 [host] delay: directly link against ntdll.dll
There is no need to LoadLibrary and GetProcAddress to get pointers to
NtDelayExecution or NtSetTimerResolution. These functions don't have
prototypes in any SDK header, but they are exported in ntdll.dll and
we can simply declare the prototype and link ntdll.

There is also no chance that the functions do not exist: I checked an
old install of Windows NT 4.0 and both of these functions exist.

Also used NtSetTimerResolution instead of ZeSetTimerResolution for
consistency (they are the same).

Also changed system timer resolution log message units to μs with
one decimal digit for readability. This is the actual amount of
precision available to us.
2021-07-20 11:30:12 +10:00
Quantum
d57b5a320e [host] service: fix adjustPriv return value
When OpenProcessToken fails, the function returned -1, which would be true
when converted to bool. This is wrong, and it should be returning false.
2021-07-20 11:29:32 +10:00
Quantum
b4dc021381 [host] service: pass CREATE_UNICODE_ENVIRONMENT unconditionally
According to MSDN documentation for CreateEnvironmentBlock, "[i]f the
environment block is passed to CreateProcessAsUser, you must also
specify the CREATE_UNICODE_ENVIRONMENT flag."

Also pass DETACHED_PROCESS because the host is a GUI application and
doesn't use the console.
2021-07-20 11:27:16 +10:00
Quantum
ebda52b18b [host] service: use SYSTEM token attached to the current process
Since with the service, we are already running as SYSTEM, we don't need
to use dupeSystemProcessToken to get the token for SYSTEM. This removes
the need for having SeDebugPrivilege, SeTcbPrivilege, and
SeAssignPrimaryTokenPrivilege, or otherwise doing sketchy things.

Furthermore, we now only open the token with the privileges we actually
need.
2021-07-20 11:27:03 +10:00
Quantum
16ee1a825c [host] windows: use event to gracefully signal exit
This allows the process to be terminated without resorting to
TerminateProcess. With some fixes, this allows the notification icon to be
removed when the service is restarted.

Furthermore, instead of sending WM_DESTROY to fool the window into believing
it's being destroyed, we actually call DestroyWindow now.
2021-07-20 11:26:49 +10:00
arcnmx
aa41e4d2ce Revert "Revert "[host] avoid manual windres command""
This reverts commit cd10e02862.
2021-07-20 11:25:55 +10:00
Quantum
9ab85fd0b8 [host] capture: stop sending DPI information
The client doesn't need DPI information anymore, so there is no point
fetching it.
2021-07-18 10:50:57 +10:00
Tudor Brindus
92706caddc [common]: move array length into a common helper
Since it is more generally useful, and less cryptic this way.
2021-07-18 10:41:50 +10:00
Quantum
893b2500c2 [host] nvfbc: copy damaged areas only
This commit tracks the damage made to the framebuffer and only updates those
areas. Damage is tracked directly with NvFBC provided diffmaps.
2021-07-18 10:41:50 +10:00
Quantum
9ce4990793 [host] capture: pass frameIndex to capture backends
This allows capture backends to track damage made to each frame.
2021-07-18 10:41:50 +10:00
Tudor Brindus
f274bec8fc [host] dxgi: compute damage rectangles from moved rectangles
This is untested in that I don't have a Windows 8 VM where move rects
are supplied, but seems sound.
2021-07-18 10:41:50 +10:00
Quantum
e42747f4e3 [host] nvfbc: better algorithm for merging adjacent regions
Use a proper disjoint-set to give a more accurate result.
2021-07-18 10:41:50 +10:00
Quantum
5ed3301cf5 [host] nvfbc: merge adjacent changed regions
For adjacent changed regions, we actually use the bounding box for the
entire polygon. This may result in more area being damaged than strictly
necessary, but is nevertheless desirable since it reduces the number of
rectangles.
2021-07-18 10:41:50 +10:00
Quantum
6b16bb3ea1 [host] nvfbc: populate damage rectangles 2021-07-18 10:41:50 +10:00
Tudor Brindus
d7f9afb3ba [host] dxgi: populate damage rectangles
Co-Authored-By: Quantum <quantum2048@gmail.com>
2021-07-18 10:41:50 +10:00
Geoffrey McRae
7decb58bf7 [host] windows: fix build on Linux due to case sensitive filenames 2021-07-17 15:05:32 +10:00
Geoffrey McRae
d1ec19b30b [host] windows: fix delayExecution order of magnitude bug 2021-07-17 15:02:58 +10:00
Geoffrey McRae
74468cf799 [host] windows: remove accidental addition of some junk 2021-07-17 15:02:36 +10:00
Geoffrey McRae
411a6b1e49 [host] windows: add delayExecution function for more accurate sleeps
This change not only exposes and allows use of NtDelayExecution, but
also moves the code to set the system timer resolution.
2021-07-17 14:55:22 +10:00
Geoffrey McRae
e228165ff9 [host] windows: fix system timer resolution message units
ZwSetTimerResolution works in units of 100ns
2021-07-17 14:31:31 +10:00
Geoffrey McRae
d615514799 [host] windows: do not callback from the mouse hook context
The windows hook WH_MOUSE_LL is called in such a way that any delay in
processing causes a system wide stall. This change spawns an extra
thread which waits on an event set by the hook which is then used to
call the callback with an artifical limit of 1000Hz.
2021-07-17 14:03:52 +10:00
Geoffrey McRae
789ee70674 [host] dxgi: print out the adapter details earlier
Before we try and perhaps fail to init DXGI, we should print out what
the device is so that when there is an error report we can immediately
see if the user has the QXL device attached still.
2021-07-12 19:28:13 +10:00
Geoffrey McRae
3c0616bab7 [host] dxgi: print out the output device name to aid with support 2021-07-12 19:03:02 +10:00
Geoffrey McRae
7d0b9711bd [host] nvfbc: remove the frameEvent event and associated code
Now that the host application can run the capture interface in
synchronous mode, and NVFBC uses this mode there is no longer need for
the frameEvent.
2021-07-12 17:01:23 +10:00
Geoffrey McRae
e477663a7e [host] app: allow the capture interface to select async or sync mode
While it's correct for DXGI to use a asyncronous waitFrame model, other
capture interfaces such as NvFBC it is not correct. This change allows
the capture interface to specify which is more correct for it and moves
the waitFrame/post into the main thread if async is not desired.
2021-07-12 16:57:22 +10:00
Quantum
eb01efe0cb [host] nvfbc: do not crash when protected content is playing
We return a timeout, so that when protected content finishes playing, we
can immediately resume capture.
2021-07-11 17:54:23 +10:00
Quantum
501b270890 [host] nvfbc: optimize change detection loop
Before, we only break out of the current row when a change is detected,
and all subsequent rows are still scanned. Now we break out of the entire
loop. This should make change detection ever so slightly faster.
2021-07-11 10:15:12 +10:00
Quantum
fd8f8b2b28 [host] dxgi: correctly mention AcquireNextFrame in help text
Also fix some formatting issues.

Co-Authored-By: Tudor Brindus <me@tbrindus.ca>
2021-07-11 10:15:12 +10:00
Geoffrey McRae
78b8e2a73c [host] windows: make D3DKMTSetProcessSchedulingPriorityClass global
Testing shows that `D3DKMTSetProcessSchedulingPriorityClass` has a
positive performance impact for NvFBC as well as DXGI, as such always
try to boost the priority for the windows host.
2021-07-10 12:27:30 +10:00
Geoffrey McRae
041b95507d [host] windows/nvfbc/common: strip out broken "enhanced" event logic
This so called "enhanced" event logic is completely flawed and can never
work correctly, better to strip it out and put our faith in windows to
handle the events for us.

And yes, I am fully aware I wrote the utter trash in the first place :)
2021-07-09 10:22:03 +10:00
Geoffrey McRae
1effd5fddc [common] debug: add color support to debug messages
People often miss the warnings about invalid arguments in their command
line, this last minute patch attempts to address this by making
warnings, errors, fixme's and fatal errors stand out if stdout is a TTY.
2021-07-07 23:05:46 +10:00
Geoffrey McRae
cd10e02862 Revert "[host] avoid manual windres command"
This reverts commit d82f2e510d.
While the proposed change is more correct, it breaks the generation of
the file due to failure to locate the resource files, such as
`resources/icon.ico`.
2021-07-04 19:30:06 +10:00
arcnmx
d82f2e510d [host] avoid manual windres command 2021-07-03 04:28:28 +10:00
Geoffrey McRae
d36c4f0e83 [host] kvmfr: allow the frame size to exceed the available memory
This change allows the host to still transmit a frame that is truncated
if the IVSHMEM size is too small to allow for a full frame.
2021-06-12 18:44:28 +10:00
Geoffrey McRae
f02d61d665 [host] dxgi: sleep until it's close to time to map
This change adds an average function to time how long it takes the GPU
to copy and map the texture, and then uses this average to sleep for 80%
of this average lowering CPU usage and potentially decreasing lock
contention.
2021-06-06 12:26:36 +10:00
Quantum
24d0aa0c18 [all] normalize copyright on all source files 2021-06-06 11:53:05 +10:00
Geoffrey McRae
fcf6abc7c6 [host] NvFBC/DXGI: make DXGI the default instead of the fallback
It has been detemined that a failure to init NvFBC causes a 20-30%
performance penalty on non NvFBC supported hardware (GeForce) when using
DXGI, as such reverse the order and default to using DXGI as our first
option.

If NvFBC is still desired, pr #500 added the option `app:capture` which
can be used to force NvFBC.
2021-06-06 06:14:24 +10:00
Geoffrey McRae
0d9b0bd367 [host] dxgi: increase maxTextures default to 4
Testing shows that at high frame rates the default of 3 is hampering
performance, increasing this to 4 yields a substantial performance
improvement.
2021-06-06 01:35:00 +10:00
Geoffrey McRae
fb1b30b728 [host] app: calculate and report the required IVSHMEM size
One of the most common issues reported in the support channels is the
IVSHMEM size being too small. This change adds a calculation to
determine an optimal size and uses the new `os_showMessage` platform
method to display a message box to the user with the error.
2021-06-04 12:31:15 +10:00
Quantum
ec81a353c2 [host] nvfbc: fix null dereference in mouse hook handler
Since we now let the mouse hook linger until the process is killed, the
cursor event that the hook signals may now be null, as the capture could
have stopped. If the hook fires during this time, a crash occurs.
2021-04-29 11:53:19 +10:00
Quantum
6a1ec9420e [host] service: compare SIDs directly without string conversion
Instead of converting every SID to string with ConvertSidToStringSidA
and compare it with the magical SID string for local system with strcmp,
we could instead create the local system SID and compare directly with
EqualSid.
2021-04-29 11:52:23 +10:00
Quantum
93d97424df [host] service: disable handle inheritance when spawning host
We don't actually have any handles that should be inherited, so specifying
TRUE for bInheritHandles to CreateProcessAsUserA is pointless.

Furthermore, according to MSDN, "[y]ou cannot inherit handles across
sessions," and we are spawning the host in a different session, so this
is even more pointless.
2021-04-29 11:51:41 +10:00
Quantum
2afad4e1be [host] service: disable privileges as soon as they are not needed
It is usually considered good practice to enable elevated privileges
for the shortest duration possible.
2021-04-29 11:51:30 +10:00
Quantum
5bfb33c739 [host] windows: re-implement open log safely
Instead of doing ShellExecute from the service, we instead get the token
of the currently logged in user, and do CreateProcessAsUserA to run
notepad with that token. This should be safe.
2021-03-22 09:06:07 +11:00
Quantum
a089c4ea32 [host] service: introduce fatal errors for ivshmem failures
Also for failure to parse command line. For these errors, restarting
with exponential backoff will not help: no amount of restarting the
service could possibly make the ivshmem device exist or larger, so
we shouldn't try.
2021-03-22 08:54:58 +11:00
Quantum
c12c6ea3c7 [host] service: retry a few times when host fails to restart
Certain users of Radeon cards have observed that the host fails to start
at boot, with D3D11CreateDevice failing with HSTATUS 0x887a0004, which
translates to "The specified device interface or feature level is not
supported on this system."

This failure results in a LG_HOST_EXIT_FAILED exit code, which the service
does not attempt to restart. The user has to manually restart the service
for the host application to work.

These users reported that the host application started fine on
B2. This strongly suggests that the fix to enable capturing the login
screen made the host application start too early during the boot process,
and the graphics driver did not have time to initialize fully.

This PR allows the service to retry a few times on LG_HOST_EXIT_FAILED,
with exponential backoff, before giving up. This should cover this bug
and other similar bugs related to the early initialization which I do not
have logs for.
2021-03-22 08:54:58 +11:00
Quantum
f2c0b8c0b4 [host] allow user to select capture backend
This commit introduces a new option, app:capture, which can be set to
either DXGI or NvFBC to force the host application to use that backend.

This is very useful for testing DXGI on Quadro cards, which would default
to running with NvFBC.
2021-02-27 17:41:44 +11:00
Quantum
8e98f863b6 [host] windows: detect whether screensaver is disabled in the guest
This will allow us to add an option to disable the screensaver on the client
when an application in the guest requests it. This behaviour may be useful
when the guest is doing media playback.
2021-02-21 10:31:48 +11:00
Quantum
ff0a859ceb [host] nvfbc: avoid recreating mouse hook and 1x1 window
The mouse hook code is very fragile, and we would like to avoid unhooking
and re-hooking as much as possible.

After this commit, this is done only once, and the hook and 1x1 window is
only destroyed upon exit. This, of course, comes with the downside of
the slight performance penalty if the guest machine is used directly while
the host is running and the client is not running.
2021-01-31 12:17:14 +11:00
Quantum
1b48ac842a [host] nvfbc: fix resource leak when pointer thread creation fails
Moving NvFBCToSysSetup to nvfbc_init means that when the pointer thread
fails to be created, NvFBCToSysRelease needs to be called.

To resolve such cleanup issues in the future, we instead call nvfbc_deinit,
which should cleanup everything that needs to be cleaned up. fails.
2021-01-31 11:21:24 +11:00
Quantum
a702c912ae [host] nvfbc: move NvFBCToSysCreate into nvfbc_init
When NvFBCToSysCapture reports recreation is required, we return
CAPTURE_RESULT_REINIT, which eventually calls nvfbc_deinit and then
nvfbc_init.

However, the NvFBC object is actually created in nvfbc_create, which
means the NvFBC object is never actually recreated. The result is an
endless cycle of NvFBC asking for recreation. This commonly manifests
as the client waiting endlessly for the host when the guest machine
reboots.

In this commit, the NvFBC object creation is moved into nvfbc_init,
and when recreation is required, it will actually be recreated.
2021-01-31 10:57:51 +11:00
Quantum
acc3298344 [host] nvfbc: cleanup threads created by nvfbc_init on failure
mouseHook_install and dwmForceComposition both create threads, but these
are only freed in nvfbc_deinit which is not called if nvfbc_init fails.
These should be freed if the pointer thread fails to be created, as
nothing else could be cleaning it up.
2021-01-31 09:57:07 +11:00
Quantum
c91b7f647d [host] installer: create start menu shortcut to log directory
This commit makes the installer create a shortcut to the log directory
introduced by the previous commit.
2021-01-29 15:56:01 +11:00
Quantum
1761ea2b9b [host] windows: move log path to %ProgramData%\Looking Glass (host)
Instead of using %windir%\Temp, which is not accessible by default and
contains a lot of unrelated files, as the location for our log files,
this commit moves it to %ProgramData%\Looking Glass (host), which will
be a dedicated directory just for the LG host log files. This applies
to both the host application logs and the service logs.

Also, we now switched to using PathCombineA from shlwapi.dll instead
of using snprintf, which greatly simplifies the code. PathCombineA
guarantees that the path would not overflow a buffer of MAX_PATH.
2021-01-29 15:56:01 +11:00
Quantum
fb916cbac1 [host] nvfbc: always update cursor shape on startup
This ensures that the top-left position of the cursor sprite is correctly
computed.
2021-01-28 11:18:02 +11:00
Quantum
b97130cf20 [host] nvfbc: generate cursor position update on startup
Before this commit, the NvFBC backend only generated the first cursor
position update when the mouse moves. Therefore, if the user does
not move the mouse, the cursor will be shown at (0, 0), which is not
ideal.

This commit changes this behaviour to unconditionally generate a
cursor update when the mouse hook initializes.
2021-01-28 11:18:02 +11:00
Geoffrey McRae
e2e49bce13 [host] service: fix possible use of unitialized variable 2021-01-27 01:23:58 +11:00
Geoffrey McRae
0d7be70b56 [host] dxgi: fix maybe uninitialized warning 2021-01-27 01:21:06 +11:00
Geoffrey McRae
6b0699e664 [host] installer: include the debug PDB if it is available 2021-01-26 22:55:25 +11:00
Quantum
f9ec32b255 [host] service: disable buffering on the log file
Before this change, the log is buffered, so if the host application exits
for any reason, it usually would not show up in the log file immediately,
and the service has to be restarted for the logs to be flushed.

This commit disables the buffering so that any log entries shows up
immediately.
2021-01-25 09:35:03 +11:00
Quantum
d610aaf2cf [host] nvfbc: update cursor position on shape change
This is because we keep track of the top-left corner of the cursor, not
the location of the hotspot. When the cursor shape changes, the hotspot
location may also change. When it does, the position of the top-left
corner changes and requires an update.

In the case that we do not have the current cursor position, which
happens on startup, we do not generate this update.
2021-01-23 20:37:09 +11:00
Geoffrey McRae
04774d9cd6 [host] fix faults caused by improper startup/shudown/restart ordering 2021-01-21 17:05:30 +11:00
Geoffrey McRae
6b8161972d [host] nvfbc: prevent possible double free 2021-01-21 16:28:20 +11:00
Geoffrey McRae
98ea8b0bb8 [host] nvfbc: remove invalid close of the HMONITOR handle 2021-01-21 16:17:24 +11:00
Geoffrey McRae
536df254e0 [host] fix the return code for the platform specific init 2021-01-21 15:44:19 +11:00
Geoffrey McRae
e926bad759 [host] dont overwrite the exit code on shutdown 2021-01-21 15:14:50 +11:00
Geoffrey McRae
ad9e84eaaa [host] return a proper exit code 2021-01-21 15:07:19 +11:00
Quantum
ffa72c7992 [host] nvfbc: force composition to capture some full screen apps
NvFBC is unable to capture certain applications that bypasses the DWM
compositor, for example, Firefox playing video in full screen. This
has been a known issue for a long time with Nvidia's ShadowPlay, see:
* https://www.nvidia.com/en-us/geforce/forums/geforce-experience/14/233709/
* https://crbug.com/609857

Nvidia won't fix this, but there are workarounds. For example, we
create a transparent 1x1 layered window, which forces desktop composition
to be enabled.

Note that SetLayeredWindowAttributes also supports alpha-based transparency,
but setting transparency to 0 will cause DWM to skip composition. We could
use a transparency of 1, but this ruins the image by the slightest bit,
which is unacceptable. Therefore, we must use chroma key-based
transparency, which tricks DWM into compositing despite being fully
transparent.
2021-01-21 12:14:03 +11:00
Geoffrey McRae
cac454d9cf [host] dxgi: reverse the rotation angle.
This is undocumented however testing yields that DXGI DD reports the
inverse rotation. Research shows that this is because of a difference in
coordiate spaces.

Ref: https://docs.microsoft.com/en-us/windows/uwp/gaming/supporting-screen-rotation-directx-and-cpp
2021-01-18 15:15:36 +11:00
Geoffrey McRae
f5587b6b6b [host] all: pass back the desktop rotation to the client 2021-01-18 13:53:29 +11:00
Quantum
95e1b48f83 [host] windows: make mousehook.c work on secure desktop
Basically, this creates a separate thread for the mouse events, and this
thread detects that the desktop has changed (say to the secure desktop),
and unhooks, switches to the new desktop, and then rehooks.

This allows the cursor location to be updated while using NvFBC on secure
desktop and the login screen.
2021-01-17 13:23:29 +11:00
Quantum
fe835b98d5 [host] windows: sleep for 1 second instead of 1 millisecond
This is definitely supposed to sleep for 1 second.
1 ms is basically no throttling.
2021-01-17 02:58:27 +11:00
Quantum
c5c43d99f3 [host] windows: allow capture of login screen
WTSGetActiveConsoleSessionId will return a session even if it's not logged in,
unlike our old GetInteractiveSessionID function. Launching looking glass on
such a console session will allow the login screen to be captured.

Note that WTSGetActiveConsoleSessionId() will return 0xFFFFFFFF if there are
no sessions attached.
2021-01-17 02:56:29 +11:00
Quantum
4858bb5899 [host] windows: avoid quoting issues with CreateProcessAsUserA
To quote MSDN documentation:

> The lpApplicationName parameter can be NULL, in which case the executable
> name must be the first white space–delimited string in lpCommandLine. If
> the executable or path name has a space in it, there is a risk that a
> different executable could be run because of the way the function parses
> spaces. The following example is dangerous because the function will
> attempt to run "Program.exe", if it exists, instead of "MyApp.exe".
>
>   LPTSTR szCmdline[] = _tcsdup(TEXT("C:\\Program Files\\MyApp"));
>   CreateProcessAsUser(hToken, NULL, szCmdline, /*...*/ );
>
> If a malicious user were to create an application called "Program.exe" on
> a system, any program that incorrectly calls CreateProcessAsUser using the
> Program Files directory will run this application instead of the intended
> application.
>
> To avoid this problem, do not pass NULL for lpApplicationName.

So instead, we pass the executable to lpApplicationName instead, which avoids
the issue. MSDN says:

> The lpCommandLine parameter can be NULL. In that case, the function uses
> the string pointed to by lpApplicationName as the command line.

This also avoids the strdup since lpApplicationName is LPCSTR unlike
lpCommandLine which is LPSTR.
2021-01-16 11:48:03 +11:00
Quantum
8f27789d25 [host] windows: close handle to token in enablePriv
This should eliminate all handle leaks resulting from killing the host.
2021-01-15 20:44:50 +11:00
Quantum
e401513552 [host] windows: add timestamps to service logs
This makes it easier to identify when things in the logs happened.
2021-01-15 20:44:38 +11:00
Quantum
81561a242f [host] windows: remove ImpersonateLoggedOnUser call
It shouldn't have any effect, since the host application is created with
the token, and there is no need for the service itself to impersonate.

In practice, removal doesn't appear to have any effect on the ability to
capture privileged things like secure desktop.
2021-01-15 20:44:25 +11:00
Quantum
789f21ccb3 [host] windows: handle defined exit codes in service
The service should now react to host application exit codes.
For the exit codes that demands it, the service will exit instead of
restarting the host.
2021-01-15 20:44:13 +11:00
Quantum
323aab8ec2 [host] windows: improve restart logic and remove mutex hack
Use the process handle returned by CreateProcessAsUserA to wait on the
process. This results in faster response times and less polling.
For example, it now restarts instantly when UAC is activated.

This also removes the call to OpenProcess and rendering the mutex unnecessary.

As a bonus, it should fix #298.
2021-01-15 11:43:23 +11:00
Quantum
22920acc88 [host] windows: define exit codes for future use
The host process will be changed to return these codes, from which the
service process could decide whether to exit or restart the process and log.

Note that on Windows, return values are 32-bit unlike POSIX which is only 8.
2021-01-15 11:27:02 +11:00
Quantum
65009dcedc [host] windows: avoid leaking process and thread handles
The handles in PROCESS_INFORMATION must be closed if not used, or they
will leak.
2021-01-15 09:49:42 +11:00
Tudor Brindus
a46a3a2668 [all] use explicit void parameter lists
This makes it a compile-time error to call a function that semantically
takes no parameters with a nonzero number of arguments.

Previously, such code would still compile, but risk blowing up the stack
if a compiler chose to use something other than caller-cleanup calling
conventions.
2021-01-14 17:29:37 +11:00
Geoffrey McRae
c2ad9666bb [host] use the HotSpot information as provided by DXGI
I must have originally overlooked this member when I wrote this code. :S
2021-01-05 20:55:39 +11:00
Quantum
7e4d323427 get display DPI info to scale mouse movement 2021-01-05 09:03:29 +11:00
Jonathan Rubenstein
393a879c0b [host] nsis: change 'Stopping' to imperative 'Stop'
This follows the rest of the output like Install, Delete
2021-01-01 12:12:07 +11:00
Jonathan Rubenstein
d01d9db9bf [host] nsis: log more details about the process
Uses nsExec:ExecToLog in a few places to log on the installation output
window
2021-01-01 12:12:02 +11:00
Jonathan Rubenstein
5cc4f5454f [host] nsis: amended installer welcome description 2021-01-01 12:10:23 +11:00
Jonathan Rubenstein
32c797e60a [host] nsis: adds colour to installer and welcome screen 2021-01-01 12:10:15 +11:00
Jonathan Rubenstein
b66715b042 [host] nsisi: add welcome page to installer 2021-01-01 12:10:09 +11:00
Geoffrey McRae
38198b1477 [host] dynamically locate CreateProcesssAsUserA for pre-win 10 2020-12-30 18:29:58 +11:00
Geoffrey McRae
604b6bec9a [host] don't fail if windows is dumb and doesnt give us the cursor info 2020-11-01 04:45:57 +11:00
Geoffrey McRae
9d0ae23f9f [host] init ivshmem options before testing 2020-10-19 03:01:35 +11:00
Geoffrey McRae
9ff1859dc1 [host] windows: check the ivshmem device exists in the service 2020-10-19 02:49:15 +11:00
Geoffrey McRae
7a7e1d006b [host] set the program name/description in the app.manifest 2020-10-19 01:56:03 +11:00
Geoffrey McRae
38b05cda50 [host] dxgi: fix incorrect bpp value 2020-10-12 20:08:51 +11:00
Geoffrey McRae
7a49f75d95 [host] dxgi: ensure formatVer is incremented on re-init 2020-10-12 19:39:57 +11:00
Geoffrey McRae
b2961c7939 [all] added new format version field to frame header 2020-10-12 18:52:37 +11:00
Geoffrey McRae
8a9f004ff6 [host/client] fix invalid initialization of RGBA16F 2020-10-11 19:39:47 +11:00
Geoffrey McRae
9c6bd888fd [host/client] added experimental RGBA16 float support (EGL only) 2020-10-11 19:22:31 +11:00
Geoffrey McRae
a94d3734c2 [all] pass the project path to the version.cmake script 2020-10-09 02:51:28 +11:00
Geoffrey McRae
e1d7752165 [host] fix nsis build failure to do invalid path to new VERSION file 2020-10-09 02:36:48 +11:00
Geoffrey McRae
e6c88a4af3 [all] be smarter about getting the git version 2020-10-09 02:17:20 +11:00
Geoffrey McRae
e20c8a5cc7 [host] dxgi: don't try to get the hotspot of a null cursor 2020-10-06 23:24:01 +11:00
Geoffrey McRae
4f4d2dbf42 [host] dxgi: fix memory leak if an error occurs 2020-10-06 22:32:10 +11:00
Geoffrey McRae
7e362050f7 [all] update KVMFR to provide cursor hotspot information
This commit bumps the KVMFR protocol version as it adds additional
hotspot x & y fields to the KVMFRCursor struct. This corrects the issue
of invalid alignment of the local mouse when the shape has an offset
such as the 'I' beam.
2020-08-20 13:51:01 +10:00