mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-25 09:17:12 +01:00
metal: Fix high dpi and resizing on macOS, and clean up iOS code. Fixes bug #4250.
This commit is contained in:
parent
9a98e4b647
commit
d9094421e1
@ -752,11 +752,6 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load)
|
|||||||
static void
|
static void
|
||||||
METAL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
METAL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||||
{
|
{
|
||||||
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
|
||||||
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
|
|
||||||
data.mtllayer.drawableSize = CGSizeMake(event->data1, event->data2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->event == SDL_WINDOWEVENT_SHOWN ||
|
if (event->event == SDL_WINDOWEVENT_SHOWN ||
|
||||||
event->event == SDL_WINDOWEVENT_HIDDEN) {
|
event->event == SDL_WINDOWEVENT_HIDDEN) {
|
||||||
// !!! FIXME: write me
|
// !!! FIXME: write me
|
||||||
@ -848,12 +843,20 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||||||
mtltexdesc.height = (texture->h + 1) / 2;
|
mtltexdesc.height = (texture->h + 1) / 2;
|
||||||
mtltexdesc.textureType = MTLTextureType2DArray;
|
mtltexdesc.textureType = MTLTextureType2DArray;
|
||||||
mtltexdesc.arrayLength = 2;
|
mtltexdesc.arrayLength = 2;
|
||||||
mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
|
|
||||||
} else if (nv12) {
|
} else if (nv12) {
|
||||||
mtltexdesc.pixelFormat = MTLPixelFormatRG8Unorm;
|
mtltexdesc.pixelFormat = MTLPixelFormatRG8Unorm;
|
||||||
mtltexdesc.width = (texture->w + 1) / 2;
|
mtltexdesc.width = (texture->w + 1) / 2;
|
||||||
mtltexdesc.height = (texture->h + 1) / 2;
|
mtltexdesc.height = (texture->h + 1) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yuv || nv12) {
|
||||||
mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
|
mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
|
||||||
|
if (mtltexture_uv == nil) {
|
||||||
|
#if !__has_feature(objc_arc)
|
||||||
|
[mtltexture release];
|
||||||
|
#endif
|
||||||
|
return SDL_SetError("Texture allocation failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
METAL_TextureData *texturedata = [[METAL_TextureData alloc] init];
|
METAL_TextureData *texturedata = [[METAL_TextureData alloc] init];
|
||||||
|
@ -39,16 +39,16 @@
|
|||||||
|
|
||||||
#define METALVIEW_TAG 255
|
#define METALVIEW_TAG 255
|
||||||
|
|
||||||
@interface SDL_cocoametalview : NSView {
|
@interface SDL_cocoametalview : NSView
|
||||||
NSInteger _tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(NSRect)frame
|
- (instancetype)initWithFrame:(NSRect)frame
|
||||||
scale:(CGFloat)scale;
|
highDPI:(BOOL)highDPI;
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
|
@property (nonatomic) BOOL highDPI;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
SDL_cocoametalview* Cocoa_Mtl_AddMetalView(SDL_Window* window);
|
SDL_cocoametalview* Cocoa_Mtl_AddMetalView(SDL_Window* window);
|
||||||
|
@ -33,9 +33,6 @@
|
|||||||
|
|
||||||
@implementation SDL_cocoametalview
|
@implementation SDL_cocoametalview
|
||||||
|
|
||||||
/* The synthesized getter should be called by super's viewWithTag. */
|
|
||||||
@synthesize tag = _tag;
|
|
||||||
|
|
||||||
/* Return a Metal-compatible layer. */
|
/* Return a Metal-compatible layer. */
|
||||||
+ (Class)layerClass
|
+ (Class)layerClass
|
||||||
{
|
{
|
||||||
@ -57,27 +54,48 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(NSRect)frame
|
- (instancetype)initWithFrame:(NSRect)frame
|
||||||
scale:(CGFloat)scale
|
highDPI:(BOOL)highDPI
|
||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame])) {
|
if ((self = [super initWithFrame:frame])) {
|
||||||
_tag = METALVIEW_TAG;
|
self.highDPI = highDPI;
|
||||||
self.wantsLayer = YES;
|
self.wantsLayer = YES;
|
||||||
|
|
||||||
/* Allow resize. */
|
/* Allow resize. */
|
||||||
self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
||||||
|
|
||||||
/* Set the desired scale. */
|
[self updateDrawableSize];
|
||||||
((CAMetalLayer *) self.layer).drawableSize = NSSizeToCGSize([self bounds].size);
|
|
||||||
self.layer.contentsScale = scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSInteger)tag
|
||||||
|
{
|
||||||
|
return METALVIEW_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateDrawableSize
|
||||||
|
{
|
||||||
|
CAMetalLayer *metalLayer = (CAMetalLayer *)self.layer;
|
||||||
|
CGSize size = self.bounds.size;
|
||||||
|
CGSize backingSize = size;
|
||||||
|
|
||||||
|
if (self.highDPI) {
|
||||||
|
/* Note: NSHighResolutionCapable must be set to true in the app's
|
||||||
|
* Info.plist in order for the backing size to be high res.
|
||||||
|
*/
|
||||||
|
backingSize = [self convertSizeToBacking:size];
|
||||||
|
}
|
||||||
|
|
||||||
|
metalLayer.contentsScale = backingSize.height / size.height;
|
||||||
|
metalLayer.drawableSize = backingSize;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the size of the metal drawables when the view is resized. */
|
/* Set the size of the metal drawables when the view is resized. */
|
||||||
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize
|
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize
|
||||||
{
|
{
|
||||||
[super resizeWithOldSuperviewSize:oldSize];
|
[super resizeWithOldSuperviewSize:oldSize];
|
||||||
|
[self updateDrawableSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@ -87,24 +105,10 @@ Cocoa_Mtl_AddMetalView(SDL_Window* window)
|
|||||||
{
|
{
|
||||||
SDL_WindowData* data = (__bridge 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;
|
BOOL highDPI = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
|
||||||
|
SDL_cocoametalview *metalview;
|
||||||
|
|
||||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
metalview = [[SDL_cocoametalview alloc] initWithFrame:view.frame highDPI: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 scale:scale];
|
|
||||||
[view addSubview:metalview];
|
[view addSubview:metalview];
|
||||||
return metalview;
|
return metalview;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,8 @@
|
|||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame])) {
|
if ((self = [super initWithFrame:frame])) {
|
||||||
self.tag = METALVIEW_TAG;
|
self.tag = METALVIEW_TAG;
|
||||||
/* Set the desired scale. */
|
|
||||||
((CAMetalLayer *) self.layer).drawableSize = self.bounds.size;
|
|
||||||
self.layer.contentsScale = scale;
|
self.layer.contentsScale = scale;
|
||||||
|
[self updateDrawableSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@ -60,14 +59,16 @@
|
|||||||
/* Set the size of the metal drawables when the view is resized. */
|
/* Set the size of the metal drawables when the view is resized. */
|
||||||
- (void)layoutSubviews
|
- (void)layoutSubviews
|
||||||
{
|
{
|
||||||
CGSize bounds;
|
|
||||||
|
|
||||||
[super layoutSubviews];
|
[super layoutSubviews];
|
||||||
|
[self updateDrawableSize];
|
||||||
|
}
|
||||||
|
|
||||||
bounds = [self bounds].size;
|
- (void)updateDrawableSize
|
||||||
bounds.width *= self.layer.contentsScale;
|
{
|
||||||
bounds.height *= self.layer.contentsScale;
|
CGSize size = self.bounds.size;
|
||||||
((CAMetalLayer *) self.layer).drawableSize = bounds;
|
size.width *= self.layer.contentsScale;
|
||||||
|
size.height *= self.layer.contentsScale;
|
||||||
|
((CAMetalLayer *)self.layer).drawableSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
Loading…
Reference in New Issue
Block a user