mirror of
https://github.com/LizardByte/Sunshine.git
synced 2026-02-07 00:46:19 +01:00
feat(linux)!: Support streaming through XDG portals and Pipewire (#4417)
Some checks failed
CodeQL / CodeQL (push) Has been cancelled
CI / Coverage-Homebrew-macos-14 (push) Has been cancelled
CI / GitHub Env Debug (push) Has been cancelled
CI / Release Setup (push) Has been cancelled
CI / Docker (push) Has been cancelled
CI / FreeBSD (push) Has been cancelled
CI / Homebrew (push) Has been cancelled
CI / Linux (push) Has been cancelled
CI / Archlinux (push) Has been cancelled
CI / Linux Copr (push) Has been cancelled
CI / Linux Flatpak (push) Has been cancelled
CI / Windows (push) Has been cancelled
CI / Bundle Analysis (push) Has been cancelled
CI / Coverage-Homebrew-macos-15 (push) Has been cancelled
CI / Coverage-Homebrew-macos-26 (push) Has been cancelled
CI / Coverage-Archlinux (push) Has been cancelled
CI / Coverage-FreeBSD-14.3-aarch64 (push) Has been cancelled
CI / Coverage-FreeBSD-14.3-amd64 (push) Has been cancelled
CI / Coverage-Homebrew-ubuntu-22.04 (push) Has been cancelled
CI / Coverage-Linux-AppImage (push) Has been cancelled
CI / Coverage-Windows-AMD64 (push) Has been cancelled
CI / Release (push) Has been cancelled
CI / Release Homebrew Beta (push) Has been cancelled
localize / Update Localization (push) Has been cancelled
Build GH-Pages / prep (push) Has been cancelled
Build GH-Pages / call-jekyll-build (push) Has been cancelled
Some checks failed
CodeQL / CodeQL (push) Has been cancelled
CI / Coverage-Homebrew-macos-14 (push) Has been cancelled
CI / GitHub Env Debug (push) Has been cancelled
CI / Release Setup (push) Has been cancelled
CI / Docker (push) Has been cancelled
CI / FreeBSD (push) Has been cancelled
CI / Homebrew (push) Has been cancelled
CI / Linux (push) Has been cancelled
CI / Archlinux (push) Has been cancelled
CI / Linux Copr (push) Has been cancelled
CI / Linux Flatpak (push) Has been cancelled
CI / Windows (push) Has been cancelled
CI / Bundle Analysis (push) Has been cancelled
CI / Coverage-Homebrew-macos-15 (push) Has been cancelled
CI / Coverage-Homebrew-macos-26 (push) Has been cancelled
CI / Coverage-Archlinux (push) Has been cancelled
CI / Coverage-FreeBSD-14.3-aarch64 (push) Has been cancelled
CI / Coverage-FreeBSD-14.3-amd64 (push) Has been cancelled
CI / Coverage-Homebrew-ubuntu-22.04 (push) Has been cancelled
CI / Coverage-Linux-AppImage (push) Has been cancelled
CI / Coverage-Windows-AMD64 (push) Has been cancelled
CI / Release (push) Has been cancelled
CI / Release Homebrew Beta (push) Has been cancelled
localize / Update Localization (push) Has been cancelled
Build GH-Pages / prep (push) Has been cancelled
Build GH-Pages / call-jekyll-build (push) Has been cancelled
Co-authored-by: Carlos Garnacho <carlosg@gnome.org> Co-authored-by: Carson Katri <Carson.katri@gmail.com> Co-authored-by: Bond <bond-d@ukr.net> Co-authored-by: d.bondarev <d.bondarev@crm-onebox.com> Co-authored-by: Conn O'Griofa <connogriofa@gmail.com>
This commit is contained in:
2
.github/workflows/ci-freebsd.yml
vendored
2
.github/workflows/ci-freebsd.yml
vendored
@@ -114,6 +114,7 @@ jobs:
|
||||
graphics/wayland \
|
||||
lang/python312 \
|
||||
multimedia/libva \
|
||||
multimedia/pipewire \
|
||||
net/miniupnpc \
|
||||
ports-mgmt/pkg \
|
||||
security/openssl \
|
||||
@@ -167,6 +168,7 @@ jobs:
|
||||
-DSUNSHINE_EXECUTABLE_PATH=/usr/local/bin/sunshine \
|
||||
-DSUNSHINE_ENABLE_CUDA=OFF \
|
||||
-DSUNSHINE_ENABLE_DRM=OFF \
|
||||
-DSUNSHINE_ENABLE_PORTAL=ON \
|
||||
-DSUNSHINE_ENABLE_WAYLAND=ON \
|
||||
-DSUNSHINE_ENABLE_X11=ON \
|
||||
-DSUNSHINE_PUBLISHER_NAME="${GITHUB_REPOSITORY_OWNER}" \
|
||||
|
||||
@@ -19,6 +19,11 @@ IF (NOT WIN32)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
OUTPUT_VARIABLE SYSTEMD_USER_UNIT_INSTALL_DIR)
|
||||
|
||||
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE}
|
||||
--variable=systemd_user_preset_dir systemd
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
OUTPUT_VARIABLE SYSTEMD_USER_PRESET_INSTALL_DIR)
|
||||
|
||||
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE}
|
||||
--variable=systemd_system_unit_dir systemd
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
@@ -29,7 +34,12 @@ IF (NOT WIN32)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
OUTPUT_VARIABLE SYSTEMD_MODULES_LOAD_DIR)
|
||||
|
||||
mark_as_advanced(SYSTEMD_USER_UNIT_INSTALL_DIR SYSTEMD_SYSTEM_UNIT_INSTALL_DIR SYSTEMD_MODULES_LOAD_DIR)
|
||||
mark_as_advanced(
|
||||
SYSTEMD_USER_UNIT_INSTALL_DIR
|
||||
SYSTEMD_USER_PRESET_INSTALL_DIR
|
||||
SYSTEMD_SYSTEM_UNIT_INSTALL_DIR
|
||||
SYSTEMD_MODULES_LOAD_DIR
|
||||
)
|
||||
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -168,12 +168,29 @@ if(X11_FOUND)
|
||||
"${CMAKE_SOURCE_DIR}/src/platform/linux/x11grab.cpp")
|
||||
endif()
|
||||
|
||||
# XDG portal
|
||||
if(${SUNSHINE_ENABLE_PORTAL})
|
||||
pkg_check_modules(GIO gio-2.0 gio-unix-2.0 REQUIRED)
|
||||
pkg_check_modules(PIPEWIRE libpipewire-0.3 REQUIRED)
|
||||
else()
|
||||
set(GIO_FOUND OFF)
|
||||
set(PIPEWIRE_FOUND OFF)
|
||||
endif()
|
||||
if(PIPEWIRE_FOUND)
|
||||
add_compile_definitions(SUNSHINE_BUILD_PORTAL)
|
||||
include_directories(SYSTEM ${GIO_INCLUDE_DIRS} ${PIPEWIRE_INCLUDE_DIRS})
|
||||
list(APPEND PLATFORM_LIBRARIES ${GIO_LIBRARIES} ${PIPEWIRE_LIBRARIES})
|
||||
list(APPEND PLATFORM_TARGET_FILES
|
||||
"${CMAKE_SOURCE_DIR}/src/platform/linux/portalgrab.cpp")
|
||||
endif()
|
||||
|
||||
if(NOT ${CUDA_FOUND}
|
||||
AND NOT ${WAYLAND_FOUND}
|
||||
AND NOT ${X11_FOUND}
|
||||
AND NOT ${PIPEWIRE_FOUND}
|
||||
AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND})
|
||||
AND NOT ${LIBVA_FOUND})
|
||||
message(FATAL_ERROR "Couldn't find either cuda, wayland, x11, (libdrm and libcap), or libva")
|
||||
message(FATAL_ERROR "Couldn't find either cuda, libva, pipewire, wayland, x11, or (libdrm and libcap)")
|
||||
endif()
|
||||
|
||||
# tray icon
|
||||
|
||||
@@ -18,6 +18,10 @@ if(${SUNSHINE_BUILD_APPIMAGE} OR ${SUNSHINE_BUILD_FLATPAK})
|
||||
DESTINATION "${SUNSHINE_ASSETS_DIR}/modules-load.d")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service"
|
||||
DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine-kms.service"
|
||||
DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/00-sunshine-kms.preset"
|
||||
DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user-preset")
|
||||
else()
|
||||
find_package(Systemd)
|
||||
find_package(Udev)
|
||||
@@ -29,6 +33,10 @@ else()
|
||||
if(SYSTEMD_FOUND)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service"
|
||||
DESTINATION "${SYSTEMD_USER_UNIT_INSTALL_DIR}")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine-kms.service"
|
||||
DESTINATION "${SYSTEMD_USER_UNIT_INSTALL_DIR}")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/00-sunshine-kms.preset"
|
||||
DESTINATION "${SYSTEMD_USER_PRESET_INSTALL_DIR}")
|
||||
install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/60-sunshine.conf"
|
||||
DESTINATION "${SYSTEMD_MODULES_LOAD_DIR}")
|
||||
endif()
|
||||
@@ -105,10 +113,11 @@ list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
|
||||
audio/opus
|
||||
ftp/curl
|
||||
devel/libevdev
|
||||
multimedia/pipewire
|
||||
net/avahi
|
||||
x11/libX11
|
||||
net/miniupnpc
|
||||
security/openssl
|
||||
x11/libX11
|
||||
)
|
||||
|
||||
if(NOT BOOST_USE_STATIC)
|
||||
|
||||
@@ -64,4 +64,6 @@ elseif(UNIX) # Linux
|
||||
"Enable building wayland specific code." ON)
|
||||
option(SUNSHINE_ENABLE_X11
|
||||
"Enable X11 grab if available." ON)
|
||||
option(SUNSHINE_ENABLE_PORTAL
|
||||
"Enable XDG portal grab if available" ON)
|
||||
endif()
|
||||
|
||||
@@ -26,6 +26,8 @@ elseif(UNIX)
|
||||
|
||||
# configure service
|
||||
configure_file(packaging/linux/sunshine.service.in sunshine.service @ONLY)
|
||||
configure_file(packaging/linux/sunshine-kms.service.in sunshine-kms.service @ONLY)
|
||||
configure_file(packaging/linux/00-sunshine-kms.preset.in 00-sunshine-kms.preset @ONLY)
|
||||
|
||||
# configure the arch linux pkgbuild
|
||||
if(${SUNSHINE_CONFIGURE_PKGBUILD})
|
||||
|
||||
@@ -274,16 +274,11 @@ flatpak install --user ./sunshine_{arch}.flatpak
|
||||
flatpak run --command=additional-install.sh dev.lizardbyte.app.Sunshine
|
||||
```
|
||||
|
||||
##### Run with NVFBC capture (X11 Only)
|
||||
##### Run with NVFBC capture (X11 Only) or XDG Portal (Wayland Only)
|
||||
```bash
|
||||
flatpak run dev.lizardbyte.app.Sunshine
|
||||
```
|
||||
|
||||
##### Run with KMS capture (Wayland & X11)
|
||||
```bash
|
||||
sudo -i PULSE_SERVER=unix:/run/user/$(id -u $whoami)/pulse/native flatpak run dev.lizardbyte.app.Sunshine
|
||||
```
|
||||
|
||||
##### Uninstall
|
||||
```bash
|
||||
flatpak run --command=remove-additional-install.sh dev.lizardbyte.app.Sunshine
|
||||
@@ -405,37 +400,21 @@ After adding yourself to the group, log out and log back in for the changes to t
|
||||
|
||||
### Linux
|
||||
|
||||
#### KMS Capture
|
||||
|
||||
> [!WARNING]
|
||||
> Capture of most Wayland-based desktop environments will fail unless this step is performed.
|
||||
#### Services
|
||||
|
||||
> [!NOTE]
|
||||
> `cap_sys_admin` may as well be root, except you don't need to be root to run the program. This is necessary to
|
||||
> allow Sunshine to use KMS capture.
|
||||
|
||||
##### Enable
|
||||
```bash
|
||||
sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))
|
||||
```
|
||||
|
||||
#### X11 Capture
|
||||
For X11 capture to work, you may need to disable the capabilities that were set for KMS capture.
|
||||
|
||||
```bash
|
||||
sudo setcap -r $(readlink -f $(which sunshine))
|
||||
```
|
||||
|
||||
#### Service
|
||||
> Two service unit files are available. Pick "sunshine" for unprivileged XDG Portal or X11 capture, otherwise
|
||||
> pick "sunshine-kms" for privileged KMS capture.
|
||||
|
||||
**Start once**
|
||||
```bash
|
||||
systemctl --user start sunshine
|
||||
```
|
||||
|
||||
**Start on boot**
|
||||
**Start on boot (unprivileged; swap logic for KMS)**
|
||||
```bash
|
||||
systemctl --user enable sunshine
|
||||
systemctl --user --now disable sunshine-kms
|
||||
systemctl --user --now enable sunshine
|
||||
```
|
||||
|
||||
### macOS
|
||||
|
||||
@@ -160,16 +160,18 @@ sudo usermod -aG input $USER
|
||||
```
|
||||
|
||||
### KMS Streaming fails
|
||||
If screencasting fails with KMS, you may need to run the following to force unprivileged screencasting.
|
||||
If screencasting fails with KMS, you may be using the unprivileged sunshine service unit. Switch to the privileged
|
||||
sunshine-kms service:
|
||||
|
||||
```bash
|
||||
sudo setcap -r $(readlink -f $(which sunshine))
|
||||
systemctl --user --now disable sunshine
|
||||
systemctl --user --now enable sunshine-kms
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> The above command will not work with the AppImage or Flatpak packages. Please refer to the
|
||||
> [AppImage setup](md_docs_2getting__started.html#appimage) or
|
||||
> [Flatpak setup](md_docs_2getting__started.html#flatpak) for more specific instructions.
|
||||
> The above commands will not work with the AppImage or Flatpak packages, as KMS screencasting
|
||||
> requires elevated privileges which are not allowed by their respective packaging security policies.
|
||||
> As an alternative, XDG Portal capture is recommended.
|
||||
|
||||
### KMS streaming fails on Nvidia GPUs
|
||||
If KMS screen capture results in a black screen being streamed, you may need to
|
||||
|
||||
4
packaging/linux/00-sunshine-kms.preset.in
Normal file
4
packaging/linux/00-sunshine-kms.preset.in
Normal file
@@ -0,0 +1,4 @@
|
||||
# @PROJECT_DESCRIPTION@
|
||||
# KMS service should preset to disabled
|
||||
|
||||
disable sunshine-kms.service
|
||||
@@ -37,6 +37,7 @@ depends=(
|
||||
'libevdev'
|
||||
'libmfx'
|
||||
'libnotify'
|
||||
'libpipewire'
|
||||
'libpulse'
|
||||
'libva'
|
||||
'libx11'
|
||||
|
||||
@@ -41,6 +41,7 @@ BuildRequires: libXinerama-devel
|
||||
BuildRequires: libXrandr-devel
|
||||
BuildRequires: libXtst-devel
|
||||
BuildRequires: openssl-devel
|
||||
BuildRequires: pipewire-devel
|
||||
BuildRequires: rpm-build
|
||||
BuildRequires: systemd-rpm-macros
|
||||
BuildRequires: wget
|
||||
@@ -194,9 +195,10 @@ cmake_args=(
|
||||
"-DCMAKE_INSTALL_PREFIX=%{_prefix}"
|
||||
"-DSUNSHINE_ASSETS_DIR=%{_datadir}/sunshine"
|
||||
"-DSUNSHINE_EXECUTABLE_PATH=%{_bindir}/sunshine"
|
||||
"-DSUNSHINE_ENABLE_DRM=ON"
|
||||
"-DSUNSHINE_ENABLE_PORTAL=ON"
|
||||
"-DSUNSHINE_ENABLE_WAYLAND=ON"
|
||||
"-DSUNSHINE_ENABLE_X11=ON"
|
||||
"-DSUNSHINE_ENABLE_DRM=ON"
|
||||
"-DSUNSHINE_PUBLISHER_NAME=LizardByte"
|
||||
"-DSUNSHINE_PUBLISHER_WEBSITE=https://app.lizardbyte.dev"
|
||||
"-DSUNSHINE_PUBLISHER_ISSUE_URL=https://app.lizardbyte.dev/support"
|
||||
@@ -366,8 +368,10 @@ fi
|
||||
%caps(cap_sys_admin+p) %{_bindir}/sunshine
|
||||
%caps(cap_sys_admin+p) %{_bindir}/sunshine-*
|
||||
|
||||
# Systemd unit file for user services
|
||||
# Systemd unit/preset files for user services
|
||||
%{_userunitdir}/sunshine.service
|
||||
%{_userunitdir}/sunshine-kms.service
|
||||
%{_userpresetdir}/00-sunshine-kms.preset
|
||||
|
||||
# Udev rules
|
||||
%{_udevrulesdir}/*-sunshine.rules
|
||||
|
||||
@@ -33,10 +33,6 @@
|
||||
<code>flatpak run --command=additional-install.sh @PROJECT_FQDN@</code>
|
||||
</p>
|
||||
<p>NOTE: Sunshine uses a self-signed certificate. The web browser will report it as not secure, but it is safe.</p>
|
||||
<p>NOTE: KMS Grab (Flatpak)</p>
|
||||
<p>
|
||||
<code>sudo -i PULSE_SERVER=unix:/run/user/$(id -u $whoami)/pulse/native flatpak run @PROJECT_FQDN@</code>
|
||||
</p>
|
||||
</description>
|
||||
|
||||
<releases>
|
||||
|
||||
@@ -69,10 +69,11 @@ modules:
|
||||
- -DSUNSHINE_ASSETS_DIR=share/sunshine
|
||||
- -DSUNSHINE_BUILD_FLATPAK=ON
|
||||
- -DSUNSHINE_EXECUTABLE_PATH=/app/bin/sunshine
|
||||
- -DSUNSHINE_ENABLE_CUDA=ON
|
||||
- -DSUNSHINE_ENABLE_DRM=ON
|
||||
- -DSUNSHINE_ENABLE_PORTAL=ON
|
||||
- -DSUNSHINE_ENABLE_WAYLAND=ON
|
||||
- -DSUNSHINE_ENABLE_X11=ON
|
||||
- -DSUNSHINE_ENABLE_DRM=ON
|
||||
- -DSUNSHINE_ENABLE_CUDA=ON
|
||||
- -DSUNSHINE_PUBLISHER_NAME='LizardByte'
|
||||
- -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev'
|
||||
- -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support'
|
||||
|
||||
16
packaging/linux/sunshine-kms.service.in
Normal file
16
packaging/linux/sunshine-kms.service.in
Normal file
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=@PROJECT_DESCRIPTION@
|
||||
StartLimitIntervalSec=500
|
||||
StartLimitBurst=5
|
||||
Conflicts=sunshine.service
|
||||
|
||||
[Service]
|
||||
# Avoid starting Sunshine before the desktop is fully initialized.
|
||||
ExecStartPre=/bin/sleep 5
|
||||
@SUNSHINE_SERVICE_START_COMMAND@
|
||||
@SUNSHINE_SERVICE_STOP_COMMAND@
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=xdg-desktop-autostart.target
|
||||
@@ -2,6 +2,7 @@
|
||||
Description=@PROJECT_DESCRIPTION@
|
||||
StartLimitIntervalSec=500
|
||||
StartLimitBurst=5
|
||||
Conflicts=sunshine-kms.service
|
||||
|
||||
[Service]
|
||||
# Avoid starting Sunshine before the desktop is fully initialized.
|
||||
@@ -10,6 +11,7 @@ ExecStartPre=/bin/sleep 5
|
||||
@SUNSHINE_SERVICE_STOP_COMMAND@
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
WantedBy=xdg-desktop-autostart.target
|
||||
|
||||
@@ -91,6 +91,7 @@ class Sunshine < Formula
|
||||
depends_on "mesa"
|
||||
depends_on "numactl"
|
||||
depends_on "pango"
|
||||
depends_on "pipewire"
|
||||
depends_on "pulseaudio"
|
||||
depends_on "systemd"
|
||||
depends_on "wayland"
|
||||
|
||||
@@ -234,6 +234,7 @@ function add_debian_based_deps() {
|
||||
"libnotify-dev"
|
||||
"libnuma-dev"
|
||||
"libopus-dev"
|
||||
"libpipewire-0.3-dev"
|
||||
"libpulse-dev"
|
||||
"libssl-dev"
|
||||
"libsystemd-dev"
|
||||
@@ -322,6 +323,7 @@ function add_fedora_deps() {
|
||||
"numactl-devel"
|
||||
"openssl-devel"
|
||||
"opus-devel"
|
||||
"pipewire-devel"
|
||||
"pulseaudio-libs-devel"
|
||||
"rpm-build" # if you want to build an RPM binary package
|
||||
"wget" # necessary for cuda install with `run` file
|
||||
@@ -545,9 +547,10 @@ function run_step_cmake() {
|
||||
"-DCMAKE_INSTALL_PREFIX=/usr"
|
||||
"-DSUNSHINE_ASSETS_DIR=share/sunshine"
|
||||
"-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine"
|
||||
"-DSUNSHINE_ENABLE_DRM=ON"
|
||||
"-DSUNSHINE_ENABLE_PORTAL=ON"
|
||||
"-DSUNSHINE_ENABLE_WAYLAND=ON"
|
||||
"-DSUNSHINE_ENABLE_X11=ON"
|
||||
"-DSUNSHINE_ENABLE_DRM=ON"
|
||||
)
|
||||
|
||||
if [[ "$appimage_build" == 1 ]]; then
|
||||
|
||||
@@ -1660,9 +1660,9 @@ namespace platf {
|
||||
|
||||
if (!fb->handles[0]) {
|
||||
BOOST_LOG(error) << "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Probably not permitted"sv;
|
||||
BOOST_LOG((window_system != window_system_e::X11 || config::video.capture == "kms") ? fatal : error)
|
||||
<< "You must run [sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))] for KMS display capture to work!\n"sv
|
||||
<< "If you installed from AppImage or Flatpak, please refer to the official documentation:\n"sv
|
||||
BOOST_LOG((config::video.capture == "kms") ? fatal : error)
|
||||
<< "If you installed from AppImage or Flatpak, KMS capture is not supported.\n"sv
|
||||
<< "Please refer to the official documentation:\n"sv
|
||||
<< "https://docs.lizardbyte.dev/projects/sunshine/latest/md_docs_2getting__started.html#linux"sv;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -888,6 +888,9 @@ namespace platf {
|
||||
#endif
|
||||
#ifdef SUNSHINE_BUILD_X11
|
||||
X11, ///< X11
|
||||
#endif
|
||||
#ifdef SUNSHINE_BUILD_PORTAL
|
||||
PORTAL, ///< XDG PORTAL
|
||||
#endif
|
||||
MAX_FLAGS ///< The maximum number of flags
|
||||
};
|
||||
@@ -931,6 +934,15 @@ namespace platf {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUNSHINE_BUILD_PORTAL
|
||||
std::vector<std::string> portal_display_names();
|
||||
std::shared_ptr<display_t> portal_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
|
||||
|
||||
bool verify_portal() {
|
||||
return !portal_display_names().empty();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<std::string> display_names(mem_type_e hwdevice_type) {
|
||||
#ifdef SUNSHINE_BUILD_CUDA
|
||||
// display using NvFBC only supports mem_type_e::cuda
|
||||
@@ -952,6 +964,11 @@ namespace platf {
|
||||
if (sources[source::X11]) {
|
||||
return x11_display_names();
|
||||
}
|
||||
#endif
|
||||
#ifdef SUNSHINE_BUILD_PORTAL
|
||||
if (sources[source::PORTAL]) {
|
||||
return portal_display_names();
|
||||
}
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
@@ -990,6 +1007,12 @@ namespace platf {
|
||||
return x11_display(hwdevice_type, display_name, config);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUNSHINE_BUILD_PORTAL
|
||||
if (sources[source::PORTAL]) {
|
||||
BOOST_LOG(info) << "Screencasting with XDG portal"sv;
|
||||
return portal_display(hwdevice_type, display_name, config);
|
||||
}
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1019,33 +1042,30 @@ namespace platf {
|
||||
#endif
|
||||
|
||||
#ifdef SUNSHINE_BUILD_CUDA
|
||||
if ((config::video.capture.empty() && sources.none()) || config::video.capture == "nvfbc") {
|
||||
if (verify_nvfbc()) {
|
||||
sources[source::NVFBC] = true;
|
||||
}
|
||||
if (((config::video.capture.empty() && sources.none()) || config::video.capture == "nvfbc") && verify_nvfbc()) {
|
||||
sources[source::NVFBC] = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef SUNSHINE_BUILD_WAYLAND
|
||||
if ((config::video.capture.empty() && sources.none()) || config::video.capture == "wlr") {
|
||||
if (verify_wl()) {
|
||||
sources[source::WAYLAND] = true;
|
||||
}
|
||||
if (((config::video.capture.empty() && sources.none()) || config::video.capture == "wlr") && verify_wl()) {
|
||||
sources[source::WAYLAND] = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef SUNSHINE_BUILD_DRM
|
||||
if ((config::video.capture.empty() && sources.none()) || config::video.capture == "kms") {
|
||||
if (verify_kms()) {
|
||||
sources[source::KMS] = true;
|
||||
}
|
||||
if (((config::video.capture.empty() && sources.none()) || config::video.capture == "kms") && verify_kms()) {
|
||||
sources[source::KMS] = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef SUNSHINE_BUILD_X11
|
||||
// We enumerate this capture backend regardless of other suitable sources,
|
||||
// since it may be needed as a NvFBC fallback for software encoding on X11.
|
||||
if (config::video.capture.empty() || config::video.capture == "x11") {
|
||||
if (verify_x11()) {
|
||||
sources[source::X11] = true;
|
||||
}
|
||||
if ((config::video.capture.empty() || config::video.capture == "x11") && verify_x11()) {
|
||||
sources[source::X11] = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef SUNSHINE_BUILD_PORTAL
|
||||
if ((config::video.capture.empty() || config::video.capture == "portal") && verify_portal()) {
|
||||
sources[source::PORTAL] = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
1183
src/platform/linux/portalgrab.cpp
Normal file
1183
src/platform/linux/portalgrab.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -67,12 +67,14 @@ const config = ref(props.config)
|
||||
<template #freebsd>
|
||||
<option value="wlr">wlroots</option>
|
||||
<option value="x11">X11</option>
|
||||
<option value="portal">XDG Portal</option>
|
||||
</template>
|
||||
<template #linux>
|
||||
<option value="nvfbc">NvFBC</option>
|
||||
<option value="wlr">wlroots</option>
|
||||
<option value="kms">KMS</option>
|
||||
<option value="x11">X11</option>
|
||||
<option value="portal">XDG Portal</option>
|
||||
</template>
|
||||
<template #windows>
|
||||
<option value="ddx">Desktop Duplication API</option>
|
||||
|
||||
10
third-party/glad/include/glad/egl.h
vendored
10
third-party/glad/include/glad/egl.h
vendored
@@ -467,6 +467,14 @@ typedef EGLBoolean(GLAD_API_PTR *PFNEGLWAITSYNCPROC)(EGLDisplay dpy, EGLSync syn
|
||||
typedef EGLImageKHR(EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
|
||||
typedef EGLBoolean(EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC)(EGLDisplay dpy, EGLImageKHR image);
|
||||
|
||||
typedef EGLenum(EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC)(EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats);
|
||||
typedef EGLenum(EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC)(EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers);
|
||||
|
||||
GLAD_API_CALL PFNEGLQUERYDMABUFFORMATSEXTPROC glad_eglQueryDmaBufFormatsEXT;
|
||||
#define eglQueryDmaBufFormatsEXT glad_eglQueryDmaBufFormatsEXT
|
||||
GLAD_API_CALL PFNEGLQUERYDMABUFMODIFIERSEXTPROC glad_eglQueryDmaBufModifiersEXT;
|
||||
#define eglQueryDmaBufModifiersEXT glad_eglQueryDmaBufModifiersEXT
|
||||
|
||||
GLAD_API_CALL PFNEGLCREATEIMAGEKHRPROC glad_eglCreateImageKHR;
|
||||
#define eglCreateImageKHR glad_eglCreateImageKHR
|
||||
GLAD_API_CALL PFNEGLDESTROYIMAGEKHRPROC glad_eglDestroyImageKHR;
|
||||
@@ -578,4 +586,4 @@ gladLoaderUnloadEGL(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
12
third-party/glad/src/egl.c
vendored
12
third-party/glad/src/egl.c
vendored
@@ -75,6 +75,8 @@ PFNEGLWAITNATIVEPROC glad_eglWaitNative = NULL;
|
||||
PFNEGLWAITSYNCPROC glad_eglWaitSync = NULL;
|
||||
PFNEGLCREATEIMAGEKHRPROC glad_eglCreateImageKHR = NULL;
|
||||
PFNEGLDESTROYIMAGEKHRPROC glad_eglDestroyImageKHR = NULL;
|
||||
PFNEGLQUERYDMABUFFORMATSEXTPROC glad_eglQueryDmaBufFormatsEXT = NULL;
|
||||
PFNEGLQUERYDMABUFMODIFIERSEXTPROC glad_eglQueryDmaBufModifiersEXT = NULL;
|
||||
|
||||
|
||||
static void glad_egl_load_EGL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
|
||||
@@ -138,7 +140,10 @@ static void glad_egl_load_EGL_VERSION_1_5( GLADuserptrloadfunc load, void* userp
|
||||
glad_eglGetSyncAttrib = (PFNEGLGETSYNCATTRIBPROC) load(userptr, "eglGetSyncAttrib");
|
||||
glad_eglWaitSync = (PFNEGLWAITSYNCPROC) load(userptr, "eglWaitSync");
|
||||
}
|
||||
|
||||
static void glad_egl_load_EGL_EXT_image_dma_buf_import_modifiers( GLADuserptrloadfunc load, void* userptr) {
|
||||
glad_eglQueryDmaBufFormatsEXT = (PFNEGLQUERYDMABUFFORMATSEXTPROC) load(userptr, "eglQueryDmaBufFormatsEXT");
|
||||
glad_eglQueryDmaBufModifiersEXT = (PFNEGLQUERYDMABUFMODIFIERSEXTPROC) load(userptr, "eglQueryDmaBufModifiersEXT");
|
||||
}
|
||||
|
||||
|
||||
static int glad_egl_get_extensions(EGLDisplay display, const char **extensions) {
|
||||
@@ -236,6 +241,7 @@ int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void* userp
|
||||
glad_egl_load_EGL_VERSION_1_2(load, userptr);
|
||||
glad_egl_load_EGL_VERSION_1_4(load, userptr);
|
||||
glad_egl_load_EGL_VERSION_1_5(load, userptr);
|
||||
glad_egl_load_EGL_EXT_image_dma_buf_import_modifiers(load, userptr);
|
||||
|
||||
if (!glad_egl_find_extensions_egl(display)) return 0;
|
||||
|
||||
@@ -246,7 +252,7 @@ int gladLoadEGL(EGLDisplay display, GLADloadfunc load) {
|
||||
return gladLoadEGLUserPtr(display, glad_egl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef GLAD_EGL
|
||||
|
||||
@@ -394,4 +400,4 @@ void gladLoaderUnloadEGL() {
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user