Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .github/workflows/build-appimage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

This file was deleted.

8 changes: 6 additions & 2 deletions app/gui/NavigableToolButton.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 7 additions & 1 deletion app/gui/PcView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 11 additions & 1 deletion app/streaming/video/ffmpeg-renderers/cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion app/streaming/video/ffmpeg-renderers/cuda.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
36 changes: 36 additions & 0 deletions app/streaming/video/ffmpeg-renderers/plvk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion setup-deps.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion setup-deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

ORGANIZATION = "moonlight-stream"
PREBUILT_REPO = "moonlight-qt-deps"
TAG = "v19"
TAG = "v20"

def get_platform_config():
system = platform.system()
Expand Down
Loading