From 6a27188023832f666c81ec340738a5f73e01e50d Mon Sep 17 00:00:00 2001 From: Sam Lantinga 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 a2318246d..d8d5c52c9 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 2d23c82eb..6aeb65c9c 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 3c0c47a37..b413d0394 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 9d9d69cd7..925f3dd10 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 1abb43997..cc2afdc40 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 6c781b9af..1bb617127 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 895bedca2..bb22d7e08 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 e1ef48a94..147bae41d 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 e996bcba4..1db906aa1 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 bcdae31f2..9b43206be 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 cc2570748..388b65415 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 5b1156f28..a13477f8a 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 e198a6b87..a99357da1 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 70c764851..7ab359ed8 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 7dd4017ef..dbc1a1d28 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 06612c55f..0988a9451 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 60ade1a8f..c1a5f8c03 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 6732e4701..1d792eec9 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 ee5762f93..65308674c 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 1292cd221..2bea542e5 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_GetDisplayMode(_this, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &orientation)) { + if (!WIN_GetDisplayMode(_this, hMonitor, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &orientation)) { return; } @@ -733,7 +728,7 @@ void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay *display) SDL_DisplayMode mode; for (i = 0;; ++i) { - if (!WIN_GetDisplayMode(_this, data->DeviceName, i, &mode, NULL)) { + if (!WIN_GetDisplayMode(_this, data->MonitorHandle, data->DeviceName, i, &mode, NULL)) { break; } if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) { diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index e046ee4cc..519e614ab 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -577,7 +577,6 @@ static int X11_InitModes_StdXlib(_THIS) mode.w = WidthOfScreen(screen); mode.h = HeightOfScreen(screen); mode.format = pixelformat; - mode.refresh_rate = 0; /* don't know it, sorry. */ displaydata = (SDL_DisplayData *)SDL_calloc(1, sizeof(*displaydata)); if (displaydata == NULL) { @@ -666,8 +665,8 @@ void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display) * we have to use the same format for all windows and all display modes. * (or support recreating the window with a new visual behind the scenes) */ + SDL_zero(mode); mode.format = sdl_display->current_mode.format; - mode.driverdata = NULL; #if SDL_VIDEO_DRIVER_X11_XRANDR if (data->use_xrandr) {