Skip to content

Commit a3bda81

Browse files
committed
Fix crash when resizing
1 parent 8ffdb83 commit a3bda81

2 files changed

Lines changed: 58 additions & 10 deletions

File tree

fusepb/views/DisplayOpenGLView.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
CVDisplayLinkRef displayLink;
7777
CGDirectDisplayID mainViewDisplayID;
7878
BOOL displayLinkRunning;
79+
BOOL isResizing;
7980
}
8081
+(DisplayOpenGLView *) instance;
8182

fusepb/views/DisplayOpenGLView.m

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ -(id) initWithFrame:(NSRect)frameRect
311311
currentScreenTex = 0;
312312

313313
statusbar_updated = NO;
314+
isResizing = NO;
314315

315316
[self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
316317

@@ -571,31 +572,48 @@ -(void) drawRect:(NSRect)aRect
571572
-(void) doReshape
572573
{
573574
[view_lock lock];
575+
576+
/* Set resize flag to block rendering during reshape */
577+
isResizing = YES;
578+
579+
/* Stop display link during reshape to prevent drawing with invalid context */
580+
[self displayLinkStop];
581+
574582
NSRect rect;
575583

576-
[[self openGLContext] makeCurrentContext];
584+
NSOpenGLContext *context = [self openGLContext];
585+
if (context) {
586+
[context makeCurrentContext];
577587

578-
rect = [self bounds];
588+
rect = [self bounds];
579589

580-
glViewport( 0, 0, (int) rect.size.width, (int) rect.size.height );
590+
glViewport( 0, 0, (int) rect.size.width, (int) rect.size.height );
581591

582-
glMatrixMode( GL_PROJECTION );
583-
glLoadIdentity();
592+
glMatrixMode( GL_PROJECTION );
593+
glLoadIdentity();
584594

585-
glMatrixMode( GL_MODELVIEW );
586-
glLoadIdentity();
587-
588-
[[self openGLContext] update];
595+
glMatrixMode( GL_MODELVIEW );
596+
glLoadIdentity();
597+
598+
[context update];
599+
}
589600

590601
statusbar_updated = YES;
602+
603+
/* Clear resize flag and restart display link after reshape completes */
604+
isResizing = NO;
605+
[self displayLinkStart];
606+
591607
[view_lock unlock];
592608
}
593609

594610
/* scrolled, moved or resized */
595611
-(void) reshape
596612
{
597613
[super reshape];
598-
[self performSelectorOnMainThread:@selector(doReshape) withObject:self waitUntilDone:NO];
614+
/* Wait for reshape to complete to prevent queuing multiple reshape operations
615+
during slow drag resize, which can cause race conditions */
616+
[self performSelectorOnMainThread:@selector(doReshape) withObject:self waitUntilDone:YES];
599617
}
600618

601619
-(void) destroyTexture
@@ -1333,6 +1351,15 @@ -(CVReturn) displayFrame:(const CVTimeStamp *)timeStamp
13331351
int i;
13341352
PIG_dirtytable *workdirty = NULL;
13351353

1354+
/* Skip rendering if window is being resized to prevent crashes */
1355+
[view_lock lock];
1356+
BOOL resizing = isResizing;
1357+
[view_lock unlock];
1358+
1359+
if (resizing) {
1360+
return kCVReturnSuccess;
1361+
}
1362+
13361363
// Is it possible that while waiting for a lock the emulator is stopped?
13371364
// or already holds the lock? If so give up on updating the frame rather
13381365
// than deadlock on getting the lock - may mean that we miss some screen
@@ -1341,6 +1368,12 @@ -(CVReturn) displayFrame:(const CVTimeStamp *)timeStamp
13411368
return kCVReturnSuccess;
13421369
}
13431370

1371+
/* Check if buffered_screen.dirty is initialized - it might be NULL during initialization or cleanup */
1372+
if( !buffered_screen.dirty ) {
1373+
[buffered_screen_lock unlock];
1374+
return kCVReturnSuccess;
1375+
}
1376+
13441377
if( buffered_screen.dirty->count == 0 && !statusbar_updated ) {
13451378
[buffered_screen_lock unlock];
13461379
return kCVReturnSuccess;
@@ -1354,6 +1387,20 @@ -(CVReturn) displayFrame:(const CVTimeStamp *)timeStamp
13541387
// occur, also cover the screen texture swap
13551388
[view_lock lock];
13561389

1390+
// Double-check resize flag after acquiring lock - resize might have started
1391+
if (isResizing) {
1392+
[view_lock unlock];
1393+
[buffered_screen_lock unlock];
1394+
return kCVReturnSuccess;
1395+
}
1396+
1397+
// Check if textures are initialized - they may be destroyed during window resize
1398+
if (!screenTexInitialised) {
1399+
[view_lock unlock];
1400+
[buffered_screen_lock unlock];
1401+
return kCVReturnSuccess;
1402+
}
1403+
13571404
if (screenTex[currentScreenTex].dirty)
13581405
pig_dirty_copy( &workdirty, screenTex[currentScreenTex].dirty );
13591406

0 commit comments

Comments
 (0)