mirror of https://github.com/encounter/SDL.git
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:
parent
a0687a9ccb
commit
69958441be
|
@ -110,7 +110,9 @@ typedef enum
|
||||||
SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */
|
SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */
|
||||||
SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
|
SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
|
||||||
SDL_WINDOW_FOREIGN = 0x00000800, /**< window not created by SDL */
|
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_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_ALWAYS_ON_TOP = 0x00008000, /**< window should always be above others */
|
||||||
SDL_WINDOW_SKIP_TASKBAR = 0x00010000, /**< window should not be added to the taskbar */
|
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
|
* platform with high-DPI support (Apple calls this "Retina"), and not disabled
|
||||||
* by the \c SDL_HINT_VIDEO_HIGHDPI_DISABLED hint.
|
* 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_GetWindowSize()
|
||||||
* \sa SDL_CreateWindow()
|
* \sa SDL_CreateWindow()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -41,11 +41,10 @@
|
||||||
|
|
||||||
@interface SDL_cocoametalview : NSView {
|
@interface SDL_cocoametalview : NSView {
|
||||||
NSInteger _tag;
|
NSInteger _tag;
|
||||||
bool _useHighDPI;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(NSRect)frame
|
- (instancetype)initWithFrame:(NSRect)frame
|
||||||
useHighDPI:(bool)useHighDPI;
|
scale:(CGFloat)scale;
|
||||||
|
|
||||||
/* Override superclass tag so this class can set it. */
|
/* Override superclass tag so this class can set it. */
|
||||||
@property (assign, readonly) NSInteger tag;
|
@property (assign, readonly) NSInteger tag;
|
||||||
|
|
|
@ -57,17 +57,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(NSRect)frame
|
- (instancetype)initWithFrame:(NSRect)frame
|
||||||
useHighDPI:(bool)useHighDPI
|
scale:(CGFloat)scale
|
||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame])) {
|
if ((self = [super initWithFrame:frame])) {
|
||||||
|
_tag = METALVIEW_TAG;
|
||||||
self.wantsLayer = YES;
|
self.wantsLayer = YES;
|
||||||
|
|
||||||
/* Allow resize. */
|
/* Allow resize. */
|
||||||
self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
||||||
_tag = METALVIEW_TAG;
|
|
||||||
|
|
||||||
_useHighDPI = useHighDPI;
|
/* Set the desired scale. The default drawableSize of a CAMetalLayer
|
||||||
[self updateDrawableSize];
|
* is its bounds x its scale so nothing further needs to be done.
|
||||||
|
*/
|
||||||
|
self.layer.contentsScale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -77,16 +79,6 @@
|
||||||
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize
|
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize
|
||||||
{
|
{
|
||||||
[super resizeWithOldSuperviewSize: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
|
@end
|
||||||
|
@ -94,12 +86,26 @@
|
||||||
SDL_cocoametalview*
|
SDL_cocoametalview*
|
||||||
Cocoa_Mtl_AddMetalView(SDL_Window* window)
|
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;
|
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 *metalview
|
||||||
= [[SDL_cocoametalview alloc] initWithFrame:view.frame
|
= [[SDL_cocoametalview alloc] initWithFrame:view.frame scale:scale];
|
||||||
useHighDPI:(window->flags & SDL_WINDOW_ALLOW_HIGHDPI)];
|
|
||||||
[view addSubview:metalview];
|
[view addSubview:metalview];
|
||||||
return metalview;
|
return metalview;
|
||||||
}
|
}
|
||||||
|
@ -119,6 +125,8 @@ Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
|
||||||
if (h) {
|
if (h) {
|
||||||
*h = layer.drawableSize.height;
|
*h = layer.drawableSize.height;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SDL_GetWindowSize(window, w, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,7 @@
|
||||||
@interface SDL_uikitmetalview : SDL_uikitview
|
@interface SDL_uikitmetalview : SDL_uikitview
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
scale:(CGFloat)scale
|
scale:(CGFloat)scale;
|
||||||
tag:(int)tag;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -46,14 +46,12 @@
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
scale:(CGFloat)scale
|
scale:(CGFloat)scale
|
||||||
tag:(int)tag
|
|
||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame])) {
|
if ((self = [super initWithFrame:frame])) {
|
||||||
/* Set the appropriate scale (for retina display support) */
|
self.tag = METALVIEW_TAG;
|
||||||
self.contentScaleFactor = scale;
|
/* Set the desired scale. The default drawableSize of a CAMetalLayer
|
||||||
self.tag = tag;
|
* is its bounds x its scale so nothing further needs to be done. */
|
||||||
|
self.layer.contentsScale = scale;
|
||||||
[self updateDrawableSize];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -63,16 +61,6 @@
|
||||||
- (void)layoutSubviews
|
- (void)layoutSubviews
|
||||||
{
|
{
|
||||||
[super 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
|
@end
|
||||||
|
@ -89,9 +77,10 @@ UIKit_Mtl_AddMetalView(SDL_Window* window)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||||
/* Set the scale to the natural scale factor of the screen - the
|
/* Set the scale to the natural scale factor of the screen - then
|
||||||
* backing dimensions of the Metal view will match the pixel
|
* the backing dimensions of the Metal view will match the pixel
|
||||||
* dimensions of the screen rather than the dimensions in points.
|
* dimensions of the screen rather than the dimensions in points
|
||||||
|
* yielding high resolution on retine displays.
|
||||||
*/
|
*/
|
||||||
#ifdef __IPHONE_8_0
|
#ifdef __IPHONE_8_0
|
||||||
if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
|
if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
|
||||||
|
@ -104,8 +93,7 @@ UIKit_Mtl_AddMetalView(SDL_Window* window)
|
||||||
}
|
}
|
||||||
SDL_uikitmetalview *metalview
|
SDL_uikitmetalview *metalview
|
||||||
= [[SDL_uikitmetalview alloc] initWithFrame:view.frame
|
= [[SDL_uikitmetalview alloc] initWithFrame:view.frame
|
||||||
scale:scale
|
scale:scale];
|
||||||
tag:METALVIEW_TAG];
|
|
||||||
[metalview setSDLWindow:window];
|
[metalview setSDLWindow:window];
|
||||||
|
|
||||||
return metalview;
|
return metalview;
|
||||||
|
|
Loading…
Reference in New Issue