Commit Graph

164 Commits

Author SHA1 Message Date
Geoffrey McRae
f7682c289a [client] egl: always render the black bar areas
Failure to render these causes artifacts/ghosting when the overlays are
using this area, as such we need to always render this area of the
screen.
2021-08-03 22:29:04 +10:00
Geoffrey McRae
4b4a75475a [client] egl: fix out by one error with letterbox rendering
This replaces the scaled `destRect` with a version that uses doubles
correcting the rounding error that is causing a failure to properly
clear the black bar areas.
2021-08-03 22:27:46 +10:00
Quantum
8545d15c85 [client] egl: warn when EGL_EXT_buffer_age is not supported 2021-08-03 21:37:31 +10:00
Quantum
87aac8cf03 [client] egl: use buffer age extension to render only damaged parts
We avoid rendering any area that has not changed since the buffer was used
and also not covered by an overlay.
2021-08-03 21:37:31 +10:00
Quantum
f9977332a6 [client] egl: convert desktop to use desktop_rects 2021-08-03 21:37:31 +10:00
Quantum
2dca056526 [client] egl: refactor damage mesh generation into desktop_rects
This mesh will later be used to render only damaged portions of the desktop.
We also moved the coordinate transformation for damage overlay into a matrix
and computed by the shader.
2021-08-03 21:37:31 +10:00
Geoffrey McRae
f3413815a9 [client] egl: re-implement DMABUF (untested) 2021-08-03 03:59:03 +10:00
Quantum
5d5e4ede1a [client] egl: use new EGL damage count semantics
After the damage queue PR, EGL damage count 0 means no change, and -1 means
invalidate the entire window. However, several other places have different
semantics, and we are not handling them correctly:

1. KVMFR uses 0 to signal invalidating the entire frame, so if we receive 0
   rectangles in egl_on_frame, we should set damage count to -1.
2. The damage overlay treated 0 as full damage, which is now incorrect. This
   is fixed, and now it treats 0 as no update, and -1 as full damage.
2021-08-03 00:57:32 +10:00
Geoffrey McRae
13d9c84dc9 [client] egl: replace monolithic EGLTexture with modular version
The way things were handled in EGLTexture is not only very hard to
follow, but broken. This change set breaks up EGLTexture into a modular
design making it easier to implement the various versions.

Note that DMABUF is currently broken and needs to be re-implemented.
2021-08-02 23:37:33 +10:00
Quantum
23c77e8508 [client] egl: use a lock for desktop damage to eliminate all races
There used to be a possible race when a bunch of rectangle is appended, but
the total count is not updated before it's read. Using a lock eliminates
all such races.
2021-08-01 19:54:56 +10:00
Geoffrey McRae
f8e1ab8f31 [client] renderers: add new needs_render method to the interface
With jitRender the renderer needs to tell the main application if it
needs to be rendererd, such as during the initial splash screen fade
out.
2021-08-01 18:18:08 +10:00
Quantum
b3b71d6f02 [client] egl: fix cursor handling when invalidating
If we invalidate the window, we used to not update this->cursorLast, and
this causes us to lose track of the cursor. Now we update this->cursorLast
unconditionally, and this fixes the issue.
2021-08-01 17:28:40 +10:00
Quantum
b9a7ce17fe [client] egl: use queue of damages
This prevents damage from being overwritten when frames are received
faster than could be rendered.

This implementation cycles between two queues, removing all need for
memory allocation.
2021-08-01 12:11:54 +10:00
Quantum
a980cd9406 [client] egl: log when EGL_EXT_image_dma_buf_import is unavailable 2021-07-29 17:03:44 +10:00
Quantum
6c64965703 [client] egl: make functions that do not need linking static 2021-07-29 16:54:56 +10:00
Quantum
134829cbf2 [client] imgui: make graph y-axis configurable
The default of [0, 50] makes sense for FPS/UPS graphs, but does not for
things like the import graph. The latter should not take more than 5 ms
for sure.

This commit allows the min/max y-axis value to be specified when registering
the graph.
2021-07-29 15:54:15 +10:00
Quantum
009ae02e32 [client] egl: add graph tracking time taken to import frame
This tracks the time taken to load the frame buffer into an OpenGL texture.
2021-07-29 10:08:52 +10:00
Quantum
d9cdc8d26c [client] egl: rotate damage rectangles according to client side rotation 2021-07-25 16:56:48 +10:00
Geoffrey McRae
60a58d4d8d [client] all: make it possible to signal full window invalidation
Now that we are drawing with damage rects, when the window is hidden and
then exposed the window may not get fully redrawn. This provides
`app_invalidateWindow` for the display server backend to call when the
screen needs a full redraw.
2021-07-25 15:29:29 +10:00
Quantum
cb9774bbd2 [client] egl: remove font management 2021-07-23 20:18:12 +10:00
Quantum
dd0edc1394 [client] renderers: remove alert handling 2021-07-23 20:18:12 +10:00
Quantum
5153d35bb5 [client] renderer: remove on_help from renderer interface 2021-07-23 18:04:05 +10:00
Quantum
5d053128ac [client] imgui: use improved high DPI rendering
This actually makes imgui render at a higher resolution, avoiding scaling
and resulting blurriness.
2021-07-23 16:07:42 +10:00
Quantum
df0397b10b [client] imgui: track last rectangles for overlays
This is necessary in case overlays change size. When this happens, we must
damage the larger of the overlays' rectangles this frame and last frame.
This erases the overlay from where it is no longer appears.

In order to do this, we must keep track of the rectangles for every overlay
with no exception. We cannot short-circuit the generation of rectangles if
we run out of buffer space, and we must allocate space for MAX_OVERLAY_RECTS
rectangles for every frame. Otherwise, we will not know where to erase the
overlay if it disappears.
2021-07-23 15:54:18 +10:00
Quantum
334bfeecea [client] egl: correctly handle mixing imgui and non-imgui overlays
This allows the full frame to be damaged when both types are visible.
2021-07-23 15:53:59 +10:00
Quantum
947eac52f6 [client] renderers: treat -1 as full damage and 0 as no overlay
This makes everything consistent.
2021-07-22 18:57:34 +10:00
Quantum
515f08d2da [client] egl: transform overlay damage coordinates
EGL uses bottom-up y-coordinate while we use top-down.
2021-07-22 18:32:18 +10:00
Quantum
58ab77d237 [client] egl: avoid overflowing damage buffer
We allocate 10 rectangles for overlay damage as agreed on Discord.
2021-07-22 18:32:18 +10:00
Geoffrey McRae
fdbdf6f167 [client] app: implement new overlay rendering framework
This change set implements a framework for overlays to be registered
that make use of ImGui. See `overlay/fps` for a simple implementation
example.
2021-07-22 17:27:30 +10:00
Quantum
27e3be3778 [client] egl: free desktop damage after rendering 2021-07-22 13:12:07 +10:00
Geoffrey McRae
08293c8721 [egl] damage: only update the damage vbo if there was a new frame 2021-07-21 17:29:46 +10:00
Geoffrey McRae
6389a06903 [client] main: let the renderer know if it's rendering a whole new frame
While the renderer can internally track this it would be better to
simply provide this information to the renderer directly so it can make
better decisions on how best to update the screen.
2021-07-21 17:26:48 +10:00
Quantum
563ad18f4e [client] egl: improve cursor damage logic
1. Use atomics and return exact cursor positions from egl_cursor_render
   to avoid race conditions between cursor render and update.
2. Instead of messing with lastCursorValid in various overlays, simply use
   the hasOverlay/hadOverlay logic for cursor damage. This simplifies the
   logic greatly.

As a result, I believe all cursor-related artifacts are fixed.

Note to reviewer: as atomic_init and atomic_store are implemented as macros,
it is currently not possible to pass structs as compound literals due to the
comma being interpreted as an argument separator by the preprocessor.
2021-07-20 11:29:13 +10:00
Quantum
7c872d2d9e [client] egl: properly use OpenGL ES
Instead of using the desktop <GL/gl.h>, we properly use the OpenGL ES 3.x
headers. Also, we now use GL_EXT_buffer_storage for MAP_PERSISTENT_BIT_EXT
and MAP_COHERENT_BIT_EXT as the core versions are only available in desktop
OpenGL 4.4. Similarly, we need GL_EXT_texture_format_BGRA8888 for GL_BGRA_EXT
as GL_BGRA is desktop-only.
2021-07-18 20:44:32 +10:00
Geoffrey McRae
ab31040d5f [client] all: use imgui for FPS/UPS display 2021-07-18 20:43:17 +10:00
Quantum
42d8f31eba [client] imgui: use ES 3.0 and remove glew dependency
If we specifically tell ImGui's OpenGL 3.x backend to target OpenGL ES 3.0,
then no extension loader is necessary.
2021-07-18 18:50:12 +10:00
Quantum
c6a6230a56 [client] egl: revert "only copy damaged areas when using dmabuf"
This reverts commit a14de25661.
Frame is sometimes incorrect.
2021-07-18 18:48:35 +10:00
Quantum
a14de25661 [client] egl: only copy damaged areas when using dmabuf
This speeds up the copy significantly when the frame only has small
amount of damage.
2021-07-18 17:41:29 +10:00
Quantum
a4bf3c8088 [client] egl: use debug context and make it configurable
The boolean option egl:debug is used to control whether we want debug
output or not. This defaults to true to aid in debugging.
2021-07-18 15:55:50 +10:00
Quantum
f49f2af6cd [client] egl: implement error reporting callback
This reports useful information from OpenGL on supported platforms.
2021-07-18 13:54:16 +10:00
Quantum
2b3f31700b [client] egl: implement frame damage display 2021-07-18 10:41:50 +10:00
Quantum
00eb26a34f [client] egl: do not use damage when overlays are visible
This allows the overlays to show up correctly.
2021-07-18 10:41:50 +10:00
Quantum
442ab318fd [client] egl: use desktop frame damage information 2021-07-18 10:41:50 +10:00
Geoffrey McRae
f08163fd72 [client] imgui: added imgui to the client and OpenGL/EGL renderers 2021-07-17 21:09:51 +10:00
Quantum
24d0aa0c18 [all] normalize copyright on all source files 2021-06-06 11:53:05 +10:00
Quantum
e70cfd84fb [client] egl: use eglSwapBuffersWithDamageKHR for cursor-only updates
Instead of damaging the entire surface when rendering a cursor move,
we can use the EGL_KHR_swap_buffers_with_damage extension to only
damage the part of the window covered by the cursor. This should
reduce the cursor movement latency on Wayland.
2021-05-19 18:56:36 +10:00
Quantum
f9a9953071 [client] egl: use new util_hasGLExt helper to check extensions
We previously used strstr, which can be prone to false positives when
the name of one extension is a substring of another extension.

This commit creates the helper function util_hasGLExt, which asserts
that the substring found in extension list is bounded by either spaces
or the beginning/end of the string.
2021-05-19 15:58:54 +10:00
Geoffrey McRae
8771103abb [client] all: fix more maybe-uninitialized when -O3 is in use
Closes #475
2021-02-23 20:25:30 +11:00
Quantum
30b5287c38 [client] egl: add option to set initial scale algorithm
The option is egl:scale. The scale algorithm number is displayed on the
alert to make it easier to specify the number for the option.
2021-02-22 17:25:06 +11:00
Geoffrey McRae
28024de314 [client] egl: fix gcc false maybe-uninitialized positives 2021-02-22 01:38:26 +11:00
Quantum
fd50426dda [client] egl: scale UI elements on high DPI displays
This is done by actually rendering the text at high DPI.
2021-02-21 19:06:53 +11:00
Quantum
3ec73e2444 [client] egl: support scaled UI for high DPI displays 2021-02-21 19:06:53 +11:00
Quantum
b35e19fc27 [client] renderer: add interface for high DPI rendering 2021-02-21 19:06:53 +11:00
Quantum
ba6f26393f [client] egl: add framework for multiple scaling algorithms
This commit fixes the issues with the meaning of useNearest being flipped
by removing the variable and use enumerations.

We define an enumeration EGL_DesktopScaleType to express the type of scaling
needed to be performed: no scaling, upscaling, or downscaling. This is
updated when either the frame size or the viewport size changes.
Previously, we only updated the useNearest when the frame size changes.

The desktop shader can now support an enumeration of scaling algorithms,
although only nearest and linear are currently implemented.

Like before, nearest is used when not scaling or upscaling, and linear is
used when downscaling.
2021-02-21 14:20:41 +11:00
Quantum
39a09ca565 [client] egl: remove dependency on SDL
After this PR, EGL functions are now accessed through <EGL/egl.h>
instead of through <SDL2/SDL_egl.h>, removing a pointless dependency
on SDL.
2021-02-21 10:31:49 +11:00
Quantum
89b73512ad [client] renderer: add ability to toggle the FPS display
Before, if you want to see the FPS, you need to close the client and
restart it with the -k switch to see the FPS. This is annoying.

This PR introduces a new keybind, ScrollLock+D, which, when pressed,
toggles the display of the FPS.

This is implemented for both EGL and OpenGL backends.
2021-02-21 10:31:48 +11:00
Geoffrey McRae
1d99c821eb [client] egl: decrease the font size for the help text 2021-02-21 10:31:48 +11:00
Quantum
2993f7ae7d [client] egl: create 24-bit colour context
This should prevent the looking-glass-client window from having an alpha
channel. On Wayland, the alpha channel is used to compose the window onto
the desktop, so the wallpaper would bleed through unless set to complete
opaque.

We worked around this by using constant alpha for rendering, but it was
not sustainable. Instead, we should just ask for 24-bit context.
2021-02-21 10:31:48 +11:00
Quantum
5ac53362a3 [client] renderer/egl: implement support for rendering help text
The help text is rendered in the bottom left corner on a semi-transparent
background, very similar to how the FPS text is rendered.
2021-02-21 10:31:48 +11:00
Quantum
5dce97264b [client] renderers: add on_help to renderer interface
This will be used to tell a render to display a help message.
2021-02-21 10:31:48 +11:00
Geoffrey McRae
4dfe4b8e2b [client] allow renderers to pass back if they need an OpenGL context 2021-02-21 10:31:48 +11:00
Quantum
9f0b99dac0 [client] wayland: implement window creation for egl
This commit implements window creation and resize logic, allowing the desktop
to be drawn.
2021-02-21 10:31:48 +11:00
Geoffrey McRae
ca5c3938e4 [client] all: move all SDL specific code into displayservers/sdl 2021-02-21 10:31:48 +11:00
Geoffrey McRae
bf583290a4 [client/common] restructure project in prep for full SDL removal 2021-02-21 10:31:46 +11:00
Tudor Brindus
637a7625d2 [client] wayland: allow EGL/OpenGL vsync to be set to on
This effectively reverts 4bceaf5.

Upstream ticket: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4180

Commit 941c651 makes working around the hang in LG itself not as
annoying as before.

In the future, we can bypass this entire issue by implementing our own
swapchain and listening to frame callbacks ourselves.
2021-02-09 09:12:57 +11:00
Geoffrey McRae
9e96156912 [client] egl: use eglGetPlatformDisplay(EXT) if possible 2021-01-25 16:04:33 +11:00
Geoffrey McRae
4c1893fe20 [all] fix numerous memory leaks at application shutdown 2021-01-24 21:47:53 +11:00
Geoffrey McRae
086f73721d [client] egl: remove accidental commit 2021-01-24 19:19:43 +11:00
Geoffrey McRae
202739c5be [client] egl: better debug output for EGL errors 2021-01-24 13:17:11 +11:00
Geoffrey McRae
88b15cb3fe [client] egl: nit, fix case of function name 2021-01-24 12:18:56 +11:00
Geoffrey McRae
9941a4bb83 [client] egl: runtime detect support for glEGLImageTargetTexture2DOES 2021-01-24 12:06:10 +11:00
Xiretza
31ea93dd0d [client] Fix compiler warnings about potentially uninitialized variables
Build failed with _FORTIFY_SOURCE enabled because the compiler couldn't
ensure the switch statements didn't hit the default arm and thus wouldn't
define the variables. Adding a statically failing assert makes sure that
all code paths either define the variables or fail early.

$ cd client
$ env CFLAGS='-O1 -D_FORTIFY_SOURCE=1' cmake -B build/
$ make -C build
[...]
client/renderers/EGL/egl.c: In function ‘egl_calc_mouse_size’:
client/renderers/EGL/egl.c:299:36: error: ‘h’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  299 |         (this->mouseHeight * (1.0f / h)) * this->scaleY
      |                              ~~~~~~^~~~
2021-01-20 03:05:30 +11:00
Geoffrey McRae
f9faa0542b [client] x11: use raw keyboard and mouse button press events 2021-01-19 20:36:43 +11:00
Geoffrey McRae
8a1578230f [client] all: properly support guest rotation
If the guest has it's output rotated (ie, landscape) we must rotate and
translate the pointer draw location, as well as all the translations of
cursor coordinate spaces based on the rotation, along with any local
rotations that may also be applied.
2021-01-19 02:54:56 +11:00
Geoffrey McRae
27a38294ea [client] major restructure of platform specific code 2021-01-16 20:41:13 +11:00
Geoffrey McRae
72c86d7125 [client] all: add screen rotation support win:rotate
Currently only supports EGL, if there is enough demand for OpenGL
support this can be added later.

Closes #231
2021-01-15 12:42:16 +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
19db67cfe5 [client] egl: detect the NVIDIA driver and disable DMA support
DMA suport for NVIDIA is advertised as available by the presense of the
extension `EGL_EXT_image_dma_buf_import`, however it is completely
broken. Until this is fixed refuse to use DMA support even if VM->VM
support is possible.

See: https://forums.developer.nvidia.com/t/egl-ext-image-dma-buf-import-broken-egl-bad-alloc-with-tons-of-free-ram/165552
2021-01-09 21:25:41 +11:00
Tudor Brindus
1ca5e439c1 [client] egl: disable EGL when running on Wayland
This commit makes Looking Glass always use the OpenGL renderer when
running on Wayland. The EGL renderer is broken on Wayland and can't
reasonably be fixed until SDL is dropped entirely (as per
https://github.com/gnif/LookingGlass/issues/306).

Until that time, the OpenGL renderer provides a much better
Wayland-native experience.
2021-01-04 15:47:01 +11:00
Geoffrey McRae
3016f0c53e [client] fix invalid method names 2021-01-04 14:44:33 +11:00
Tudor Brindus
4bceaf5505 [client] fix hang in eglSwapBuffers when exiting while not visible
eglSwapBuffers is allowed to block when called with a nonzero interval
parameter. On Wayland, Mesa will block until a frame callback arrives.
If an application is not visible, a compositor is free to not schedule
frame callbacks (in order to save CPU time rendering something that is
entirely invisible).

Currently, starting Looking Glass from a terminal, hiding it
entirely, and sending ^C will cause Looking Glass to hang joining the
render thread until the window is made visible again.

Calling eglDestroySurface is insufficient to unblock eglSwapBuffers, as
it attempts to grab the same underlying mutex.

Instead, this commit makes it so that we pass a 0 interval to
eglSwapBuffers when running on Wayland, such that we don't block waiting
for a frame callback. This is not entirely ideal as it *does* mean
Looking Glass submits buffers while hidden, but it seems better than
hanging on exit.

It also forces opengl:vsync and egl:vsync flags to off when running on
Wayland, as they are meaningless there.
2021-01-04 14:43:21 +11:00
Geoffrey McRae
bf1eba15d1 [client] egl: actually do front buffer rendering 2020-12-31 15:31:24 +11:00
Geoffrey McRae
806ff934b2 [client] egl: detect if egl is even available 2020-11-29 21:43:28 +11:00
Geoffrey McRae
36726bb349 [client] egl: fixed typo 2020-11-09 07:42:59 +11:00
Geoffrey McRae
dd7e0ea8c6 [client] egl: added colorblind support (egl:cbMode=0/1/2/3)
Based on http://www.daltonize.org/search/label/Daltonize

0 = Off
1 = Protanope
2 = Deuteranope
3 = Tritanope
2020-11-09 07:08:15 +11:00
Geoffrey McRae
4f9544d61d [client] egl: added DMA texture support for direct upload
Note: This only works with the KVMFR kernel module in a VM->VM
configuration. If this causes issues it can be disabled with the new
option `app:allowDMA`
2020-10-30 02:36:45 +11:00
Geoffrey McRae
0bf73d862d [client] added initial framework for dma buffer support 2020-10-30 02:36:45 +11:00
Geoffrey McRae
58ba76a27f [client] seperate frame setup and data events 2020-10-12 19:43:29 +11:00
Jonathan Rubenstein
66df00cee2 Add option to skip splash screen fade out 2020-10-09 03:28:58 +11:00
Geoffrey McRae
76e119f8ad [client] egl: don't fade the splash when restarting 2020-08-11 14:54:48 +10:00
Geoffrey McRae
da8b2d0cec [client] egl: properly wait for a new frame on restart 2020-08-11 14:45:08 +10:00
Geoffrey McRae
74649ddb96 [client] gracefully restart if the host application restarts 2020-08-11 14:30:44 +10:00
Geoffrey McRae
075c82b32c [client] egl: fix context binding enabling a lock free implementation 2020-05-22 17:47:19 +10:00
Geoffrey McRae
756b57400b [client] egl: move context init to lock function 2020-05-21 11:55:35 +10:00
Geoffrey McRae
01bfd2e090 [client] egl: make better use of the second thread for streaming 2020-05-21 11:44:56 +10:00
Geoffrey McRae
73ba325072 [client] egl: reworked the streaming texture pipeline 2020-05-19 22:03:36 +10:00
feltcat
e7f088ef52 [client] egl: typo fix in info message
"Multsampling" to "Multisampling"
2020-04-24 19:01:42 +10:00
Geoffrey McRae
4746c89227 [all] moved time and locking methods to the common library 2020-01-17 14:35:08 +11:00
Geoffrey McRae
278d851c7c [egl] added fallback for platforms not supporting eglGetPlatformDisplay 2020-01-17 11:50:00 +11:00
Geoffrey McRae
17e05c6fd5 [all] expose the FrameBuffer struct for correct sizeof calculations 2020-01-13 19:30:49 +11:00