Merge commit 'metal renderer crash fix' into Integration

This commit is contained in:
TrueZhuanjia committed 2025-09-02 12:36:50 +08:00
commit b1b46b3ec0
3 files changed
+26 -9

No files matched your search

+2 -1
View File
@@ -23,12 +23,13 @@
@property (nonatomic) id<CAMetalDrawable> _Nullable nextDrawable; @property (nonatomic) id<CAMetalDrawable> _Nullable nextDrawable;
@property (atomic) BOOL isStopping; @property (atomic) BOOL isStopping;
@property (nonatomic) BOOL hdrEnabled; @property (nonatomic) BOOL hdrEnabled;
@property (nonatomic, readonly, nonnull) dispatch_semaphore_t inFlightSemaphore;
- (instancetype _Nonnull )initWithMetalDevice:(id<MTLDevice>_Nonnull)device drawablePixelFormat:(MTLPixelFormat)drawablePixelFormat settings:(TemporarySettings* _Nonnull )currentSettings; - (instancetype _Nonnull )initWithMetalDevice:(id<MTLDevice>_Nonnull)device drawablePixelFormat:(MTLPixelFormat)drawablePixelFormat settings:(TemporarySettings* _Nonnull )currentSettings;
- (void)renderFrame:(nonnull Frame *)frame toLayer:(nonnull CAMetalLayer *)layer; - (void)renderFrame:(nonnull Frame *)frame toLayer:(nonnull CAMetalLayer *)layer;
- (void)waitToRenderTo:(nonnull CAMetalLayer *)layer API_AVAILABLE(ios(13.0)); - (BOOL)waitToRenderTo:(nonnull CAMetalLayer *)layer API_AVAILABLE(ios(13.0));
- (void)drawableResize:(CGSize)drawableSize; - (void)drawableResize:(CGSize)drawableSize;
- (void)shutdown; - (void)shutdown;
+13 -4
View File
@@ -138,6 +138,8 @@ CFStringRef __currentColorSpace;
dispatch_semaphore_t _inFlightSemaphore; dispatch_semaphore_t _inFlightSemaphore;
} }
@synthesize inFlightSemaphore = _inFlightSemaphore;
- (instancetype)initWithMetalDevice:(id<MTLDevice>)device drawablePixelFormat:(MTLPixelFormat)drawablePixelFormat settings:(TemporarySettings* )currentSettings { - (instancetype)initWithMetalDevice:(id<MTLDevice>)device drawablePixelFormat:(MTLPixelFormat)drawablePixelFormat settings:(TemporarySettings* )currentSettings {
self = [super init]; self = [super init];
if (self) { if (self) {
@@ -842,13 +844,20 @@ CFStringRef __currentColorSpace;
} }
} }
- (void)waitToRenderTo:(nonnull CAMetalLayer *)layer { - (BOOL)waitToRenderTo:(nonnull CAMetalLayer *)layer {
// Wait to ensure only `MaxFramesInFlight` number of frames are getting processed // Wait to ensure only `MaxFramesInFlight` number of frames are getting processed
// by any stage in the Metal pipeline (CPU, GPU, Metal, Drivers, etc.). // by any stage in the Metal pipeline (CPU, GPU, Metal, Drivers, etc.).
if (!self.isStopping) { if (self.isStopping) {
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1f * NSEC_PER_SEC)); // 100ms return NO;
dispatch_semaphore_wait(_inFlightSemaphore, timeout);
} }
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1f * NSEC_PER_SEC)); // 100ms
if (dispatch_semaphore_wait(_inFlightSemaphore, timeout) != 0) {
Log(LOG_W, @"Timed out waiting for in-flight frame buffer.");
return NO;
}
return YES;
} }
- (void)shutdown { - (void)shutdown {
+11 -4
View File
@@ -19,6 +19,7 @@
MetalVideoRenderer *_renderer; MetalVideoRenderer *_renderer;
MetricsHandler _metricsHandler; MetricsHandler _metricsHandler;
CADisplayLink *_displayLink; CADisplayLink *_displayLink;
BOOL _frameSlotAcquired;
} }
- (nonnull instancetype)initWithFrame:(CGRect)bounds framerate:(float)framerate settings:(TemporarySettings* )settings metricsHandler:(MetricsHandler)metricsHandler { - (nonnull instancetype)initWithFrame:(CGRect)bounds framerate:(float)framerate settings:(TemporarySettings* )settings metricsHandler:(MetricsHandler)metricsHandler {
@@ -113,17 +114,20 @@
return; return;
} }
// Renderer obtains a nextDrawable, waiting if necessary
if (@available(iOS 13.0, *)) { if (@available(iOS 13.0, *)) {
[_renderer waitToRenderTo:layer]; _frameSlotAcquired = [_renderer waitToRenderTo:layer];
} }
// If we don't have a frame yet, wait on that too if (_frameSlotAcquired) {
[_frameQueue waitForEnqueue]; [_frameQueue waitForEnqueue];
}
} }
/// Draw frame (used by manual loop) /// Draw frame (used by manual loop)
- (void)renderTo:(nonnull CAMetalLayer *)layer { - (void)renderTo:(nonnull CAMetalLayer *)layer {
if (!_frameSlotAcquired) {
return;
}
CFTimeInterval timeout = (1.0f / _framerate) - _renderer.averageGPUTime; CFTimeInterval timeout = (1.0f / _framerate) - _renderer.averageGPUTime;
Frame *frame = [_frameQueue dequeueWithTimeout:timeout]; Frame *frame = [_frameQueue dequeueWithTimeout:timeout];
@@ -133,10 +137,13 @@
//if (@available(iOS 13.0, *)) { //if (@available(iOS 13.0, *)) {
[_renderer renderFrame:frame toLayer:layer]; [_renderer renderFrame:frame toLayer:layer];
//} //}
} else {
dispatch_semaphore_signal([_renderer inFlightSemaphore]);
} }
} else { } else {
// When paused, we still dequeue frames to prevent accumulation // When paused, we still dequeue frames to prevent accumulation
// but don't render them. Also sleep a bit to reduce CPU usage // but don't render them. Also sleep a bit to reduce CPU usage
dispatch_semaphore_signal([_renderer inFlightSemaphore]);
usleep(100000); usleep(100000);
} }
} }