Skip to content

Commit

Permalink
Fix blurry window on native Wayland
Browse files Browse the repository at this point in the history
  • Loading branch information
Maia-Everett committed Apr 22, 2024
1 parent 0926da4 commit e9a4905
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 3 deletions.
14 changes: 14 additions & 0 deletions src/XIVLauncher.Core/DesktopEnvironment/SdlHelpers.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;

using Serilog;

using Veldrid.Sdl2;

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

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SDL_GL_GetDrawableSize_t(SDL_Window SDL2Window, int* w, int* h);
private static SDL_GL_GetDrawableSize_t s_getDrawableSize = Sdl2Native.LoadFunction<SDL_GL_GetDrawableSize_t>("SDL_GL_GetDrawableSize");
private static void SDL_GL_GetDrawableSize(SDL_Window Sdl2Window, int* w, int* h) => s_getDrawableSize(Sdl2Window, w, h);

private static unsafe string GetString(byte* stringStart)
{
int characters = 0;
Expand Down Expand Up @@ -51,4 +58,11 @@ public static Vector2 GetDisplayDpiScale()
Log.Verbose("SDL reports {0}x{1} DPI", hdpi, vdpi);
return new Vector2(hdpi / 96, vdpi / 96);
}

public static Vector2 GetWindowScale(Sdl2Window window)
{
int width, height;
SDL_GL_GetDrawableSize(window.SdlWindowHandle, &width, &height);
return new Vector2((float)width / window.Width, (float)height / window.Height);
}
}
88 changes: 88 additions & 0 deletions src/XIVLauncher.Core/DesktopEnvironment/XLVeldridStartup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Veldrid;
using Veldrid.Sdl2;
using Veldrid.StartupUtilities;

namespace XIVLauncher.Core.DesktopEnvironment;

// Patched piece of VeldridStartup to pass SDL_WindowFlags.AllowHighDpi to SDL_CreateWindow
public static class XLVeldridStartup
{
public static void CreateWindowAndGraphicsDevice(
WindowCreateInfo windowCI,
out Sdl2Window window,
out GraphicsDevice gd)
=> CreateWindowAndGraphicsDevice(
windowCI,
new GraphicsDeviceOptions(),
VeldridStartup.GetPlatformDefaultBackend(),
out window,
out gd);

public static void CreateWindowAndGraphicsDevice(
WindowCreateInfo windowCI,
GraphicsDeviceOptions deviceOptions,
out Sdl2Window window,
out GraphicsDevice gd)
=> CreateWindowAndGraphicsDevice(windowCI, deviceOptions, VeldridStartup.GetPlatformDefaultBackend(), out window, out gd);

public static void CreateWindowAndGraphicsDevice(
WindowCreateInfo windowCI,
GraphicsDeviceOptions deviceOptions,
GraphicsBackend preferredBackend,
out Sdl2Window window,
out GraphicsDevice gd)
{
Sdl2Native.SDL_Init(SDLInitFlags.Video);
if (preferredBackend == GraphicsBackend.OpenGL || preferredBackend == GraphicsBackend.OpenGLES)
{
VeldridStartup.SetSDLGLContextAttributes(deviceOptions, preferredBackend);
}

window = CreateWindow(ref windowCI);
gd = VeldridStartup.CreateGraphicsDevice(window, deviceOptions, preferredBackend);
}


public static Sdl2Window CreateWindow(WindowCreateInfo windowCI) => CreateWindow(ref windowCI);

public static Sdl2Window CreateWindow(ref WindowCreateInfo windowCI)
{
SDL_WindowFlags flags = SDL_WindowFlags.OpenGL | SDL_WindowFlags.Resizable | SDL_WindowFlags.AllowHighDpi
| GetWindowFlags(windowCI.WindowInitialState);
if (windowCI.WindowInitialState != WindowState.Hidden)
{
flags |= SDL_WindowFlags.Shown;
}
Sdl2Window window = new Sdl2Window(
windowCI.WindowTitle,
windowCI.X,
windowCI.Y,
windowCI.WindowWidth,
windowCI.WindowHeight,
flags,
false);

return window;
}

private static SDL_WindowFlags GetWindowFlags(WindowState state)
{
switch (state)
{
case WindowState.Normal:
return 0;
case WindowState.FullScreen:
return SDL_WindowFlags.Fullscreen;
case WindowState.Maximized:
return SDL_WindowFlags.Maximized;
case WindowState.Minimized:
return SDL_WindowFlags.Minimized;
case WindowState.BorderlessFullScreen:
return SDL_WindowFlags.FullScreenDesktop;
case WindowState.Hidden:
return SDL_WindowFlags.Hidden;
default:
throw new VeldridException("Invalid WindowState: " + state);
}
}
}
12 changes: 9 additions & 3 deletions src/XIVLauncher.Core/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,22 @@ private static void Main(string[] args)
var windowWidth = (int)ImGuiHelpers.GetScaled(1280);
var windowHeight = (int)ImGuiHelpers.GetScaled(800);

VeldridStartup.CreateWindowAndGraphicsDevice(
XLVeldridStartup.CreateWindowAndGraphicsDevice(
new WindowCreateInfo(50, 50, windowWidth, windowHeight, WindowState.Normal, $"XIVLauncher {version}"),
new GraphicsDeviceOptions(false, null, true, ResourceBindingModel.Improved, true, true),
out window,
out gd);

var windowScale = SdlHelpers.GetWindowScale(window).Y;
ImGuiHelpers.GlobalScale *= windowScale;

window.Resized += () =>
{
gd.MainSwapchain.Resize((uint)window.Width, (uint)window.Height);
bindings.WindowResized(window.Width, window.Height);
var scaledWidth = (int)Math.Round(window.Width * windowScale);
var scaledHeight = (int)Math.Round(window.Height * windowScale);
gd.MainSwapchain.Resize((uint)scaledWidth, (uint)scaledHeight);
bindings.WindowResized(scaledWidth, scaledHeight);
Invalidate();
};
cl = gd.ResourceFactory.CreateCommandList();
Expand Down

0 comments on commit e9a4905

Please sign in to comment.