Merge commit 'metal renderer crash fix' into Integration
This commit is contained in:
commit
b1b46b3ec0
3 files changed
+26
-9
No files matched your search
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user