mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-10-26 12:27:44 +00:00 
			
		
		
		
	Fix high-dpi support on macOS and simplify it and iOS variant.
The detault drawableSize for a CAMetalLayer is its bounds x its scale. So it is sufficient to set the *layer's* scale to the desired value.
This commit is contained in:
		| @@ -110,7 +110,9 @@ typedef enum | ||||
|     SDL_WINDOW_MOUSE_FOCUS = 0x00000400,        /**< window has mouse focus */ | ||||
|     SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), | ||||
|     SDL_WINDOW_FOREIGN = 0x00000800,            /**< window not created by SDL */ | ||||
|     SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported */ | ||||
|     SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported. | ||||
|                                                      On macOS NSHighResolutionCapable must be set true in the | ||||
|                                                      application's Info.plist for this to have any effect. */ | ||||
|     SDL_WINDOW_MOUSE_CAPTURE = 0x00004000,      /**< window has mouse captured (unrelated to INPUT_GRABBED) */ | ||||
|     SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000,      /**< window should always be above others */ | ||||
|     SDL_WINDOW_SKIP_TASKBAR  = 0x00010000,      /**< window should not be added to the taskbar */ | ||||
|   | ||||
| @@ -240,6 +240,9 @@ extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface( | ||||
|  * platform with high-DPI support (Apple calls this "Retina"), and not disabled | ||||
|  * by the \c SDL_HINT_VIDEO_HIGHDPI_DISABLED hint. | ||||
|  * | ||||
|  *  \note On macOS high-DPI support must be enabled for an application by | ||||
|  *        setting NSHighResolutionCapable to true in its Info.plist. | ||||
|  * | ||||
|  *  \sa SDL_GetWindowSize() | ||||
|  *  \sa SDL_CreateWindow() | ||||
|  */ | ||||
|   | ||||
| @@ -41,11 +41,10 @@ | ||||
|  | ||||
| @interface SDL_cocoametalview : NSView { | ||||
|     NSInteger _tag; | ||||
|     bool _useHighDPI; | ||||
| } | ||||
|  | ||||
| - (instancetype)initWithFrame:(NSRect)frame | ||||
|                    useHighDPI:(bool)useHighDPI; | ||||
|                         scale:(CGFloat)scale; | ||||
|  | ||||
| /* Override superclass tag so this class can set it. */ | ||||
| @property (assign, readonly) NSInteger tag; | ||||
|   | ||||
| @@ -57,17 +57,19 @@ | ||||
| } | ||||
|  | ||||
| - (instancetype)initWithFrame:(NSRect)frame | ||||
|                    useHighDPI:(bool)useHighDPI | ||||
|                         scale:(CGFloat)scale | ||||
| { | ||||
| 	if ((self = [super initWithFrame:frame])) { | ||||
|         _tag = METALVIEW_TAG; | ||||
|         self.wantsLayer = YES; | ||||
|  | ||||
|         /* Allow resize. */ | ||||
|         self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; | ||||
|         _tag = METALVIEW_TAG; | ||||
|  | ||||
|         _useHighDPI = useHighDPI; | ||||
|         [self updateDrawableSize]; | ||||
|         /* Set the desired scale. The default drawableSize of a CAMetalLayer | ||||
|          * is its bounds x its scale so nothing further needs to be done. | ||||
|          */ | ||||
|         self.layer.contentsScale = scale; | ||||
| 	} | ||||
|    | ||||
| 	return self; | ||||
| @@ -77,16 +79,6 @@ | ||||
| - (void)resizeWithOldSuperviewSize:(NSSize)oldSize | ||||
| { | ||||
|     [super resizeWithOldSuperviewSize:oldSize]; | ||||
|     [self updateDrawableSize]; | ||||
| } | ||||
|  | ||||
| - (void)updateDrawableSize | ||||
| { | ||||
|     NSRect bounds = [self bounds]; | ||||
|     if (_useHighDPI) { | ||||
|         bounds = [self convertRectToBacking:bounds]; | ||||
|     } | ||||
|     ((CAMetalLayer *) self.layer).drawableSize = NSSizeToCGSize(bounds.size); | ||||
| } | ||||
|  | ||||
| @end | ||||
| @@ -94,12 +86,26 @@ | ||||
| SDL_cocoametalview* | ||||
| Cocoa_Mtl_AddMetalView(SDL_Window* window) | ||||
| { | ||||
|     SDL_WindowData *data = (SDL_WindowData *)window->driverdata; | ||||
|     SDL_WindowData* data = (__bridge SDL_WindowData *)window->driverdata; | ||||
|     NSView *view = data->nswindow.contentView; | ||||
|     CGFloat scale = 1.0; | ||||
|  | ||||
|     if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { | ||||
|         /* Set the scale to the natural scale factor of the screen - then | ||||
|          * the backing dimensions of the Metal view will match the pixel | ||||
|          * dimensions of the screen rather than the dimensions in points | ||||
|          * yielding high resolution on retine displays. | ||||
|          * | ||||
|          * N.B. In order for backingScaleFactor to be > 1, | ||||
|          * NSHighResolutionCapable must be set to true in the app's Info.plist. | ||||
|          */ | ||||
|         NSWindow* nswindow = data->nswindow; | ||||
|         if ([nswindow.screen respondsToSelector:@selector(backingScaleFactor)]) | ||||
|             scale = data->nswindow.screen.backingScaleFactor; | ||||
|     } | ||||
|          | ||||
|     SDL_cocoametalview *metalview | ||||
|         = [[SDL_cocoametalview alloc] initWithFrame:view.frame | ||||
|                        useHighDPI:(window->flags & SDL_WINDOW_ALLOW_HIGHDPI)]; | ||||
|         = [[SDL_cocoametalview alloc] initWithFrame:view.frame scale:scale]; | ||||
|     [view addSubview:metalview]; | ||||
|     return metalview; | ||||
| } | ||||
| @@ -119,6 +125,8 @@ Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h) | ||||
|         if (h) { | ||||
|             *h = layer.drawableSize.height; | ||||
|         } | ||||
|     } else { | ||||
|         SDL_GetWindowSize(window, w, h); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -43,8 +43,7 @@ | ||||
| @interface SDL_uikitmetalview : SDL_uikitview | ||||
|  | ||||
| - (instancetype)initWithFrame:(CGRect)frame | ||||
|                         scale:(CGFloat)scale | ||||
|                         tag:(int)tag; | ||||
|                         scale:(CGFloat)scale; | ||||
|  | ||||
| @end | ||||
|  | ||||
|   | ||||
| @@ -46,14 +46,12 @@ | ||||
|  | ||||
| - (instancetype)initWithFrame:(CGRect)frame | ||||
|                         scale:(CGFloat)scale | ||||
|                           tag:(int)tag | ||||
| { | ||||
|     if ((self = [super initWithFrame:frame])) { | ||||
|         /* Set the appropriate scale (for retina display support) */ | ||||
|         self.contentScaleFactor = scale; | ||||
|         self.tag = tag; | ||||
|  | ||||
|         [self updateDrawableSize]; | ||||
|         self.tag = METALVIEW_TAG; | ||||
|         /* Set the desired scale. The default drawableSize of a CAMetalLayer | ||||
|          * is its bounds x its scale so nothing further needs to be done. */ | ||||
|         self.layer.contentsScale = scale; | ||||
|     } | ||||
|  | ||||
|     return self; | ||||
| @@ -63,16 +61,6 @@ | ||||
| - (void)layoutSubviews | ||||
| { | ||||
|     [super layoutSubviews]; | ||||
|     [self updateDrawableSize]; | ||||
| } | ||||
|  | ||||
| - (void)updateDrawableSize | ||||
| { | ||||
|     CGSize size  = self.bounds.size; | ||||
|     size.width  *= self.contentScaleFactor; | ||||
|     size.height *= self.contentScaleFactor; | ||||
|  | ||||
|     ((CAMetalLayer *) self.layer).drawableSize = size; | ||||
| } | ||||
|  | ||||
| @end | ||||
| @@ -89,9 +77,10 @@ UIKit_Mtl_AddMetalView(SDL_Window* window) | ||||
| 	} | ||||
|  | ||||
|     if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { | ||||
|         /* Set the scale to the natural scale factor of the screen - the | ||||
|          * backing dimensions of the Metal view will match the pixel | ||||
|          * dimensions of the screen rather than the dimensions in points. | ||||
|         /* Set the scale to the natural scale factor of the screen - then | ||||
|          * the backing dimensions of the Metal view will match the pixel | ||||
|          * dimensions of the screen rather than the dimensions in points | ||||
|          * yielding high resolution on retine displays. | ||||
|          */ | ||||
| #ifdef __IPHONE_8_0 | ||||
|         if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) { | ||||
| @@ -104,8 +93,7 @@ UIKit_Mtl_AddMetalView(SDL_Window* window) | ||||
|     } | ||||
|     SDL_uikitmetalview *metalview | ||||
|          = [[SDL_uikitmetalview alloc] initWithFrame:view.frame | ||||
|                                           scale:scale | ||||
|                                             tag:METALVIEW_TAG]; | ||||
|                                                scale:scale]; | ||||
|     [metalview setSDLWindow:window]; | ||||
|  | ||||
|     return metalview; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Mark Callow
					Mark Callow