mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-30 19:24:23 +01:00
iOS: Resize in place on rotation instead of restarting graphics
Both view controllers stopped the emu/render thread on every rotation
and started it again, tearing down all of graphics. Since d0e45b94d9
NativeFrame resizes the graphics context and posts GPU_DISPLAY_RESIZED
on iOS too, so a NativeResized() is all a size change needs, like
Android now does. GLKView resizes its drawable by itself, and the Vulkan
context recreates the swapchain, which MoltenVK sizes from the layer.
The resize happens in viewDidLayoutSubviews, which UIKit runs at the
final size as a rotation animation starts. Resizing when the rotation
completed instead left half the screen black while it animated. This
also covers window resizes, which matter more now that
UIRequiresFullScreen is deprecated (iPadOS 26).
NativeFrame sets the PSP_CoreParameter() size, so the main thread
doesn't have to.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b544f5cb4e
commit
69d33ef8e9
3 files changed
+19
-52
No files matched your search
@@ -259,24 +259,6 @@ PPSSPPBaseViewController *sharedViewController;
|
||||
[(GLKView*)self.glView bindDrawable];
|
||||
}
|
||||
|
||||
// Can't consolidate this yet.
|
||||
- (void)viewWillTransitionToSize:(CGSize)size
|
||||
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
|
||||
[self.view endEditing:YES]; // clears any input focus
|
||||
|
||||
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
||||
NSLog(@"Rotating to size: %@", NSStringFromCGSize(size));
|
||||
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
||||
NSLog(@"Rotation finished");
|
||||
// Reinitialize graphics context to match new size
|
||||
[self requestExitGLRenderLoop];
|
||||
[self updateResolutionWithView:self.view];
|
||||
[self runGLRenderLoop];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void bindDefaultFBO()
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
@implementation PPSSPPBaseViewController {
|
||||
UIScreenEdgePanGestureRecognizer *mBackGestureRecognizer;
|
||||
CGSize lastLayoutSize_;
|
||||
}
|
||||
|
||||
// Strange idiom for generating unique IDs (within the process, at least).
|
||||
@@ -523,6 +524,23 @@ extern float g_safeInsetBottom;
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
// The immersive mode setting is per-orientation, so the status bar may need to change along with the rotation.
|
||||
[self setNeedsStatusBarAppearanceUpdate];
|
||||
|
||||
[self.view endEditing:YES]; // clears any input focus
|
||||
}
|
||||
|
||||
// Rotations and window resizes land here. UIKit lays out at the final size at the start of a
|
||||
// rotation animation, so resizing here (rather than when the rotation completes) keeps the
|
||||
// backbuffer matching the view while it animates.
|
||||
- (void)viewDidLayoutSubviews {
|
||||
[super viewDidLayoutSubviews];
|
||||
CGSize size = self.view.bounds.size;
|
||||
if (size.width <= 0.0 || size.height <= 0.0 || CGSizeEqualToSize(size, lastLayoutSize_)) {
|
||||
return;
|
||||
}
|
||||
lastLayoutSize_ = size;
|
||||
INFO_LOG(Log::G3D, "Laid out at %dx%d", (int)size.width, (int)size.height);
|
||||
// Resized in place: NativeFrame picks up the new size and lets the graphics context resize.
|
||||
[self updateResolutionWithView:self.view];
|
||||
}
|
||||
|
||||
- (void)updateResolutionWithView:(UIView *)view {
|
||||
@@ -548,10 +566,7 @@ extern float g_safeInsetBottom;
|
||||
|
||||
[view setContentScaleFactor:scale];
|
||||
|
||||
// PSP native resize
|
||||
PSP_CoreParameter().pixelWidth = g_display.pixel_xres;
|
||||
PSP_CoreParameter().pixelHeight = g_display.pixel_yres;
|
||||
|
||||
// NativeFrame updates the PSP_CoreParameter() size along with the rest.
|
||||
NativeResized();
|
||||
|
||||
NSLog(@"Updated display resolution: (%d, %d) @%.1fx",
|
||||
|
||||
@@ -220,36 +220,6 @@ static void VulkanRenderLoop(GraphicsContext *graphicsContext, CAMetalLayer *met
|
||||
INFO_LOG(Log::G3D, "viewDidDisappear");
|
||||
}
|
||||
|
||||
- (void)viewWillLayoutSubviews {
|
||||
[super viewWillLayoutSubviews];
|
||||
|
||||
// This is the first reliable place where self.view.bounds
|
||||
// matches the forced orientation.
|
||||
CGRect bounds = self.view.bounds;
|
||||
|
||||
INFO_LOG(Log::G3D, "Correcting metal view layout: %dx%d",
|
||||
(int)bounds.size.width, (int)bounds.size.height);
|
||||
|
||||
// Update your Metal layer/viewport here if necessary
|
||||
}
|
||||
|
||||
- (void)viewWillTransitionToSize:(CGSize)size
|
||||
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
|
||||
[self.view endEditing:YES]; // clears any input focus
|
||||
|
||||
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
||||
NSLog(@"Rotating to size: %@", NSStringFromCGSize(size));
|
||||
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
||||
NSLog(@"Rotation finished");
|
||||
// Reinitialize graphics context to match new size
|
||||
[self requestExitVulkanRenderLoop];
|
||||
[self updateResolutionWithView:self.view];
|
||||
[self runVulkanRenderLoop];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PPSSPPMetalView
|
||||
|
||||
Reference in new issue
Block a user