diff --git a/.github/workflows/build-appimage.yml b/.github/workflows/build-appimage.yml index 4285c771c3..300ac584ce 100644 --- a/.github/workflows/build-appimage.yml +++ b/.github/workflows/build-appimage.yml @@ -42,7 +42,7 @@ jobs: uses: actions/checkout@v5 with: repository: libsdl-org/SDL - ref: release-3.4.18 + ref: release-3.4.20 path: deps/SDL - name: Build SDL3 @@ -56,7 +56,7 @@ jobs: uses: actions/checkout@v5 with: repository: libsdl-org/sdl2-compat - ref: release-2.32.74 + ref: bebc6eb01397497130ca58a1cb48c8bd141422f5 path: deps/sdl2-compat - name: Build sdl2-compat @@ -101,14 +101,13 @@ jobs: uses: actions/checkout@v5 with: repository: haasn/libplacebo - ref: 92b5ac6db79f4d680eb656692f7bf51e9606f42a + ref: v7.387.0 path: deps/libplacebo submodules: 'recursive' - name: Build libplacebo working-directory: deps/libplacebo run: | - git apply ../../app/deploy/linux/appimage/*.patch meson setup build -Dvulkan=enabled -Dopengl=disabled -Ddemos=false ninja -C build sudo ninja install -C build diff --git a/app/deploy/linux/appimage/libplacebo-disable-internally-synchronized-queues.patch b/app/deploy/linux/appimage/libplacebo-disable-internally-synchronized-queues.patch deleted file mode 100644 index 0aaa10ec45..0000000000 --- a/app/deploy/linux/appimage/libplacebo-disable-internally-synchronized-queues.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/vulkan/context.c b/src/vulkan/context.c -index bc9084ad..52290154 100644 ---- a/src/vulkan/context.c -+++ b/src/vulkan/context.c -@@ -265,7 +265,7 @@ static_assert(PL_ARRAY_SIZE(pl_vulkan_recommended_extensions) + 1 == - #ifdef VK_KHR_internally_synchronized_queues - static const VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR synchronized_queues = { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR, -- .internallySynchronizedQueues = true, -+ .internallySynchronizedQueues = false, - }; - #endif - diff --git a/app/gui/NavigableToolButton.qml b/app/gui/NavigableToolButton.qml index 9839196cbe..97c0ea907e 100644 --- a/app/gui/NavigableToolButton.qml +++ b/app/gui/NavigableToolButton.qml @@ -8,8 +8,12 @@ ToolButton { activeFocusOnTab: true icon.source: iconSource - icon.width: background.width - icon.height: background.height + // Size the icon from the button's height rather than its background. + // Material's background spans the full button width when the content + // isn't square, so binding the icon to it feeds the button's width back + // into its own implicit width and the toolbar layout grows without bound. + icon.width: height / 2 + icon.height: height / 2 // This determines the size of the Material highlight. We increase it // from the default because we use larger than normal icons for TV readability. diff --git a/app/gui/PcView.qml b/app/gui/PcView.qml index fed98a22a3..cba64f7e74 100644 --- a/app/gui/PcView.qml +++ b/app/gui/PcView.qml @@ -154,12 +154,18 @@ CenteredGridView { width: parent.width anchors.top: pcIcon.bottom anchors.bottom: parent.bottom - font.pointSize: 36 + font.pointSize: 30 horizontalAlignment: Text.AlignHCenter wrapMode: Text.Wrap elide: Text.ElideRight } + // Display a tooltip with the full name if it's truncated + ToolTip.text: model.name + ToolTip.delay: 1000 + ToolTip.timeout: 5000 + ToolTip.visible: (hovered || highlighted) && pcNameText.truncated + Loader { id: pcContextMenuLoader asynchronous: true diff --git a/app/streaming/video/ffmpeg-renderers/cuda.cpp b/app/streaming/video/ffmpeg-renderers/cuda.cpp index b238249367..60b794f827 100644 --- a/app/streaming/video/ffmpeg-renderers/cuda.cpp +++ b/app/streaming/video/ffmpeg-renderers/cuda.cpp @@ -16,10 +16,15 @@ CUDARenderer::~CUDARenderer() } } -bool CUDARenderer::initialize(PDECODER_PARAMETERS) +bool CUDARenderer::initialize(PDECODER_PARAMETERS params) { int err; + // This renderer only supports NV12 output + if (params->videoFormat & (VIDEO_FORMAT_MASK_10BIT | VIDEO_FORMAT_MASK_YUV444)) { + return false; + } + err = av_hwdevice_ctx_create(&m_HwContext, AV_HWDEVICE_TYPE_CUDA, nullptr, nullptr, 0); if (err != 0) { m_InitFailureReason = InitFailureReason::NoSoftwareSupport; @@ -106,6 +111,11 @@ bool CUDAGLInteropHelper::registerBoundTextures() // Get the ID of this plane's texture glActiveTexture(GL_TEXTURE0 + i); glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex); + if (tex == 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No GL texture bound to slot %d", i); + err = 211; // CUDA_ERROR_NOT_MAPPED + goto Exit; + } // Register it with CUDA err = m_Funcs->cuGraphicsGLRegisterImage(&m_Resources[i], tex, GL_TEXTURE_2D, CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD); diff --git a/app/streaming/video/ffmpeg-renderers/cuda.h b/app/streaming/video/ffmpeg-renderers/cuda.h index d58a56c724..60e3e5ab73 100644 --- a/app/streaming/video/ffmpeg-renderers/cuda.h +++ b/app/streaming/video/ffmpeg-renderers/cuda.h @@ -12,7 +12,7 @@ class CUDARenderer : public IFFmpegRenderer { public: CUDARenderer(); virtual ~CUDARenderer() override; - virtual bool initialize(PDECODER_PARAMETERS) override; + virtual bool initialize(PDECODER_PARAMETERS params) override; virtual bool prepareDecoderContext(AVCodecContext* context, AVDictionary** options) override; virtual void renderFrame(AVFrame* frame) override; virtual bool isDirectRenderingSupported() override; diff --git a/app/streaming/video/ffmpeg-renderers/plvk.cpp b/app/streaming/video/ffmpeg-renderers/plvk.cpp index 07ccce8fff..48081e6f38 100644 --- a/app/streaming/video/ffmpeg-renderers/plvk.cpp +++ b/app/streaming/video/ffmpeg-renderers/plvk.cpp @@ -2,6 +2,7 @@ #include "streaming/session.h" #include "streaming/streamutils.h" +#include "utils.h" // Implementation in plvk_c.c #define PL_LIBAV_IMPLEMENTATION 0 @@ -375,6 +376,41 @@ bool PlVkRenderer::tryInitializeDevice(VkPhysicalDevice device, VkPhysicalDevice vkParams.extra_queues = VK_QUEUE_FLAG_BITS_MAX_ENUM; } +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(60, 31, 101) && defined(VK_KHR_internally_synchronized_queues) + // libplacebo needs explicit opt-in to use internally synchronized queues, since + // it requires cooperation with the app (ex: using vkGetDeviceQueue2). We know + // FFmpeg 9.0+ always wants internally synchronized queues if available, so we + // will turn it on when supported by the physical device. + if (isExtensionSupportedByPhysicalDevice(device, "VK_KHR_internally_synchronized_queues")) { + bool internallySynchronizedQueues; + if (!Utils::getEnvironmentVariableOverride("PLVK_INT_SYNC_QUEUES", &internallySynchronizedQueues)) { +#if LIBAVUTIL_VERSION_MAJOR < 62 + // The Gamescope WSI layer currently breaks apps using internally synchronized queues + // (failing to use vkGetDeviceQueue2), so we disable this feature when the Gamescope + // WSI layer is enabled. See gamescope#2261 for details. + internallySynchronizedQueues = (qEnvironmentVariableIntValue("ENABLE_GAMESCOPE_WSI") == 0 || + qEnvironmentVariableIntValue("DISABLE_GAMESCOPE_WSI") == 1); +#else + // We have no choice but to enable it since the queue locking callbacks are gone + internallySynchronizedQueues = true; +#endif + } + + static VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR featInternalSyncQueues = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR, + nullptr, + internallySynchronizedQueues, + }; + + static const VkPhysicalDeviceFeatures2 features = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + (void*)&featInternalSyncQueues, + }; + + vkParams.features = &features; + } +#endif + { // Don't let Qt take DRM master from us during pl_vulkan_create() DrmMasterLocker locker; diff --git a/setup-deps.ps1 b/setup-deps.ps1 index bdb2bdbca7..0c6aedbc9c 100644 --- a/setup-deps.ps1 +++ b/setup-deps.ps1 @@ -4,7 +4,7 @@ $Organization = "moonlight-stream" $PrebuiltRepo = "moonlight-qt-deps" $TargetDir = Join-Path $PSScriptRoot "libs\windows" $Assets = @("windows-x64.zip", "windows-ARM64.zip") -$Tag = "v19" +$Tag = "v20" if (Test-Path $TargetDir) { Write-Host "Cleaning target directory..." -ForegroundColor Cyan diff --git a/setup-deps.py b/setup-deps.py index b713ee2bcd..c19547717d 100644 --- a/setup-deps.py +++ b/setup-deps.py @@ -7,7 +7,7 @@ ORGANIZATION = "moonlight-stream" PREBUILT_REPO = "moonlight-qt-deps" -TAG = "v19" +TAG = "v20" def get_platform_config(): system = platform.system()