Skip to content

Commit 15c37bf

Browse files
SiegeLordExSiegeLord
authored andcommitted
Add a workaround for liballeg#1350
Elias investigated the issue in liballeg#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 88ba729 commit 15c37bf

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
@@ -34,6 +34,10 @@ typedef struct ALLEGRO_DISPLAY_OSX_WIN {
3434
BOOL in_fullscreen;
3535
BOOL single_buffer;
3636
CGDisplayModeRef original_mode;
37+
BOOL send_halt_events;
38+
ALLEGRO_MUTEX *halt_mutex;
39+
ALLEGRO_COND *halt_cond;
40+
BOOL halt_event_acknowledged;
3741
/* For new (10.14+) vsyncing. */
3842
CVDisplayLinkRef display_link;
3943
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
}
@@ -1102,6 +1135,19 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
11021135
CVDisplayLinkStart(dpy->display_link);
11031136
}
11041137

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

11431190
/* Get display ID for the requested display */
11441191
if (al_get_new_display_adapter() > 0) {
@@ -1334,6 +1381,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
13341381
_al_event_source_init(&dpy->parent.es);
13351382
osx_change_cursor(dpy, [NSCursor arrowCursor]);
13361383
dpy->show_cursor = YES;
1384+
init_halt_events(dpy);
13371385

13381386
// Set up a pixel format to describe the mode we want.
13391387
osx_set_opengl_pixelformat_attributes(dpy);
@@ -1513,6 +1561,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
15131561
_al_event_source_init(&display->es);
15141562
_al_osx_change_cursor(dpy, [NSCursor arrowCursor]);
15151563
dpy->show_cursor = YES;
1564+
init_halt_events(dpy);
15161565

15171566
// Set up a pixel format to describe the mode we want.
15181567
osx_set_opengl_pixelformat_attributes(dpy);
@@ -1799,6 +1848,8 @@ static void destroy_display(ALLEGRO_DISPLAY* d)
17991848
_al_set_current_display_only(NULL);
18001849
}
18011850

1851+
al_destroy_cond(dpy->halt_cond);
1852+
al_destroy_mutex(dpy->halt_mutex);
18021853
if (dpy->flip_mutex) {
18031854
al_destroy_mutex(dpy->flip_mutex);
18041855
al_destroy_cond(dpy->flip_cond);
@@ -2489,6 +2540,15 @@ static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)
24892540
#endif
24902541
}
24912542

2543+
static void acknowledge_drawing_halt(ALLEGRO_DISPLAY *display)
2544+
{
2545+
ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display;
2546+
al_lock_mutex(dpy->halt_mutex);
2547+
dpy->halt_event_acknowledged = true;
2548+
al_signal_cond(dpy->halt_cond);
2549+
al_unlock_mutex(dpy->halt_mutex);
2550+
}
2551+
24922552
ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_win(void)
24932553
{
24942554
static ALLEGRO_DISPLAY_INTERFACE* vt = NULL;
@@ -2519,6 +2579,7 @@ static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)
25192579
vt->set_display_flag = set_display_flag;
25202580
vt->set_icons = set_icons;
25212581
vt->update_render_state = _al_ogl_update_render_state;
2582+
vt->acknowledge_drawing_halt = acknowledge_drawing_halt;
25222583
_al_ogl_add_drawing_functions(vt);
25232584
_al_osx_add_clipboard_functions(vt);
25242585
}

0 commit comments

Comments
 (0)