Skip to content

Commit dab77da

Browse files
SiegeLordExSiegeLord
authored andcommitted
Add a workaround for #1350
Elias investigated the issue in #1418, showing that there was some concurrent OpenGL usage between OS's internals and user code. That specific workaround did not work for me on my Mac, so as an alternative, in this commit we add an option to bypass live resize altogether. In short, the user opts into drawing halt/resume events via a config option, and ceases to draw while live resize is underway. This isn't ideal, but at least is a way to prevent the crashing behavior until we find some better idea.
1 parent 139b078 commit dab77da

File tree

6 files changed

+98
-2
lines changed

6 files changed

+98
-2
lines changed

allegro5.cfg

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,15 @@ max_page_size = 0
231231
# Uncomment if you want only the characters in the cache_text entry to ever be drawn
232232
# skip_cache_misses = true
233233

234+
[osx]
235+
236+
# If set to false, then Allegro will send ALLEGRO_EVENT_DISPLAY_HALT_DRAWING
237+
# and ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING events when the user resizes a
238+
# window. Drawing while resizing ("live resizing") has historically been buggy,
239+
# so setting this to false allows you to opt out of this behavior and detect
240+
# when the resize happens.
241+
allow_live_resize = true
242+
234243
[compatibility]
235244

236245
# Prior to 5.2.4 on Windows you had to manually resize the display when

demos/skater/src/framework.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ void run_framework(void)
336336

337337
case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING:
338338
background_mode = false;
339+
al_acknowledge_drawing_resume(screen);
339340
break;
340341

341342
case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:

examples/ex_camera.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ int main(int argc, char **argv)
474474
ALLEGRO_TIMER *timer;
475475
ALLEGRO_EVENT_QUEUE *queue;
476476
int redraw = 0;
477+
bool halt_drawing = false;
477478
char const *skybox_name = NULL;
478479

479480
if (argc > 1) {
@@ -489,6 +490,7 @@ int main(int argc, char **argv)
489490
al_install_keyboard();
490491
al_install_mouse();
491492

493+
al_set_config_value(al_get_system_config(), "osx", "allow_live_resize", "false");
492494
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
493495
al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
494496
al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST);
@@ -566,12 +568,20 @@ int main(int argc, char **argv)
566568
else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
567569
ex.button[event.mouse.button] = 0;
568570
}
571+
else if (event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING) {
572+
halt_drawing = true;
573+
al_acknowledge_drawing_halt(display);
574+
}
575+
else if (event.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING) {
576+
halt_drawing = false;
577+
al_acknowledge_drawing_resume(display);
578+
}
569579
else if (event.type == ALLEGRO_EVENT_MOUSE_AXES) {
570580
ex.mouse_dx += event.mouse.dx;
571581
ex.mouse_dy += event.mouse.dy;
572582
}
573583

574-
if (redraw && al_is_event_queue_empty(queue)) {
584+
if (!halt_drawing && redraw && al_is_event_queue_empty(queue)) {
575585
draw_scene();
576586

577587
al_flip_display();

examples/ex_resize2.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ int main(int argc, char **argv)
2020
ALLEGRO_EVENT event;
2121
ALLEGRO_FONT *font;
2222
bool redraw;
23+
bool halt_drawing;
2324

2425
(void)argc;
2526
(void)argv;
@@ -31,6 +32,7 @@ int main(int argc, char **argv)
3132
al_init_image_addon();
3233
al_init_font_addon();
3334

35+
al_set_config_value(al_get_system_config(), "osx", "allow_live_resize", "false");
3436
al_set_new_display_flags(ALLEGRO_RESIZABLE |
3537
ALLEGRO_GENERATE_EXPOSE_EVENTS);
3638
display = al_create_display(640, 480);
@@ -51,8 +53,9 @@ int main(int argc, char **argv)
5153
al_register_event_source(queue, al_get_keyboard_event_source());
5254

5355
redraw = true;
56+
halt_drawing = false;
5457
while (true) {
55-
if (redraw && al_is_event_queue_empty(queue)) {
58+
if (!halt_drawing && redraw && al_is_event_queue_empty(queue)) {
5659
al_clear_to_color(al_map_rgb(255, 0, 0));
5760
al_draw_scaled_bitmap(bmp,
5861
0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp),
@@ -81,6 +84,14 @@ int main(int argc, char **argv)
8184
if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) {
8285
redraw = true;
8386
}
87+
if (event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING) {
88+
halt_drawing = true;
89+
al_acknowledge_drawing_halt(display);
90+
}
91+
if (event.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING) {
92+
halt_drawing = false;
93+
al_acknowledge_drawing_resume(display);
94+
}
8495
if (event.type == ALLEGRO_EVENT_KEY_DOWN &&
8596
event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
8697
break;

src/macosx/osxgl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ typedef struct ALLEGRO_DISPLAY_OSX_WIN {
3535
BOOL in_fullscreen;
3636
BOOL single_buffer;
3737
CGDisplayModeRef original_mode;
38+
BOOL send_halt_events;
39+
ALLEGRO_MUTEX *halt_mutex;
40+
ALLEGRO_COND *halt_cond;
41+
BOOL halt_event_acknowledged;
3842
/* For new (10.14+) vsyncing. */
3943
CVDisplayLinkRef display_link;
4044
ALLEGRO_MUTEX *flip_mutex;

src/macosx/osxgl.m

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ -(void) viewDidMoveToWindow;
235235
-(void) viewWillMoveToWindow: (NSWindow*) newWindow;
236236
-(void) mouseEntered: (NSEvent*) evt;
237237
-(void) mouseExited: (NSEvent*) evt;
238+
-(void) viewWillStartLiveResize;
238239
-(void) viewDidEndLiveResize;
239240
/* Window delegate methods */
240241
-(void) windowDidBecomeMain:(NSNotification*) notification;
@@ -519,6 +520,33 @@ -(void) viewDidChangeBackingProperties
519520
}
520521
#endif
521522

523+
-(void) viewWillStartLiveResize
524+
{
525+
ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr;
526+
ALLEGRO_EVENT_SOURCE *es = &dpy->parent.es;
527+
528+
if (dpy->send_halt_events) {
529+
al_lock_mutex(dpy->halt_mutex);
530+
dpy->halt_event_acknowledged = false;
531+
al_unlock_mutex(dpy->halt_mutex);
532+
533+
_al_event_source_lock(es);
534+
if (_al_event_source_needs_to_generate_event(es)) {
535+
ALLEGRO_EVENT event;
536+
event.display.type = ALLEGRO_EVENT_DISPLAY_HALT_DRAWING;
537+
event.display.timestamp = al_get_time();
538+
_al_event_source_emit_event(es, &event);
539+
}
540+
_al_event_source_unlock(es);
541+
542+
al_lock_mutex(dpy->halt_mutex);
543+
while (!dpy->halt_event_acknowledged) {
544+
al_wait_cond(dpy->halt_cond, dpy->halt_mutex);
545+
}
546+
al_unlock_mutex(dpy->halt_mutex);
547+
}
548+
}
549+
522550
-(void) viewDidEndLiveResize
523551
{
524552
[super viewDidEndLiveResize];
@@ -541,6 +569,11 @@ -(void) viewDidEndLiveResize
541569
event.display.height = NSHeight(content);
542570
_al_event_source_emit_event(es, &event);
543571
ALLEGRO_INFO("Window finished resizing %d x %d\n", event.display.width, event.display.height);
572+
573+
if (dpy->send_halt_events) {
574+
event.display.type = ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING;
575+
_al_event_source_emit_event(es, &event);
576+
}
544577
}
545578
_al_event_source_unlock(es);
546579
dpy->old_w = NSWidth(content);
@@ -1104,6 +1137,19 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
11041137
CVDisplayLinkStart(dpy->display_link);
11051138
}
11061139

1140+
static void init_halt_events(ALLEGRO_DISPLAY_OSX_WIN *dpy)
1141+
{
1142+
const char* value = al_get_config_value(al_get_system_config(), "osx", "allow_live_resize");
1143+
if (value && strcmp(value, "false") == 0) {
1144+
dpy->send_halt_events = true;
1145+
}
1146+
else {
1147+
dpy->send_halt_events = false;
1148+
}
1149+
dpy->halt_mutex = al_create_mutex();
1150+
dpy->halt_cond = al_create_cond();
1151+
}
1152+
11071153
/* create_display_fs:
11081154
* Create a fullscreen display - capture the display
11091155
*/
@@ -1141,6 +1187,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
11411187
_al_event_source_init(&display->es);
11421188
dpy->cursor = [[NSCursor arrowCursor] retain];
11431189
dpy->display_id = CGMainDisplayID();
1190+
init_halt_events(dpy);
11441191

11451192
/* Get display ID for the requested display */
11461193
if (al_get_new_display_adapter() > 0) {
@@ -1338,6 +1385,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
13381385
_al_event_source_init(&dpy->parent.es);
13391386
osx_change_cursor(dpy, [NSCursor arrowCursor]);
13401387
dpy->show_cursor = YES;
1388+
init_halt_events(dpy);
13411389

13421390
// Set up a pixel format to describe the mode we want.
13431391
osx_set_opengl_pixelformat_attributes(dpy);
@@ -1519,6 +1567,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
15191567
_al_event_source_init(&display->es);
15201568
_al_osx_change_cursor(dpy, [NSCursor arrowCursor]);
15211569
dpy->show_cursor = YES;
1570+
init_halt_events(dpy);
15221571

15231572
// Set up a pixel format to describe the mode we want.
15241573
osx_set_opengl_pixelformat_attributes(dpy);
@@ -1807,6 +1856,8 @@ static void destroy_display(ALLEGRO_DISPLAY* d)
18071856
_al_set_current_display_only(NULL);
18081857
}
18091858

1859+
al_destroy_cond(dpy->halt_cond);
1860+
al_destroy_mutex(dpy->halt_mutex);
18101861
if (dpy->flip_mutex) {
18111862
al_destroy_mutex(dpy->flip_mutex);
18121863
al_destroy_cond(dpy->flip_cond);
@@ -2497,6 +2548,15 @@ static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)
24972548
#endif
24982549
}
24992550

2551+
static void acknowledge_drawing_halt(ALLEGRO_DISPLAY *display)
2552+
{
2553+
ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display;
2554+
al_lock_mutex(dpy->halt_mutex);
2555+
dpy->halt_event_acknowledged = true;
2556+
al_signal_cond(dpy->halt_cond);
2557+
al_unlock_mutex(dpy->halt_mutex);
2558+
}
2559+
25002560
ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_win(void)
25012561
{
25022562
static ALLEGRO_DISPLAY_INTERFACE* vt = NULL;
@@ -2527,6 +2587,7 @@ static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)
25272587
vt->set_display_flag = set_display_flag;
25282588
vt->set_icons = set_icons;
25292589
vt->update_render_state = _al_ogl_update_render_state;
2590+
vt->acknowledge_drawing_halt = acknowledge_drawing_halt;
25302591
_al_ogl_add_drawing_functions(vt);
25312592
_al_osx_add_clipboard_functions(vt);
25322593
}

0 commit comments

Comments
 (0)