Fixed bug 5431 - SDL_Metal_GetDrawableSize is inaccurate for high dpi displays if a Metal view has not already been created Caleb Cornett For a window created with SDL_WINDOW_ALLOW_HIGHDPI, SDL_GL_GetDrawableSize will return the high-dpi drawable size even before any GL context creation happens. But SDL_Metal_GetDrawableSize will return the size of the window if the Metal view has not been created. This is confusing and inconsistent behavior. An easy way to test this is to build testgl2 and testvulkan on macOS with the SDL_WINDOW_ALLOW_HIGHDPI flag enabled during window creation. The GL2 program will report a drawable size of 2x window width and 2x window height, while the Vulkan program will report the window size. This patch addresses the issue by falling back to using the content view dimensions if no Metal view exists in the window. (The code for this was taken directly from Cocoa_GL_GetDrawableSize.) With this change, the testvulkan behavior matches that of testgl2. Note that I haven't tested for this issue on UIKit. It's possible a similar change will need to be made there too.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
diff --git a/src/video/cocoa/SDL_cocoametalview.m b/src/video/cocoa/SDL_cocoametalview.m
index a55b633..f31ee8a 100644
--- a/src/video/cocoa/SDL_cocoametalview.m
+++ b/src/video/cocoa/SDL_cocoametalview.m
@@ -172,8 +172,8 @@ void
Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
{ @autoreleasepool {
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
- NSView *view = data->nswindow.contentView;
- SDL_cocoametalview* metalview = [view viewWithTag:METALVIEW_TAG];
+ NSView *contentView = data->sdlContentView;
+ SDL_cocoametalview* metalview = [contentView viewWithTag:METALVIEW_TAG];
if (metalview) {
CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
SDL_assert(layer != NULL);
@@ -184,7 +184,21 @@ Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
*h = layer.drawableSize.height;
}
} else {
- SDL_GetWindowSize(window, w, h);
+ /* Fall back to the viewport size. */
+ NSRect viewport = [contentView bounds];
+ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ /* This gives us the correct viewport for a Retina-enabled view, only
+ * supported on 10.7+. */
+ if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) {
+ viewport = [contentView convertRectToBacking:viewport];
+ }
+ }
+ if (w) {
+ *w = viewport.size.width;
+ }
+ if (h) {
+ *h = viewport.size.height;
+ }
}
}}