Cocoa Port: Fix a bunch of bugs related to moving windows between Retina and non-Retina displays. (Related to commit 2bc5b0d.)
This commit is contained in:
parent
f6e0feb13e
commit
1091e69726
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2017-2018 DeSmuME team
|
||||
Copyright (C) 2017-2025 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -256,15 +256,18 @@ double ClientDisplayPresenter::GetScaleFactor() const
|
|||
void ClientDisplayPresenter::SetScaleFactor(const double scaleFactor)
|
||||
{
|
||||
const bool willChangeScaleFactor = (this->_scaleFactor != scaleFactor);
|
||||
this->_scaleFactor = scaleFactor;
|
||||
|
||||
if (willChangeScaleFactor)
|
||||
if (!willChangeScaleFactor)
|
||||
{
|
||||
this->_glyphTileSize = (double)HUD_TEXTBOX_BASEGLYPHSIZE * scaleFactor;
|
||||
this->_glyphSize = (double)this->_glyphTileSize * 0.75;
|
||||
|
||||
this->LoadHUDFont();
|
||||
return;
|
||||
}
|
||||
|
||||
this->_scaleFactor = scaleFactor;
|
||||
this->_glyphTileSize = (double)HUD_TEXTBOX_BASEGLYPHSIZE * scaleFactor;
|
||||
this->_glyphSize = (double)this->_glyphTileSize * 0.75;
|
||||
|
||||
this->LoadHUDFont();
|
||||
this->_UpdateViewScale();
|
||||
}
|
||||
|
||||
void ClientDisplayPresenter::_UpdateClientSize()
|
||||
|
@ -292,6 +295,10 @@ void ClientDisplayPresenter::_UpdateViewScale()
|
|||
}
|
||||
|
||||
this->_hudObjectScale *= this->_scaleFactor;
|
||||
|
||||
pthread_mutex_lock(&this->_mutexHUDString);
|
||||
this->_hudNeedsUpdate = true;
|
||||
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||
}
|
||||
|
||||
// NDS screen layout
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2011 Roger Manuel
|
||||
Copyright (C) 2011-2022 DeSmuME team
|
||||
Copyright (C) 2011-2025 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -186,9 +186,9 @@ class ClientAVCaptureObject;
|
|||
@property (assign) NSInteger outputFilter;
|
||||
@property (assign) NSInteger pixelScaler;
|
||||
|
||||
- (void) commitPresenterProperties:(const ClientDisplayPresenterProperties &)viewProps;
|
||||
- (void) commitPresenterProperties:(const ClientDisplayPresenterProperties &)viewProps needFlush:(BOOL)needFlush;
|
||||
|
||||
- (void) handleChangeViewProperties;
|
||||
- (void) handleChangeViewPropertiesAndFlush:(BOOL)willFlush;
|
||||
- (void) handleReceiveGPUFrame;
|
||||
- (void) handleReloadReprocessRedraw;
|
||||
- (void) handleReprocessRedraw;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2011 Roger Manuel
|
||||
Copyright (C) 2011-2023 DeSmuME team
|
||||
Copyright (C) 2011-2025 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -721,13 +721,13 @@
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) commitPresenterProperties:(const ClientDisplayPresenterProperties &)viewProps
|
||||
- (void) commitPresenterProperties:(const ClientDisplayPresenterProperties &)viewProps needFlush:(BOOL)needFlush
|
||||
{
|
||||
apple_unfairlock_lock(_unfairlockViewProperties);
|
||||
_intermediateViewProps = viewProps;
|
||||
apple_unfairlock_unlock(_unfairlockViewProperties);
|
||||
|
||||
[self handleChangeViewProperties];
|
||||
[self handleChangeViewPropertiesAndFlush:needFlush];
|
||||
}
|
||||
|
||||
- (BOOL) canFilterOnGPU
|
||||
|
@ -1215,7 +1215,7 @@
|
|||
switch (messageID)
|
||||
{
|
||||
case MESSAGE_CHANGE_VIEW_PROPERTIES:
|
||||
[self handleChangeViewProperties];
|
||||
[self handleChangeViewPropertiesAndFlush:YES];
|
||||
break;
|
||||
|
||||
case MESSAGE_RELOAD_REPROCESS_REDRAW:
|
||||
|
@ -1247,14 +1247,18 @@
|
|||
_cdv->SetViewNeedsFlush();
|
||||
}
|
||||
|
||||
- (void) handleChangeViewProperties
|
||||
- (void) handleChangeViewPropertiesAndFlush:(BOOL)willFlush
|
||||
{
|
||||
apple_unfairlock_lock(_unfairlockViewProperties);
|
||||
_cdv->Get3DPresenter()->CommitPresenterProperties(_intermediateViewProps);
|
||||
apple_unfairlock_unlock(_unfairlockViewProperties);
|
||||
|
||||
_cdv->Get3DPresenter()->SetupPresenterProperties();
|
||||
_cdv->SetViewNeedsFlush();
|
||||
|
||||
if (willFlush)
|
||||
{
|
||||
_cdv->SetViewNeedsFlush();
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handleReceiveGPUFrame
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2017 DeSmuME team
|
||||
Copyright (C) 2017-2025 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -72,6 +72,7 @@ class MacDisplayLayeredView;
|
|||
@property (assign) NSInteger pixelScaler;
|
||||
|
||||
- (void) setupLayer;
|
||||
- (void) updateLayerPresenterProperties:(ClientDisplayPresenterProperties &)props scaleFactor:(const double)scaleFactor needFlush:(BOOL)needFlush;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2013-2023 DeSmuME team
|
||||
Copyright (C) 2013-2025 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -184,7 +184,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
|
||||
if ([self isFullScreen])
|
||||
{
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps];
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps needFlush:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -199,7 +199,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
// display view to update itself.
|
||||
if (oldBounds.width == newBounds.width && oldBounds.height == newBounds.height)
|
||||
{
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps];
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps needFlush:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
}
|
||||
else
|
||||
{
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps];
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps needFlush:YES];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
{
|
||||
if ([self isFullScreen])
|
||||
{
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps];
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps needFlush:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -261,7 +261,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
- (void) setDisplayOrder:(NSInteger)theOrder
|
||||
{
|
||||
_localViewProps.order = (ClientDisplayOrder)theOrder;
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps];
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps needFlush:YES];
|
||||
}
|
||||
|
||||
- (NSInteger) displayOrder
|
||||
|
@ -288,7 +288,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
case ClientDisplayLayout_Hybrid_16_9:
|
||||
case ClientDisplayLayout_Hybrid_16_10:
|
||||
default:
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps];
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps needFlush:YES];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
{
|
||||
case ClientDisplayLayout_Hybrid_16_9:
|
||||
case ClientDisplayLayout_Hybrid_16_10:
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps];
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps needFlush:YES];
|
||||
break;
|
||||
|
||||
case ClientDisplayLayout_Horizontal:
|
||||
|
@ -450,7 +450,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
// window size changed or not.
|
||||
if (oldBounds.width == newBounds.width && oldBounds.height == newBounds.height)
|
||||
{
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps];
|
||||
[[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps needFlush:YES];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1465,13 +1465,38 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
- (void)windowDidChangeScreen:(NSNotification *)notification
|
||||
{
|
||||
[self updateDisplayID];
|
||||
|
||||
// We also need to check if the window's backing scale factor changes, which can
|
||||
// occur when moving the window from a normal display to a HiDPI display (in
|
||||
// other words, from a non-Retina display to a Retina display), or vice versa.
|
||||
// We must update the display presenter properties now so that HUD element
|
||||
// locations and NDS touch points remain consistent for both Retina and non-Retina
|
||||
// displays. This feature requires Mac OS X v10.7 Lion or later.
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
NSScreen *screen = [[self window] screen];
|
||||
// Set up the scaling factor if this is a Retina window
|
||||
if ([screen respondsToSelector:@selector(backingScaleFactor)])
|
||||
MacDisplayLayeredView *cdv = [[self view] clientDisplayView];
|
||||
CALayer<DisplayViewCALayer> *localLayer = cdv->GetCALayer();
|
||||
|
||||
if ([[self window] respondsToSelector:@selector(backingScaleFactor)])
|
||||
{
|
||||
float scaleFactor = [screen backingScaleFactor];
|
||||
[[[self view] cdsVideoOutput] clientDisplay3DView]->Get3DPresenter()->SetScaleFactor(scaleFactor);
|
||||
const double oldScaleFactor = cdv->Get3DPresenter()->GetScaleFactor();
|
||||
const double newScaleFactor = [[self window] backingScaleFactor];
|
||||
|
||||
if (newScaleFactor != oldScaleFactor)
|
||||
{
|
||||
ClientDisplayPresenterProperties &props = [self localViewProperties];
|
||||
props.clientWidth *= newScaleFactor / oldScaleFactor;
|
||||
props.clientHeight *= newScaleFactor / oldScaleFactor;
|
||||
[[self view] updateLayerPresenterProperties:props scaleFactor:newScaleFactor needFlush:NO];
|
||||
|
||||
if ([localLayer isKindOfClass:[CAOpenGLLayer class]] && [localLayer respondsToSelector:@selector(setContentsScale:)])
|
||||
{
|
||||
[localLayer setContentsScale:newScaleFactor];
|
||||
}
|
||||
|
||||
cdv->Get3DPresenter()->SetScaleFactor(newScaleFactor);
|
||||
cdv->SetViewNeedsFlush();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2168,6 +2193,31 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
}
|
||||
}
|
||||
|
||||
- (void) updateLayerPresenterProperties:(ClientDisplayPresenterProperties &)props scaleFactor:(const double)scaleFactor needFlush:(BOOL)needFlush
|
||||
{
|
||||
double checkWidth = props.normalWidth;
|
||||
double checkHeight = props.normalHeight;
|
||||
ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, props.rotation, checkWidth, checkHeight);
|
||||
props.viewScale = ClientDisplayPresenter::GetMaxScalarWithinBounds(checkWidth, checkHeight, props.clientWidth, props.clientHeight);
|
||||
|
||||
if (localOGLContext != nil)
|
||||
{
|
||||
[localOGLContext update];
|
||||
}
|
||||
else if ([localLayer isKindOfClass:[CAOpenGLLayer class]])
|
||||
{
|
||||
[localLayer setBounds:CGRectMake(0.0f, 0.0f, props.clientWidth / scaleFactor, props.clientHeight / scaleFactor)];
|
||||
}
|
||||
#ifdef ENABLE_APPLE_METAL
|
||||
else if ([localLayer isKindOfClass:[CAMetalLayer class]])
|
||||
{
|
||||
[(CAMetalLayer *)localLayer setDrawableSize:CGSizeMake(props.clientWidth, props.clientHeight)];
|
||||
}
|
||||
#endif
|
||||
|
||||
[[self cdsVideoOutput] commitPresenterProperties:props needFlush:needFlush];
|
||||
}
|
||||
|
||||
#pragma mark InputHIDManagerTarget Protocol
|
||||
- (BOOL) handleHIDQueue:(IOHIDQueueRef)hidQueue hidManager:(InputHIDManager *)hidManager
|
||||
{
|
||||
|
@ -2258,7 +2308,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
if (rect.size.width != oldFrame.size.width || rect.size.height != oldFrame.size.height)
|
||||
{
|
||||
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
|
||||
ClientDisplayPresenterProperties &props = [windowController localViewProperties];
|
||||
NSRect newViewportRect = rect;
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
|
@ -2269,31 +2318,12 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
#endif
|
||||
|
||||
// Calculate the view scale for the given client size.
|
||||
double checkWidth = props.normalWidth;
|
||||
double checkHeight = props.normalHeight;
|
||||
ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, props.rotation, checkWidth, checkHeight);
|
||||
|
||||
ClientDisplayPresenterProperties &props = [windowController localViewProperties];
|
||||
props.clientWidth = newViewportRect.size.width;
|
||||
props.clientHeight = newViewportRect.size.height;
|
||||
props.viewScale = ClientDisplayPresenter::GetMaxScalarWithinBounds(checkWidth, checkHeight, props.clientWidth, props.clientHeight);
|
||||
|
||||
if (localOGLContext != nil)
|
||||
{
|
||||
[localOGLContext update];
|
||||
}
|
||||
else if ([localLayer isKindOfClass:[CAOpenGLLayer class]])
|
||||
{
|
||||
const double scaleFactor = [[self cdsVideoOutput] clientDisplay3DView]->Get3DPresenter()->GetScaleFactor();
|
||||
[localLayer setBounds:CGRectMake(0.0f, 0.0f, props.clientWidth / scaleFactor, props.clientHeight / scaleFactor)];
|
||||
}
|
||||
#ifdef ENABLE_APPLE_METAL
|
||||
else if ([localLayer isKindOfClass:[CAMetalLayer class]])
|
||||
{
|
||||
[(CAMetalLayer *)localLayer setDrawableSize:CGSizeMake(props.clientWidth, props.clientHeight)];
|
||||
}
|
||||
#endif
|
||||
|
||||
[[self cdsVideoOutput] commitPresenterProperties:props];
|
||||
const double scaleFactor = [[self cdsVideoOutput] clientDisplay3DView]->Get3DPresenter()->GetScaleFactor();
|
||||
[self updateLayerPresenterProperties:props scaleFactor:scaleFactor needFlush:YES];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue