Skip to content

Commit e9a4905

Browse files
committed
Fix blurry window on native Wayland
1 parent 0926da4 commit e9a4905

File tree

3 files changed

+111
-3
lines changed

3 files changed

+111
-3
lines changed

src/XIVLauncher.Core/DesktopEnvironment/SdlHelpers.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System.Numerics;
22
using System.Runtime.InteropServices;
33
using System.Text;
4+
45
using Serilog;
6+
57
using Veldrid.Sdl2;
68

79
namespace XIVLauncher.Core.DesktopEnvironment;
@@ -21,6 +23,11 @@ internal static unsafe partial class SdlHelpers
2123
private static int SDL_GetDisplayDPI(int displayIndex, float* ddpi, float* hdpi, float* vdpi)
2224
=> s_sdl_getDisplayDPI(displayIndex, ddpi, hdpi, vdpi);
2325

26+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
27+
private delegate void SDL_GL_GetDrawableSize_t(SDL_Window SDL2Window, int* w, int* h);
28+
private static SDL_GL_GetDrawableSize_t s_getDrawableSize = Sdl2Native.LoadFunction<SDL_GL_GetDrawableSize_t>("SDL_GL_GetDrawableSize");
29+
private static void SDL_GL_GetDrawableSize(SDL_Window Sdl2Window, int* w, int* h) => s_getDrawableSize(Sdl2Window, w, h);
30+
2431
private static unsafe string GetString(byte* stringStart)
2532
{
2633
int characters = 0;
@@ -51,4 +58,11 @@ public static Vector2 GetDisplayDpiScale()
5158
Log.Verbose("SDL reports {0}x{1} DPI", hdpi, vdpi);
5259
return new Vector2(hdpi / 96, vdpi / 96);
5360
}
61+
62+
public static Vector2 GetWindowScale(Sdl2Window window)
63+
{
64+
int width, height;
65+
SDL_GL_GetDrawableSize(window.SdlWindowHandle, &width, &height);
66+
return new Vector2((float)width / window.Width, (float)height / window.Height);
67+
}
5468
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using Veldrid;
2+
using Veldrid.Sdl2;
3+
using Veldrid.StartupUtilities;
4+
5+
namespace XIVLauncher.Core.DesktopEnvironment;
6+
7+
// Patched piece of VeldridStartup to pass SDL_WindowFlags.AllowHighDpi to SDL_CreateWindow
8+
public static class XLVeldridStartup
9+
{
10+
public static void CreateWindowAndGraphicsDevice(
11+
WindowCreateInfo windowCI,
12+
out Sdl2Window window,
13+
out GraphicsDevice gd)
14+
=> CreateWindowAndGraphicsDevice(
15+
windowCI,
16+
new GraphicsDeviceOptions(),
17+
VeldridStartup.GetPlatformDefaultBackend(),
18+
out window,
19+
out gd);
20+
21+
public static void CreateWindowAndGraphicsDevice(
22+
WindowCreateInfo windowCI,
23+
GraphicsDeviceOptions deviceOptions,
24+
out Sdl2Window window,
25+
out GraphicsDevice gd)
26+
=> CreateWindowAndGraphicsDevice(windowCI, deviceOptions, VeldridStartup.GetPlatformDefaultBackend(), out window, out gd);
27+
28+
public static void CreateWindowAndGraphicsDevice(
29+
WindowCreateInfo windowCI,
30+
GraphicsDeviceOptions deviceOptions,
31+
GraphicsBackend preferredBackend,
32+
out Sdl2Window window,
33+
out GraphicsDevice gd)
34+
{
35+
Sdl2Native.SDL_Init(SDLInitFlags.Video);
36+
if (preferredBackend == GraphicsBackend.OpenGL || preferredBackend == GraphicsBackend.OpenGLES)
37+
{
38+
VeldridStartup.SetSDLGLContextAttributes(deviceOptions, preferredBackend);
39+
}
40+
41+
window = CreateWindow(ref windowCI);
42+
gd = VeldridStartup.CreateGraphicsDevice(window, deviceOptions, preferredBackend);
43+
}
44+
45+
46+
public static Sdl2Window CreateWindow(WindowCreateInfo windowCI) => CreateWindow(ref windowCI);
47+
48+
public static Sdl2Window CreateWindow(ref WindowCreateInfo windowCI)
49+
{
50+
SDL_WindowFlags flags = SDL_WindowFlags.OpenGL | SDL_WindowFlags.Resizable | SDL_WindowFlags.AllowHighDpi
51+
| GetWindowFlags(windowCI.WindowInitialState);
52+
if (windowCI.WindowInitialState != WindowState.Hidden)
53+
{
54+
flags |= SDL_WindowFlags.Shown;
55+
}
56+
Sdl2Window window = new Sdl2Window(
57+
windowCI.WindowTitle,
58+
windowCI.X,
59+
windowCI.Y,
60+
windowCI.WindowWidth,
61+
windowCI.WindowHeight,
62+
flags,
63+
false);
64+
65+
return window;
66+
}
67+
68+
private static SDL_WindowFlags GetWindowFlags(WindowState state)
69+
{
70+
switch (state)
71+
{
72+
case WindowState.Normal:
73+
return 0;
74+
case WindowState.FullScreen:
75+
return SDL_WindowFlags.Fullscreen;
76+
case WindowState.Maximized:
77+
return SDL_WindowFlags.Maximized;
78+
case WindowState.Minimized:
79+
return SDL_WindowFlags.Minimized;
80+
case WindowState.BorderlessFullScreen:
81+
return SDL_WindowFlags.FullScreenDesktop;
82+
case WindowState.Hidden:
83+
return SDL_WindowFlags.Hidden;
84+
default:
85+
throw new VeldridException("Invalid WindowState: " + state);
86+
}
87+
}
88+
}

src/XIVLauncher.Core/Program.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,16 +265,22 @@ private static void Main(string[] args)
265265
var windowWidth = (int)ImGuiHelpers.GetScaled(1280);
266266
var windowHeight = (int)ImGuiHelpers.GetScaled(800);
267267

268-
VeldridStartup.CreateWindowAndGraphicsDevice(
268+
XLVeldridStartup.CreateWindowAndGraphicsDevice(
269269
new WindowCreateInfo(50, 50, windowWidth, windowHeight, WindowState.Normal, $"XIVLauncher {version}"),
270270
new GraphicsDeviceOptions(false, null, true, ResourceBindingModel.Improved, true, true),
271271
out window,
272272
out gd);
273273

274+
var windowScale = SdlHelpers.GetWindowScale(window).Y;
275+
ImGuiHelpers.GlobalScale *= windowScale;
276+
274277
window.Resized += () =>
275278
{
276-
gd.MainSwapchain.Resize((uint)window.Width, (uint)window.Height);
277-
bindings.WindowResized(window.Width, window.Height);
279+
var scaledWidth = (int)Math.Round(window.Width * windowScale);
280+
var scaledHeight = (int)Math.Round(window.Height * windowScale);
281+
282+
gd.MainSwapchain.Resize((uint)scaledWidth, (uint)scaledHeight);
283+
bindings.WindowResized(scaledWidth, scaledHeight);
278284
Invalidate();
279285
};
280286
cl = gd.ResourceFactory.CreateCommandList();

0 commit comments

Comments
 (0)