Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL: support HiDPI on wayland #17651

Merged
merged 2 commits into from
Jul 2, 2023
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
2 changes: 1 addition & 1 deletion Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ bool UpdateScreenScale(int width, int height) {
float g_logical_dpi = System_GetPropertyFloat(SYSPROP_DISPLAY_LOGICAL_DPI);
g_display.dpi_scale_x = g_logical_dpi / g_display.dpi;
g_display.dpi_scale_y = g_logical_dpi / g_display.dpi;
#elif PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
#elif (PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)) || PPSSPP_PLATFORM(LINUX)
g_display.dpi = System_GetPropertyFloat(SYSPROP_DISPLAY_DPI);
g_display.dpi_scale_x = 96.0f / g_display.dpi;
g_display.dpi_scale_y = 96.0f / g_display.dpi;
Expand Down
82 changes: 61 additions & 21 deletions SDL/SDLMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ SDLJoystick *joystick = NULL;
#include "SDLGLGraphicsContext.h"
#include "SDLVulkanGraphicsContext.h"

#if PPSSPP_PLATFORM(MAC)
#include "SDL2/SDL_vulkan.h"
#else
#include "SDL_vulkan.h"
#endif

#if PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS)
#include "UI/DarwinFileSystemServices.h"
#endif
Expand All @@ -85,6 +91,8 @@ static bool g_RestartRequested = false;

static int g_DesktopWidth = 0;
static int g_DesktopHeight = 0;
static float g_DesktopDPI = 1.0f;
static float g_ForcedDPI = 0.0f; // if this is 0.0f, use g_DesktopDPI
static float g_RefreshRate = 60.f;
static int g_sampleRate = 44100;

Expand Down Expand Up @@ -173,6 +181,20 @@ static void StopSDLAudioDevice() {
}
}

static void UpdateScreenDPI(SDL_Window *window) {
int drawable_width, window_width;
SDL_GetWindowSize(window, &window_width, NULL);

if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL)
SDL_GL_GetDrawableSize(window, &drawable_width, NULL);
else if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN)
SDL_Vulkan_GetDrawableSize(window, &drawable_width, NULL);

// Round up a little otherwise there would be a gap sometimes
// in fractional scaling
g_DesktopDPI = ((float) drawable_width + 1.0f) / window_width;
}

// Simple implementations of System functions


Expand Down Expand Up @@ -493,6 +515,8 @@ float System_GetPropertyFloat(SystemProperty prop) {
switch (prop) {
case SYSPROP_DISPLAY_REFRESH_RATE:
return g_RefreshRate;
case SYSPROP_DISPLAY_DPI:
return (g_ForcedDPI == 0.0f ? g_DesktopDPI : g_ForcedDPI) * 96.0;
case SYSPROP_DISPLAY_SAFE_INSET_LEFT:
case SYSPROP_DISPLAY_SAFE_INSET_RIGHT:
case SYSPROP_DISPLAY_SAFE_INSET_TOP:
Expand Down Expand Up @@ -684,7 +708,7 @@ int main(int argc, char *argv[]) {
int set_yres = -1;
bool portrait = false;
bool set_ipad = false;
float set_dpi = 1.0f;
float set_dpi = 0.0f;
float set_scale = 1.0f;

// Produce a new set of arguments with the ones we skip.
Expand Down Expand Up @@ -776,7 +800,7 @@ int main(int argc, char *argv[]) {
#elif defined(USING_FBDEV) || PPSSPP_PLATFORM(SWITCH)
mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;
#else
mode |= SDL_WINDOW_RESIZABLE;
mode |= SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
#endif

if (mode & SDL_WINDOW_FULLSCREEN_DESKTOP) {
Expand All @@ -795,8 +819,6 @@ int main(int argc, char *argv[]) {
g_Config.bFullScreen = false;
}

set_dpi = 1.0f / set_dpi;

if (set_ipad) {
g_display.pixel_xres = 1024;
g_display.pixel_yres = 768;
Expand All @@ -811,9 +833,8 @@ int main(int argc, char *argv[]) {
if (set_yres > 0) {
g_display.pixel_yres = set_yres;
}
float dpi_scale = 1.0f;
if (set_dpi > 0) {
dpi_scale = set_dpi;
g_ForcedDPI = set_dpi;
}

// Mac / Linux
Expand Down Expand Up @@ -864,18 +885,6 @@ int main(int argc, char *argv[]) {
if (g_Config.iWindowHeight > 0)
h = g_Config.iWindowHeight;
}
g_display.pixel_xres = w;
g_display.pixel_yres = h;
g_display.dp_xres = (float)g_display.pixel_xres * dpi_scale;
g_display.dp_yres = (float)g_display.pixel_yres * dpi_scale;

g_display.pixel_in_dps_x = (float)g_display.pixel_xres / g_display.dp_xres;
g_display.pixel_in_dps_y = (float)g_display.pixel_yres / g_display.dp_yres;
g_display.dpi_scale_x = g_display.dp_xres / (float)g_display.pixel_xres;
g_display.dpi_scale_y = g_display.dp_yres / (float)g_display.pixel_yres;
g_display.dpi_scale_real_x = g_display.dpi_scale_x;
g_display.dpi_scale_real_y = g_display.dpi_scale_y;
// g_display.Print();

GraphicsContext *graphicsContext = nullptr;
SDL_Window *window = nullptr;
Expand Down Expand Up @@ -904,6 +913,22 @@ int main(int argc, char *argv[]) {
#endif
}

UpdateScreenDPI(window);

float dpi_scale = 1.0f / (g_ForcedDPI == 0.0f ? g_DesktopDPI : g_ForcedDPI);

g_display.pixel_xres = w;
g_display.pixel_yres = h;
g_display.dp_xres = (float)g_display.pixel_xres * dpi_scale;
g_display.dp_yres = (float)g_display.pixel_yres * dpi_scale;

g_display.pixel_in_dps_x = (float)g_display.pixel_xres / g_display.dp_xres;
g_display.pixel_in_dps_y = (float)g_display.pixel_yres / g_display.dp_yres;
g_display.dpi_scale_x = g_display.dp_xres / (float)g_display.pixel_xres;
g_display.dpi_scale_y = g_display.dp_yres / (float)g_display.pixel_yres;
g_display.dpi_scale_real_x = g_display.dpi_scale_x;
g_display.dpi_scale_real_y = g_display.dpi_scale_y;

bool useEmuThread = g_Config.iGPUBackend == (int)GPUBackend::OPENGL;

SDL_SetWindowTitle(window, (app_name_nice + " " + PPSSPP_GIT_VERSION).c_str());
Expand Down Expand Up @@ -1003,8 +1028,14 @@ int main(int argc, char *argv[]) {
}
SDL_Event event, touchEvent;
while (SDL_PollEvent(&event)) {
float mx = event.motion.x * g_display.dpi_scale_x;
float my = event.motion.y * g_display.dpi_scale_y;
// We have to juggle around 3 kinds of "DPI spaces" if a logical DPI is
// provided (through --dpi, it is equal to system DPI if unspecified):
// - SDL gives us motion events in "system DPI" points
// - UpdateScreenScale expects pixels, so in a way "96 DPI" points
// - The UI code expects motion events in "logical DPI" points
float logical_dpi = 1.0f / (g_ForcedDPI == 0.0f ? g_DesktopDPI : g_ForcedDPI);
float mx = event.motion.x * g_DesktopDPI * logical_dpi;
float my = event.motion.y * g_DesktopDPI * logical_dpi;

switch (event.type) {
case SDL_QUIT:
Expand All @@ -1019,19 +1050,28 @@ int main(int argc, char *argv[]) {
int new_width = event.window.data1;
int new_height = event.window.data2;

// The size given by SDL is in point-units, convert these to
// pixels before passing to UpdateScreenScale()
int new_width_px = new_width * g_DesktopDPI;
int new_height_px = new_height * g_DesktopDPI;

windowHidden = false;
Core_NotifyWindowHidden(windowHidden);

Uint32 window_flags = SDL_GetWindowFlags(window);
bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN);

// This one calls NativeResized if the size changed.
UpdateScreenScale(new_width, new_height);
UpdateScreenScale(new_width_px, new_height_px);

// Set variable here in case fullscreen was toggled by hotkey
if (g_Config.UseFullScreen() != fullscreen) {
g_Config.bFullScreen = fullscreen;
g_Config.iForceFullScreen = -1;
} else {
// It is possible for the monitor to change DPI, so recalculate
// DPI on each resize event.
UpdateScreenDPI(window);
}

if (!g_Config.bFullScreen) {
Expand Down