{"id":18425258,"url":"https://github.com/uwerat/vnc-eglfs","last_synced_at":"2025-04-07T16:31:45.056Z","repository":{"id":48163656,"uuid":"487772881","full_name":"uwerat/vnc-eglfs","owner":"uwerat","description":"VNC server for Qt/Quick on EGLFS","archived":false,"fork":false,"pushed_at":"2024-06-21T09:26:22.000Z","size":140,"stargazers_count":25,"open_issues_count":8,"forks_count":12,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-06-22T10:39:53.439Z","etag":null,"topics":["eglfs","qt","qtquick","vnc-server"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uwerat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"uwerat"}},"created_at":"2022-05-02T08:37:47.000Z","updated_at":"2024-06-21T09:26:25.000Z","dependencies_parsed_at":"2024-02-17T11:48:52.362Z","dependency_job_id":null,"html_url":"https://github.com/uwerat/vnc-eglfs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uwerat%2Fvnc-eglfs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uwerat%2Fvnc-eglfs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uwerat%2Fvnc-eglfs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uwerat%2Fvnc-eglfs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uwerat","download_url":"https://codeload.github.com/uwerat/vnc-eglfs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223286479,"owners_count":17120000,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eglfs","qt","qtquick","vnc-server"],"created_at":"2024-11-06T05:03:20.561Z","updated_at":"2024-11-06T05:03:21.256Z","avatar_url":"https://github.com/uwerat.png","language":"C++","funding_links":["https://github.com/sponsors/uwerat"],"categories":[],"sub_categories":[],"readme":"# VNC for Qt/Quick on EGLFS\n\nThis project implements a [VNC](https://en.wikipedia.org/wiki/Virtual_Network_Computing)\nserver for [Qt/Quick](https://doc.qt.io/qt-6/qtquick-index.html) windows.\n\nThe basic idea of this server is to grab each frame from the GPU and to forward it\nto the [RFB protocol]( https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst ).\u003cbr\u003e\nThis implementation is not affected by [limitions]( https://doc.qt.io/QtQuick2DRenderer/qtquick2drenderer-limitations.html )\nof the [software renderer]( https://doc.qt.io/QtQuick2DRenderer ) and allows having native OpenGL code\nin application code ( custom scene graph nodes ).\n\nAs the [Qt/Quick](https://doc.qt.io/qt-6/qtquick-index.html) technology is for\n\"fluid and dynamic user interfaces\" the VNC server has to be able to forward\nfull updates ( f.e. fade in/out ) with an acceptable rate to the viewer, what\nmakes [image compression]( https://en.wikipedia.org/wiki/Image_compression) more or less mandatory.\nFortunately modern [GPUs](https://en.wikipedia.org/wiki/Graphics_processing_unit) usually offer\n[encoding]( https://en.wikipedia.org/wiki/Graphics_processing_unit#GPU_accelerated_video_decoding_and_encoding)\nfor [JPEG]( https://en.wikipedia.org/wiki/JPEG ) and [H.264]( https://en.wikipedia.org/wiki/Advanced_Video_Coding ).\nEncoding on the GPU also avoids the expensive calls of\n[glReadPixels](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glReadPixels.xhtml) for each frame.\n\nObvious limitations:\n\n- no partial updates\n\n    A VNC server always transfers complete frames without trying to optimize for partial updates.\n    Despite the fact that there is no ( at least I do not know one ) unexpensive way to identify\n    the update regions it would not help much for situations like swiping, fading in/out etc.\n    Of course this leads to more traffic than necessary for other situations like pressing a button.\n    Using a compression like [H.264]( https://en.wikipedia.org/wiki/Advanced_Video_Coding ),\n    that is using differences between frames, might be the best solution.\n\n- windows instead of screens\n\n    Usually VNC is used to mirror a complete screen/desktop with several windows\n    from different applications. However the \"recommended plugin for modern Embedded Linux devices\"\n    [EGLFS]( https://doc.qt.io/qt-6/embedded-linux.html ) only supports top level windows\n    in fullscreen mode - what kind of equals windows and screens.\n    For other platforms - like xcb or wayland - good solutions for mirroring a desktop are\n    available.\n\nThe code might work with all Qt versions \u003e= 5.6.\n\n# Project Status\n\nThe current status of the implementation was tested with\nremote connections to an application running on EGLFS and XCB.\n\nNumbers depend on the capabilities of the devices and the size/content of the window,\nbut on my test system ( Intel i7-8559U ) I was able to display a window with 800x800 pixels\nwith \u003e= 20fps remotely, when JPEG compression is enabled.\nThe number was found by running \u003cem\u003extigervncviewer -Log '*:stderr:100'\u003c/em\u003e as viewer.\n\nThese features are implemented:\n\n- mandatory parts of the RFB V3.3 protocol ( including VNC authentication )\n\n    This similar to what is supported by the Qt VNC plugin ( + mouse wheel, additional key codes )\n\n- [Tight/JPEG]( https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#tight-encoding )\n\n    Using the encoder from [Qt's image I/O system]( https://doc.qt.io/qt-6/qtimageformats-index.html),\n    usually a wrapper for: [libjpeg-turbo]( https://libjpeg-turbo.org/ )\n\nThe following important parts are missing:\n\n- [Authentication ( \u003e V3.3 )]( https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#security-types )\n\n- [H.264 ]( https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#open-h-264-encoding )\n\n    Looks like support for H.264 has been [added recently]( https://github.com/TigerVNC/tigervnc/pull/1194 )\n    to the [TigerVNC]( https://github.com/TigerVNC ) viewer.\n\n- hardware video acceleration: [VA_API]( https://en.wikipedia.org/wiki/Video_Acceleration_API )\n\n    Without compressing the frames early on the GPU the performance of the pipeline suffers\n    from expensive glReadPixels calls and what is needed to compress the image on the CPU.\u003cbr\u003e\n    If you are familiar with [libva]( http://intel.github.io/libva/group__api__core.html)\n    and want to help: let me know.\n\n# How to use\n\nThere are 2 way how to enable VNC support for an applation:\n\n- [C++ API]( https://github.com/uwerat/vnc-eglfs/blob/main/src/VncNamespace.h )\n\n    The C++ API allows to configure, start and stop a VNC servers individually.\n\n- [VNC platform integration proxy]( https://github.com/uwerat/vnc-eglfs/blob/main/platformproxy/VncProxyPlugin.cpp )\n\n    The VNC platform proxy allows to start VNC servers for applications that can't be modified\n    or recompiled.\n\nBoth solutions are affected by the following environment variables:\n\n- QVNC_GL_PORT\n\n   The first unused port \u003e= $QVNC_GL_PORT will be used when starting a server\n\n- QVNC_GLTIMER_INTERVAL\n\n   each server is periodically checking if a new frame is available\n   and the viewer is ready to accept it. Increasing the interval might\n   decrease the number of updates being displayed in the viewer.\n\n- QVNC_GL_PASSWORD\n\n  A string of max. 8 characters. Setting a non empty password enables\n  VNC authentication.\n\n### Application code\n\nThe most simple way to enable VNC support is to add the following line somewhere:\n\n```\n#include \u003cVncNamespace.h\u003e\n\nVNC::setup();\n```\n\nIf you want to get rid of the local windows you have several options:\n\n- using the [gbm platform plugin](https://github.com/uwerat/qpagbm)\n- using the undocumented \"offscreen\" platform, that comes with Qt ( X11 only )\n- reconfiguring a [headless](https://doc.qt.io/qt-5/embedded-linux.html#advanced-eglfs-kms-features) mode ( EGLFS only  )\n\n### VNC platform integration proxy\n\nIf you do not want ( or can't ) touch application code you can load the VNC platform\nplugin proxy by using one of these: [keys](https://github.com/uwerat/vnc-eglfs/blob/main/platformproxy/metadata.json).\nThe [proxy](https://github.com/uwerat/vnc-eglfs/blob/main/platformproxy/VncProxyPlugin.cpp)\nsimply does the initialization above before loading the real plugin following the \"vnc\" prefix.\n\nAssuming library and plugin are installed in \"/usr/local/vnceglfs\":\n\n```\n# export QT_DEBUG_PLUGINS=1\nexport QT_QPA_PLATFORM_PLUGIN_PATH=\"/usr/local/vnceglfs/plugins/platforms\"\nexport LD_LIBRARY_PATH=\"/usr/local/vnceglfs/lib\"\n\nexport QT_QPA_PLATFORM=vnceglfs # vncxcb, vncwayland, vncoffscreen, vncgbm\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuwerat%2Fvnc-eglfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuwerat%2Fvnc-eglfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuwerat%2Fvnc-eglfs/lists"}