feat: pause Metal renderer and graph when app is in background

This commit is contained in:
Acaki committed 2025-08-25 00:42:01 +08:00
1 parent a2c4d440db
commit c8f61b0b87
5 files changed
+98 -19

No files matched your search

+3
View File
@@ -22,4 +22,7 @@
enableHdr:(BOOL)enableHdr
metricsHandler:(MetricsHandler _Nonnull)metricsHandler;
- (void)pauseRendering;
- (void)resumeRendering;
@end
+33 -2
View File
@@ -91,6 +91,11 @@
}
- (void)waitToRenderTo:(nonnull CAMetalLayer *)layer {
// Skip waiting when renderer is paused
if (_renderer.isStopping) {
return;
}
// Renderer obtains a nextDrawable, waiting if necessary
if (@available(iOS 13.0, *)) {
[_renderer waitToRenderTo:layer];
@@ -102,14 +107,20 @@
/// Draw frame (used by manual loop)
- (void)renderTo:(nonnull CAMetalLayer *)layer {
CFTimeInterval timeout = (1.0f / _framerate) - _renderer.averageGPUTime;
Frame *frame = [_frameQueue dequeueWithTimeout:timeout];
if (!_renderer.isStopping) {
CFTimeInterval timeout = (1.0f / _framerate) - _renderer.averageGPUTime;
Frame *frame = [_frameQueue dequeueWithTimeout:timeout];
// Only render if not paused
if (frame) {
if (@available(iOS 13.0, *)) {
[_renderer renderFrame:frame toLayer:layer];
}
}
} else {
// When paused, we still dequeue frames to prevent accumulation
// but don't render them. Also sleep a bit to reduce CPU usage
usleep(100000);
}
}
@@ -117,6 +128,26 @@
[_renderer drawableResize:size];
}
- (void)pauseRendering {
if (_displayLink) {
_displayLink.paused = YES;
}
if (_renderer) {
_renderer.isStopping = YES;
}
Log(LOG_I, @"[MetalViewController] Rendering paused");
}
- (void)resumeRendering {
if (_renderer) {
_renderer.isStopping = NO;
}
if (_displayLink) {
_displayLink.paused = NO;
}
Log(LOG_I, @"[MetalViewController] Rendering resumed");
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];