From 6a27188023832f666c81ec340738a5f73e01e50d Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 25 Jan 2023 03:36:35 -0800
Subject: [PATCH] SDL_DisplayMode now represents physical pixels and has added
a display scaling factor
Work in progress on https://github.com/libsdl-org/SDL/issues/7134
---
include/SDL3/SDL_video.h | 10 +++--
src/test/SDL_test_common.c | 24 +++++------
src/video/SDL_video.c | 48 +++++++++++++++++++---
src/video/android/SDL_androidvideo.c | 2 +
src/video/cocoa/SDL_cocoamodes.m | 16 +++++---
src/video/dummy/SDL_nullvideo.c | 2 -
src/video/emscripten/SDL_emscriptenvideo.c | 3 +-
src/video/haiku/SDL_bmodes.cc | 1 +
src/video/kmsdrm/SDL_kmsdrmvideo.c | 1 +
src/video/n3ds/SDL_n3dsvideo.c | 1 -
src/video/ngage/SDL_ngagevideo.cpp | 3 +-
src/video/offscreen/SDL_offscreenvideo.c | 4 +-
src/video/ps2/SDL_ps2video.c | 3 --
src/video/psp/SDL_pspvideo.c | 5 +--
src/video/raspberry/SDL_rpivideo.c | 3 +-
src/video/riscos/SDL_riscosmodes.c | 1 +
src/video/uikit/SDL_uikitmodes.m | 36 ++++++----------
src/video/vita/SDL_vitavideo.c | 4 +-
src/video/wayland/SDL_waylandvideo.c | 1 +
src/video/windows/SDL_windowsmodes.c | 29 ++++++-------
src/video/x11/SDL_x11modes.c | 3 +-
21 files changed, 109 insertions(+), 91 deletions(-)
diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h
index a2318246d492..d8d5c52c9d51 100644
--- a/include/SDL3/SDL_video.h
+++ b/include/SDL3/SDL_video.h
@@ -56,8 +56,9 @@ typedef Uint32 SDL_WindowID;
typedef struct
{
Uint32 format; /**< pixel format */
- int w; /**< width, in screen coordinates */
- int h; /**< height, in screen coordinates */
+ int w; /**< width in pixels */
+ int h; /**< height in pixels */
+ float display_scale; /**< scale converting screen coordinates to pixels (e.g. a 3840x2160 mode with 1.5 scale would have a screen size of 2560x1440) */
float refresh_rate; /**< refresh rate (or zero for unspecified) */
void *driverdata; /**< driver-specific data, initialize to 0 */
} SDL_DisplayMode;
@@ -322,7 +323,7 @@ extern DECLSPEC int SDLCALL SDL_GetNumVideoDisplays(void);
extern DECLSPEC const char *SDLCALL SDL_GetDisplayName(int displayIndex);
/**
- * Get the desktop area represented by a display.
+ * Get the desktop area represented by a display, in screen coordinates.
*
* The primary display (`displayIndex` zero) is always located at 0,0.
*
@@ -338,7 +339,7 @@ extern DECLSPEC const char *SDLCALL SDL_GetDisplayName(int displayIndex);
extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect *rect);
/**
- * Get the usable desktop area represented by a display.
+ * Get the usable desktop area represented by a display, in screen coordinates.
*
* The primary display (`displayIndex` zero) is always located at 0,0.
*
@@ -440,6 +441,7 @@ extern DECLSPEC int SDLCALL SDL_GetNumDisplayModes(int displayIndex);
*
* - width -> largest to smallest
* - height -> largest to smallest
+ * - display_scale -> smallest to largest
* - bits per pixel -> more colors to fewer colors
* - packed pixel layout -> largest to smallest
* - refresh rate -> highest to lowest
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index 2d23c82eb542..6aeb65c9c4b4 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -1124,13 +1124,13 @@ SDLTest_CommonInit(SDLTest_CommonState *state)
SDL_Log("Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y);
SDL_Log("Usable bounds: %dx%d at %d,%d\n", usablebounds.w, usablebounds.h, usablebounds.x, usablebounds.y);
- SDL_Log("DPI: %fx%f\n", hdpi, vdpi);
+ SDL_Log("DPI: %gx%g\n", hdpi, vdpi);
SDL_GetDesktopDisplayMode(i, &mode);
SDL_GetMasksForPixelFormatEnum(mode.format, &bpp, &Rmask, &Gmask,
&Bmask, &Amask);
- SDL_Log(" Current mode: %dx%d@%gHz, %d bits-per-pixel (%s)\n",
- mode.w, mode.h, mode.refresh_rate, bpp,
+ SDL_Log(" Current mode: %dx%d@%gHz, %d%% scale, %d bits-per-pixel (%s)\n",
+ mode.w, mode.h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), bpp,
SDL_GetPixelFormatName(mode.format));
if (Rmask || Gmask || Bmask) {
SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32 "\n", Rmask);
@@ -1151,8 +1151,8 @@ SDLTest_CommonInit(SDLTest_CommonState *state)
SDL_GetDisplayMode(i, j, &mode);
SDL_GetMasksForPixelFormatEnum(mode.format, &bpp, &Rmask,
&Gmask, &Bmask, &Amask);
- SDL_Log(" Mode %d: %dx%d@%gHz, %d bits-per-pixel (%s)\n",
- j, mode.w, mode.h, mode.refresh_rate, bpp,
+ SDL_Log(" Mode %d: %dx%d@%gHz, %d%% scale, %d bits-per-pixel (%s)\n",
+ j, mode.w, mode.h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), bpp,
SDL_GetPixelFormatName(mode.format));
if (Rmask || Gmask || Bmask) {
SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32 "\n",
@@ -2245,8 +2245,8 @@ void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, fl
textY += lineHeight;
if (0 == SDL_GetWindowDisplayMode(window, &mode)) {
- (void)SDL_snprintf(text, sizeof text, "SDL_GetWindowDisplayMode: %dx%d@%gHz (%s)",
- mode.w, mode.h, mode.refresh_rate, SDL_GetPixelFormatName(mode.format));
+ (void)SDL_snprintf(text, sizeof text, "SDL_GetWindowDisplayMode: %dx%d@%gHz %d%% scale, (%s)",
+ mode.w, mode.h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), SDL_GetPixelFormatName(mode.format));
SDLTest_DrawString(renderer, 0.0f, textY, text);
textY += lineHeight;
}
@@ -2275,21 +2275,21 @@ void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, fl
}
if (0 == SDL_GetCurrentDisplayMode(windowDisplayIndex, &mode)) {
- (void)SDL_snprintf(text, sizeof text, "SDL_GetCurrentDisplayMode: %dx%d@%gHz (%s)",
- mode.w, mode.h, mode.refresh_rate, SDL_GetPixelFormatName(mode.format));
+ (void)SDL_snprintf(text, sizeof text, "SDL_GetCurrentDisplayMode: %dx%d@%gHz %d%% scale, (%s)",
+ mode.w, mode.h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), SDL_GetPixelFormatName(mode.format));
SDLTest_DrawString(renderer, 0.0f, textY, text);
textY += lineHeight;
}
if (0 == SDL_GetDesktopDisplayMode(windowDisplayIndex, &mode)) {
- (void)SDL_snprintf(text, sizeof text, "SDL_GetDesktopDisplayMode: %dx%d@%gHz (%s)",
- mode.w, mode.h, mode.refresh_rate, SDL_GetPixelFormatName(mode.format));
+ (void)SDL_snprintf(text, sizeof text, "SDL_GetDesktopDisplayMode: %dx%d@%gHz %d%% scale, (%s)",
+ mode.w, mode.h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), SDL_GetPixelFormatName(mode.format));
SDLTest_DrawString(renderer, 0.0f, textY, text);
textY += lineHeight;
}
if (0 == SDL_GetDisplayPhysicalDPI(windowDisplayIndex, &ddpi, &hdpi, &vdpi)) {
- (void)SDL_snprintf(text, sizeof text, "SDL_GetDisplayPhysicalDPI: ddpi: %f, hdpi: %f, vdpi: %f",
+ (void)SDL_snprintf(text, sizeof text, "SDL_GetDisplayPhysicalDPI: ddpi: %g, hdpi: %g, vdpi: %g",
ddpi, hdpi, vdpi);
SDLTest_DrawString(renderer, 0.0f, textY, text);
textY += lineHeight;
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 3c0c47a37f12..b413d0394ccc 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -382,12 +382,16 @@ static int SDLCALL cmpmodes(const void *A, const void *B)
{
const SDL_DisplayMode *a = (const SDL_DisplayMode *)A;
const SDL_DisplayMode *b = (const SDL_DisplayMode *)B;
+ float a_display_scale = (a->display_scale == 0.0f) ? 1.0f : a->display_scale;
+ float b_display_scale = (b->display_scale == 0.0f) ? 1.0f : b->display_scale;
if (a == b) {
return 0;
} else if (a->w != b->w) {
return b->w - a->w;
} else if (a->h != b->h) {
return b->h - a->h;
+ } else if (a_display_scale != b_display_scale) {
+ return (int)(a_display_scale * 100) - (int)(b_display_scale * 100);
} else if (SDL_BITSPERPIXEL(a->format) != SDL_BITSPERPIXEL(b->format)) {
return SDL_BITSPERPIXEL(b->format) - SDL_BITSPERPIXEL(a->format);
} else if (SDL_PIXELLAYOUT(a->format) != SDL_PIXELLAYOUT(b->format)) {
@@ -588,6 +592,9 @@ int SDL_AddBasicVideoDisplay(const SDL_DisplayMode *desktop_mode)
SDL_zero(display);
if (desktop_mode) {
display.desktop_mode = *desktop_mode;
+ if (display.desktop_mode.display_scale == 0.0f) {
+ display.desktop_mode.display_scale = 1.0f;
+ }
}
display.current_mode = display.desktop_mode;
@@ -617,6 +624,12 @@ int SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send_event)
displays[index].name = SDL_strdup(name);
}
+ if (displays[index].desktop_mode.display_scale == 0.0f) {
+ displays[index].desktop_mode.display_scale = 1.0f;
+ }
+ if (displays[index].current_mode.display_scale == 0.0f) {
+ displays[index].current_mode.display_scale = 1.0f;
+ }
if (send_event) {
SDL_SendDisplayEvent(&_this->displays[index], SDL_EVENT_DISPLAY_CONNECTED, 0);
}
@@ -709,8 +722,8 @@ int SDL_GetDisplayBounds(int displayIndex, SDL_Rect *rect)
SDL_GetDisplayBounds(displayIndex - 1, rect);
rect->x += rect->w;
}
- rect->w = display->current_mode.w;
- rect->h = display->current_mode.h;
+ rect->w = (int)(display->current_mode.w / display->current_mode.display_scale);
+ rect->h = (int)(display->current_mode.h / display->current_mode.display_scale);
return 0;
}
@@ -791,9 +804,7 @@ SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mo
/* Go ahead and add the new mode */
if (nmodes == display->max_display_modes) {
- modes =
- SDL_realloc(modes,
- (display->max_display_modes + 32) * sizeof(*modes));
+ modes = SDL_realloc(modes, (display->max_display_modes + 32) * sizeof(*modes));
if (modes == NULL) {
return SDL_FALSE;
}
@@ -801,6 +812,9 @@ SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mo
display->max_display_modes += 32;
}
modes[nmodes] = *mode;
+ if (modes[nmodes].display_scale == 0.0f) {
+ modes[nmodes].display_scale = 1.0f;
+ }
display->num_display_modes++;
/* Re-sort video modes */
@@ -813,11 +827,17 @@ SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mo
void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
{
SDL_memcpy(&display->current_mode, mode, sizeof(*mode));
+ if (display->current_mode.display_scale == 0.0f) {
+ display->current_mode.display_scale = 1.0f;
+ }
}
void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
{
SDL_memcpy(&display->desktop_mode, mode, sizeof(*mode));
+ if (display->desktop_mode.display_scale == 0.0f) {
+ display->desktop_mode.display_scale = 1.0f;
+ }
}
static int SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay *display)
@@ -902,6 +922,7 @@ static SDL_DisplayMode *SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay *di
SDL_DisplayMode *closest)
{
Uint32 target_format;
+ float target_display_scale;
float target_refresh_rate;
int i;
SDL_DisplayMode *current, *match;
@@ -918,6 +939,13 @@ static SDL_DisplayMode *SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay *di
target_format = display->desktop_mode.format;
}
+ /* Default to 1.0 scale */
+ if (mode->display_scale > 0.0f) {
+ target_display_scale = mode->display_scale;
+ } else {
+ target_display_scale = 1.0f;
+ }
+
/* Default to the desktop refresh rate */
if (mode->refresh_rate > 0.0f) {
target_refresh_rate = mode->refresh_rate;
@@ -962,6 +990,14 @@ static SDL_DisplayMode *SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay *di
/* Sorted highest refresh to lowest */
if (current->refresh_rate >= target_refresh_rate) {
match = current;
+ continue;
+ }
+ }
+ if (current->display_scale != match->display_scale) {
+ /* Sorted lowest display scale to highest */
+ if (current->display_scale <= target_display_scale) {
+ match = current;
+ continue;
}
}
}
@@ -978,6 +1014,8 @@ static SDL_DisplayMode *SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay *di
closest->w = mode->w;
closest->h = mode->h;
}
+ closest->display_scale = mode->display_scale;
+
if (match->refresh_rate > 0.0f) {
closest->refresh_rate = match->refresh_rate;
} else {
diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c
index 9d9d69cd7e81..925f3dd10c64 100644
--- a/src/video/android/SDL_androidvideo.c
+++ b/src/video/android/SDL_androidvideo.c
@@ -177,9 +177,11 @@ int Android_VideoInit(_THIS)
videodata->isPausing = SDL_FALSE;
videodata->pauseAudio = SDL_GetHintBoolean(SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO, SDL_TRUE);
+ SDL_zero(mode);
mode.format = Android_ScreenFormat;
mode.w = Android_DeviceWidth;
mode.h = Android_DeviceHeight;
+ mode.display_scale = 1.0f; /* FIXME */
mode.refresh_rate = Android_ScreenRate;
mode.driverdata = NULL;
diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m
index 1abb4399777a..cc2afdc40bf4 100644
--- a/src/video/cocoa/SDL_cocoamodes.m
+++ b/src/video/cocoa/SDL_cocoamodes.m
@@ -145,6 +145,8 @@ static SDL_bool GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmode
bool usableForGUI = CGDisplayModeIsUsableForDesktopGUI(vidmode);
int width = (int)CGDisplayModeGetWidth(vidmode);
int height = (int)CGDisplayModeGetHeight(vidmode);
+ int pixelW = width;
+ int pixelH = height;
uint32_t ioflags = CGDisplayModeGetIOFlags(vidmode);
float refreshrate = GetDisplayModeRefreshRate(vidmode, link);
Uint32 format = GetDisplayModePixelFormat(vidmode);
@@ -164,17 +166,17 @@ static SDL_bool GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmode
modes = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
CFArrayAppendValue(modes, vidmode);
- /* If a list of possible diplay modes is passed in, use it to filter out
+ /* If a list of possible display modes is passed in, use it to filter out
* modes that have duplicate sizes. We don't just rely on SDL's higher level
* duplicate filtering because this code can choose what properties are
* prefered, and it can add CGDisplayModes to the DisplayModeData's list of
* modes to try (see comment below for why that's necessary).
* CGDisplayModeGetPixelWidth and friends are only available in 10.8+. */
#ifdef MAC_OS_X_VERSION_10_8
- if (modelist != NULL && floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_7) {
- int pixelW = (int)CGDisplayModeGetPixelWidth(vidmode);
- int pixelH = (int)CGDisplayModeGetPixelHeight(vidmode);
+ pixelW = (int)CGDisplayModeGetPixelWidth(vidmode);
+ pixelH = (int)CGDisplayModeGetPixelHeight(vidmode);
+ if (modelist != NULL && floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_7) {
CFIndex modescount = CFArrayGetCount(modelist);
int i;
@@ -254,6 +256,7 @@ static SDL_bool GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmode
}
#endif
+ SDL_zerop(mode);
data = (SDL_DisplayModeData *)SDL_malloc(sizeof(*data));
if (!data) {
CFRelease(modes);
@@ -261,8 +264,9 @@ static SDL_bool GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmode
}
data->modes = modes;
mode->format = format;
- mode->w = width;
- mode->h = height;
+ mode->w = pixelW;
+ mode->h = pixelH;
+ mode->display_scale = (float)pixelW / width;
mode->refresh_rate = refreshrate;
mode->driverdata = data;
return SDL_TRUE;
diff --git a/src/video/dummy/SDL_nullvideo.c b/src/video/dummy/SDL_nullvideo.c
index 6c781b9afe15..1bb6171279eb 100644
--- a/src/video/dummy/SDL_nullvideo.c
+++ b/src/video/dummy/SDL_nullvideo.c
@@ -146,8 +146,6 @@ int DUMMY_VideoInit(_THIS)
mode.format = SDL_PIXELFORMAT_RGB888;
mode.w = 1024;
mode.h = 768;
- mode.refresh_rate = 0.0f;
- mode.driverdata = NULL;
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
return -1;
}
diff --git a/src/video/emscripten/SDL_emscriptenvideo.c b/src/video/emscripten/SDL_emscriptenvideo.c
index 895bedca2e5e..bb22d7e08a87 100644
--- a/src/video/emscripten/SDL_emscriptenvideo.c
+++ b/src/video/emscripten/SDL_emscriptenvideo.c
@@ -127,11 +127,10 @@ int Emscripten_VideoInit(_THIS)
SDL_DisplayMode mode;
/* Use a fake 32-bpp desktop mode */
+ SDL_zero(mode);
mode.format = SDL_PIXELFORMAT_RGB888;
emscripten_get_screen_size(&mode.w, &mode.h);
- mode.refresh_rate = 0.0f;
- mode.driverdata = NULL;
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
return -1;
}
diff --git a/src/video/haiku/SDL_bmodes.cc b/src/video/haiku/SDL_bmodes.cc
index e1ef48a94523..147bae41d706 100644
--- a/src/video/haiku/SDL_bmodes.cc
+++ b/src/video/haiku/SDL_bmodes.cc
@@ -167,6 +167,7 @@ int32 HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace)
static void _BDisplayModeToSdlDisplayMode(display_mode *bmode,
SDL_DisplayMode *mode) {
+ SDL_zerop(mode);
mode->w = bmode->virtual_width;
mode->h = bmode->virtual_height;
mode->refresh_rate = get_refresh_rate(*bmode);
diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c
index e996bcba42a7..1db906aa15fc 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c
@@ -1295,6 +1295,7 @@ void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
modedata->mode_index = i;
}
+ SDL_zero(mode);
mode.w = conn->modes[i].hdisplay;
mode.h = conn->modes[i].vdisplay;
mode.refresh_rate = CalculateRefreshRate(&conn->modes[i]);
diff --git a/src/video/n3ds/SDL_n3dsvideo.c b/src/video/n3ds/SDL_n3dsvideo.c
index bcdae31f2ba9..9b43206be0b2 100644
--- a/src/video/n3ds/SDL_n3dsvideo.c
+++ b/src/video/n3ds/SDL_n3dsvideo.c
@@ -122,7 +122,6 @@ AddN3DSDisplay(gfxScreen_t screen)
mode.h = GSP_SCREEN_WIDTH;
mode.refresh_rate = 60.0f;
mode.format = FRAMEBUFFER_FORMAT;
- mode.driverdata = NULL;
display.name = (screen == GFX_TOP) ? "N3DS top screen" : "N3DS bottom screen";
display.desktop_mode = mode;
diff --git a/src/video/ngage/SDL_ngagevideo.cpp b/src/video/ngage/SDL_ngagevideo.cpp
index cc2570748dc8..388b65415379 100644
--- a/src/video/ngage/SDL_ngagevideo.cpp
+++ b/src/video/ngage/SDL_ngagevideo.cpp
@@ -148,11 +148,10 @@ int NGAGE_VideoInit(_THIS)
SDL_DisplayMode mode;
/* Use 12-bpp desktop mode */
+ SDL_zero(mode);
mode.format = SDL_PIXELFORMAT_RGB444;
mode.w = 176;
mode.h = 208;
- mode.refresh_rate = 0.0f;
- mode.driverdata = NULL;
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
return -1;
}
diff --git a/src/video/offscreen/SDL_offscreenvideo.c b/src/video/offscreen/SDL_offscreenvideo.c
index 5b1156f28b48..a13477f8aad3 100644
--- a/src/video/offscreen/SDL_offscreenvideo.c
+++ b/src/video/offscreen/SDL_offscreenvideo.c
@@ -101,16 +101,14 @@ int OFFSCREEN_VideoInit(_THIS)
SDL_DisplayMode mode;
/* Use a fake 32-bpp desktop mode */
+ SDL_zero(mode);
mode.format = SDL_PIXELFORMAT_RGB888;
mode.w = 1024;
mode.h = 768;
- mode.refresh_rate = 0.0f;
- mode.driverdata = NULL;
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
return -1;
}
- SDL_zero(mode);
SDL_AddDisplayMode(&_this->displays[0], &mode);
/* We're done! */
diff --git a/src/video/ps2/SDL_ps2video.c b/src/video/ps2/SDL_ps2video.c
index e198a6b87669..a99357da1932 100644
--- a/src/video/ps2/SDL_ps2video.c
+++ b/src/video/ps2/SDL_ps2video.c
@@ -69,19 +69,16 @@ static int PS2_VideoInit(_THIS)
SDL_DisplayMode current_mode;
SDL_zero(current_mode);
-
current_mode.w = 640;
current_mode.h = 480;
current_mode.refresh_rate = 60.0f;
/* 32 bpp for default */
current_mode.format = SDL_PIXELFORMAT_ABGR8888;
- current_mode.driverdata = NULL;
SDL_zero(display);
display.desktop_mode = current_mode;
display.current_mode = current_mode;
- display.driverdata = NULL;
SDL_AddDisplayMode(&display, ¤t_mode);
SDL_AddVideoDisplay(&display, SDL_FALSE);
diff --git a/src/video/psp/SDL_pspvideo.c b/src/video/psp/SDL_pspvideo.c
index 70c764851e92..7ab359ed8ad8 100644
--- a/src/video/psp/SDL_pspvideo.c
+++ b/src/video/psp/SDL_pspvideo.c
@@ -140,19 +140,16 @@ int PSP_VideoInit(_THIS)
SDL_DisplayMode current_mode;
SDL_zero(current_mode);
-
current_mode.w = 480;
current_mode.h = 272;
-
current_mode.refresh_rate = 60.0f;
+
/* 32 bpp for default */
current_mode.format = SDL_PIXELFORMAT_ABGR8888;
- current_mode.driverdata = NULL;
SDL_zero(display);
display.desktop_mode = current_mode;
display.current_mode = current_mode;
- display.driverdata = NULL;
SDL_AddDisplayMode(&display, ¤t_mode);
diff --git a/src/video/raspberry/SDL_rpivideo.c b/src/video/raspberry/SDL_rpivideo.c
index 7dd4017efbe4..dbc1a1d288f7 100644
--- a/src/video/raspberry/SDL_rpivideo.c
+++ b/src/video/raspberry/SDL_rpivideo.c
@@ -166,11 +166,10 @@ static void AddDispManXDisplay(const int display_id)
current_mode.w = modeinfo.width;
current_mode.h = modeinfo.height;
current_mode.refresh_rate = RPI_GetRefreshRate();
+
/* 32 bpp for default */
current_mode.format = SDL_PIXELFORMAT_ABGR8888;
- current_mode.driverdata = NULL;
-
SDL_zero(display);
display.desktop_mode = current_mode;
display.current_mode = current_mode;
diff --git a/src/video/riscos/SDL_riscosmodes.c b/src/video/riscos/SDL_riscosmodes.c
index 06612c55f000..0988a9451f96 100644
--- a/src/video/riscos/SDL_riscosmodes.c
+++ b/src/video/riscos/SDL_riscosmodes.c
@@ -136,6 +136,7 @@ static SDL_bool read_mode_block(int *block, SDL_DisplayMode *mode, SDL_bool exte
modeflags = read_mode_variable(block, 0);
}
+ SDL_zerop(mode);
mode->w = xres;
mode->h = yres;
mode->format = RISCOS_ModeToPixelFormat(ncolour, modeflags, log2bpp);
diff --git a/src/video/uikit/SDL_uikitmodes.m b/src/video/uikit/SDL_uikitmodes.m
index 60ade1a8f305..c1a5f8c039d7 100644
--- a/src/video/uikit/SDL_uikitmodes.m
+++ b/src/video/uikit/SDL_uikitmodes.m
@@ -263,16 +263,17 @@ static int UIKit_AddSingleDisplayMode(SDL_VideoDisplay *display, int w, int h,
UIScreen *uiscreen, UIScreenMode *uiscreenmode)
{
SDL_DisplayMode mode;
- SDL_zero(mode);
+ SDL_zero(mode);
if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
return -1;
}
- mode.format = SDL_PIXELFORMAT_ABGR8888;
- mode.refresh_rate = UIKit_GetDisplayModeRefreshRate(uiscreen);
mode.w = w;
mode.h = h;
+ mode.display_scale = uiscreen.scale;
+ mode.refresh_rate = UIKit_GetDisplayModeRefreshRate(uiscreen);
+ mode.format = SDL_PIXELFORMAT_ABGR8888;
if (SDL_AddDisplayMode(display, &mode)) {
return 0;
@@ -282,8 +283,8 @@ static int UIKit_AddSingleDisplayMode(SDL_VideoDisplay *display, int w, int h,
}
}
-static int UIKit_AddDisplayMode(SDL_VideoDisplay *display, int w, int h, UIScreen *uiscreen,
- UIScreenMode *uiscreenmode, SDL_bool addRotation)
+static int UIKit_AddDisplayMode(SDL_VideoDisplay *display, int w, int h,
+ UIScreen *uiscreen, UIScreenMode *uiscreenmode, SDL_bool addRotation)
{
if (UIKit_AddSingleDisplayMode(display, w, h, uiscreen, uiscreenmode) < 0) {
return -1;
@@ -302,10 +303,9 @@ static int UIKit_AddDisplayMode(SDL_VideoDisplay *display, int w, int h, UIScree
int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
{
UIScreenMode *uiscreenmode = uiscreen.currentMode;
- CGSize size = uiscreen.bounds.size;
+ CGSize size = uiscreenmode.size;
SDL_VideoDisplay display;
SDL_DisplayMode mode;
- SDL_zero(mode);
/* Make sure the width/height are oriented correctly */
if (UIKit_IsDisplayLandscape(uiscreen) != (size.width > size.height)) {
@@ -314,10 +314,12 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
size.height = height;
}
- mode.format = SDL_PIXELFORMAT_ABGR8888;
- mode.refresh_rate = UIKit_GetDisplayModeRefreshRate(uiscreen);
+ SDL_zero(mode);
mode.w = (int)size.width;
mode.h = (int)size.height;
+ mode.display_scale = uiscreen.scale;
+ mode.format = SDL_PIXELFORMAT_ABGR8888;
+ mode.refresh_rate = UIKit_GetDisplayModeRefreshRate(uiscreen);
if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
return -1;
@@ -394,7 +396,6 @@ void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
- CGFloat scale = data.uiscreen.scale;
NSArray *availableModes = nil;
#if TARGET_OS_TV
@@ -405,19 +406,8 @@ void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
#endif
for (UIScreenMode *uimode in availableModes) {
- /* The size of a UIScreenMode is in pixels, but we deal exclusively
- * in points (except in SDL_GL_GetDrawableSize.)
- *
- * For devices such as iPhone 6/7/8 Plus, the UIScreenMode reported
- * by iOS is not in physical pixels of the display, but rather the
- * point size times the scale. For example, on iOS 12.2 on iPhone 8
- * Plus the uimode.size is 1242x2208 and the uiscreen.scale is 3
- * thus this will give the size in points which is 414x736. The code
- * used to use the nativeScale, assuming UIScreenMode returned raw
- * physical pixels (as suggested by its documentation, but in
- * practice it is returning the retina pixels). */
- int w = (int)(uimode.size.width / scale);
- int h = (int)(uimode.size.height / scale);
+ int w = uimode.size.width;
+ int h = uimode.size.height;
/* Make sure the width/height are oriented correctly */
if (isLandscape != (w > h)) {
diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c
index 6732e47017fe..1d792eec9b8d 100644
--- a/src/video/vita/SDL_vitavideo.c
+++ b/src/video/vita/SDL_vitavideo.c
@@ -210,15 +210,13 @@ int VITA_VideoInit(_THIS)
#endif
current_mode.refresh_rate = 60.0f;
+
/* 32 bpp for default */
current_mode.format = SDL_PIXELFORMAT_ABGR8888;
- current_mode.driverdata = NULL;
-
SDL_zero(display);
display.desktop_mode = current_mode;
display.current_mode = current_mode;
- display.driverdata = NULL;
SDL_AddVideoDisplay(&display, SDL_FALSE);
VITA_InitTouch();
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index ee5762f93e7d..65308674ccdd 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -570,6 +570,7 @@ static void display_handle_done(void *data,
native_mode.w = driverdata->native_width;
native_mode.h = driverdata->native_height;
}
+ native_mode.display_scale = 1.0f; /* FIXME */
native_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
native_mode.driverdata = driverdata->output;
diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c
index 1292cd2219b6..2bea542e5cf1 100644
--- a/src/video/windows/SDL_windowsmodes.c
+++ b/src/video/windows/SDL_windowsmodes.c
@@ -47,20 +47,6 @@ static void WIN_UpdateDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_Di
char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
LPBITMAPINFO bmi;
HBITMAP hbm;
- int logical_width = GetDeviceCaps(hdc, HORZRES);
- int logical_height = GetDeviceCaps(hdc, VERTRES);
-
- /* High-DPI notes:
-
- If DPI-unaware:
- - GetDeviceCaps( hdc, HORZRES ) will return the monitor width in points.
- - DeviceMode.dmPelsWidth is actual pixels (unlike almost all other Windows API's,
- it's not virtualized when DPI unaware).
-
- If DPI-aware:
- - GetDeviceCaps( hdc, HORZRES ) will return pixels, same as DeviceMode.dmPelsWidth */
- mode->w = logical_width;
- mode->h = logical_height;
SDL_zeroa(bmi_data);
bmi = (LPBITMAPINFO)bmi_data;
@@ -172,8 +158,9 @@ static float WIN_GetRefreshRate(DEVMODE *mode)
}
}
-static SDL_bool WIN_GetDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode, SDL_DisplayOrientation *orientation)
+static SDL_bool WIN_GetDisplayMode(_THIS, HMONITOR hMonitor, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode, SDL_DisplayOrientation *orientation)
{
+ const SDL_VideoData *videodata = (const SDL_VideoData *)_this->driverdata;
SDL_DisplayModeData *data;
DEVMODE devmode;
@@ -188,6 +175,7 @@ static SDL_bool WIN_GetDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_D
return SDL_FALSE;
}
+ SDL_zerop(mode);
mode->driverdata = data;
data->DeviceMode = devmode;
@@ -196,6 +184,13 @@ static SDL_bool WIN_GetDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_D
mode->h = data->DeviceMode.dmPelsHeight;
mode->refresh_rate = WIN_GetRefreshRate(&data->DeviceMode);
+ if (index == ENUM_CURRENT_SETTINGS && videodata->GetDpiForMonitor) {
+ UINT hdpi_uint, vdpi_uint;
+ if (videodata->GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &hdpi_uint, &vdpi_uint) == S_OK) {
+ mode->display_scale = (float)hdpi_uint / 96;
+ }
+ }
+
/* Fill in the mode information */
WIN_UpdateDisplayMode(_this, deviceName, index, mode);
@@ -319,7 +314,7 @@ static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info,
SDL_Log("Display: %s\n", WIN_StringToUTF8W(info->szDevice));
#endif
- if (!WIN_GetDispl
(Patch may be truncated, please check the link at the top of this post.)