Properly fix the camera threading bugs

This commit is contained in:
Lior Halphon
2024-06-12 13:35:35 +03:00
parent 60ff8577bb
commit eebdbbfd5b

View File

@@ -54,6 +54,8 @@
UIButton *_cameraPositionButton; UIButton *_cameraPositionButton;
__weak GCController *_lastController; __weak GCController *_lastController;
dispatch_queue_t _cameraQueue;
} }
static void loadBootROM(GB_gameboy_t *gb, GB_boot_rom_t type) static void loadBootROM(GB_gameboy_t *gb, GB_boot_rom_t type)
@@ -263,6 +265,8 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
[_backgroundView addSubview:_cameraPositionButton]; [_backgroundView addSubview:_cameraPositionButton];
_cameraQueue = dispatch_queue_create("SameBoy Camera Queue", NULL);
[UNUserNotificationCenter currentNotificationCenter].delegate = self; [UNUserNotificationCenter currentNotificationCenter].delegate = self;
[self verifyEntitlements]; [self verifyEntitlements];
@@ -1130,6 +1134,9 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
- (void)cameraRequestUpdate - (void)cameraRequestUpdate
{ {
dispatch_async(dispatch_get_main_queue(), ^{
if (!_cameraSession) {
dispatch_async(_cameraQueue, ^{
@try { @try {
if (!_cameraSession) { if (!_cameraSession) {
NSError *error; NSError *error;
@@ -1144,7 +1151,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
_cameraOutput = [[AVCaptureVideoDataOutput alloc] init]; _cameraOutput = [[AVCaptureVideoDataOutput alloc] init];
[_cameraOutput setVideoSettings: @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)}]; [_cameraOutput setVideoSettings: @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)}];
[_cameraOutput setSampleBufferDelegate:self [_cameraOutput setSampleBufferDelegate:self
queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)]; queue:_cameraQueue];
@@ -1162,10 +1169,11 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
/* I have not tested camera support on many devices, so we catch exceptions just in case. */ /* I have not tested camera support on many devices, so we catch exceptions just in case. */
GB_camera_updated(&_gb); GB_camera_updated(&_gb);
} }
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ });
}
_cameraNeedsUpdate = true; _cameraNeedsUpdate = true;
[_disableCameraTimer invalidate]; [_disableCameraTimer invalidate];
dispatch_async(dispatch_get_main_queue(), ^{
if (!_cameraPositionButton.alpha) { if (!_cameraPositionButton.alpha) {
[UIView animateWithDuration:0.25 animations:^{ [UIView animateWithDuration:0.25 animations:^{
_cameraPositionButton.alpha = 1; _cameraPositionButton.alpha = 1;
@@ -1179,12 +1187,13 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
_cameraPositionButton.alpha = 0; _cameraPositionButton.alpha = 0;
}]; }];
} }
dispatch_async(_cameraQueue, ^{
[_cameraSession stopRunning]; [_cameraSession stopRunning];
_cameraSession = nil; _cameraSession = nil;
_cameraConnection = nil; _cameraConnection = nil;
_cameraOutput = nil; _cameraOutput = nil;
}];
}); });
}];
}); });
} }
@@ -1270,6 +1279,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
- (void)rotateCamera - (void)rotateCamera
{ {
dispatch_async(_cameraQueue, ^{
_cameraPosition ^= AVCaptureDevicePositionBack ^ AVCaptureDevicePositionFront; _cameraPosition ^= AVCaptureDevicePositionBack ^ AVCaptureDevicePositionFront;
[_cameraSession stopRunning]; [_cameraSession stopRunning];
_cameraSession = nil; _cameraSession = nil;
@@ -1279,7 +1289,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
_cameraNeedsUpdate = false; _cameraNeedsUpdate = false;
GB_camera_updated(&_gb); GB_camera_updated(&_gb);
} }
});
} }
@end @end