Skip to content

Commit

Permalink
Add a workaround for liballeg#1350
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
SiegeLordEx authored and SiegeLord committed May 21, 2023
1 parent 88ba729 commit 15c37bf
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 2 deletions.
9 changes: 9 additions & 0 deletions allegro5.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,15 @@ max_page_size = 0
# Uncomment if you want only the characters in the cache_text entry to ever be drawn
# skip_cache_misses = true

[osx]

# If set to false, then Allegro will send ALLEGRO_EVENT_DISPLAY_HALT_DRAWING
# and ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING events when the user resizes a
# window. Drawing while resizing ("live resizing") has historically been buggy,
# so setting this to false allows you to opt out of this behavior and detect
# when the resize happens.
allow_live_resize = true

[compatibility]

# Prior to 5.2.4 on Windows you had to manually resize the display when
Expand Down
1 change: 1 addition & 0 deletions demos/skater/src/framework.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ void run_framework(void)

case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING:
background_mode = false;
al_acknowledge_drawing_resume(screen);
break;

case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:
Expand Down
12 changes: 11 additions & 1 deletion examples/ex_camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ int main(int argc, char **argv)
ALLEGRO_TIMER *timer;
ALLEGRO_EVENT_QUEUE *queue;
int redraw = 0;
bool halt_drawing = false;
char const *skybox_name = NULL;

if (argc > 1) {
Expand All @@ -489,6 +490,7 @@ int main(int argc, char **argv)
al_install_keyboard();
al_install_mouse();

al_set_config_value(al_get_system_config(), "osx", "allow_live_resize", "false");
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST);
Expand Down Expand Up @@ -566,12 +568,20 @@ int main(int argc, char **argv)
else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
ex.button[event.mouse.button] = 0;
}
else if (event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING) {
halt_drawing = true;
al_acknowledge_drawing_halt(display);
}
else if (event.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING) {
halt_drawing = false;
al_acknowledge_drawing_resume(display);
}
else if (event.type == ALLEGRO_EVENT_MOUSE_AXES) {
ex.mouse_dx += event.mouse.dx;
ex.mouse_dy += event.mouse.dy;
}

if (redraw && al_is_event_queue_empty(queue)) {
if (!halt_drawing && redraw && al_is_event_queue_empty(queue)) {
draw_scene();

al_flip_display();
Expand Down
13 changes: 12 additions & 1 deletion examples/ex_resize2.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ int main(int argc, char **argv)
ALLEGRO_EVENT event;
ALLEGRO_FONT *font;
bool redraw;
bool halt_drawing;

(void)argc;
(void)argv;
Expand All @@ -31,6 +32,7 @@ int main(int argc, char **argv)
al_init_image_addon();
al_init_font_addon();

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

redraw = true;
halt_drawing = false;
while (true) {
if (redraw && al_is_event_queue_empty(queue)) {
if (!halt_drawing && redraw && al_is_event_queue_empty(queue)) {
al_clear_to_color(al_map_rgb(255, 0, 0));
al_draw_scaled_bitmap(bmp,
0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp),
Expand Down Expand Up @@ -81,6 +84,14 @@ int main(int argc, char **argv)
if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) {
redraw = true;
}
if (event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING) {
halt_drawing = true;
al_acknowledge_drawing_halt(display);
}
if (event.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING) {
halt_drawing = false;
al_acknowledge_drawing_resume(display);
}
if (event.type == ALLEGRO_EVENT_KEY_DOWN &&
event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
break;
Expand Down
4 changes: 4 additions & 0 deletions src/macosx/osxgl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ typedef struct ALLEGRO_DISPLAY_OSX_WIN {
BOOL in_fullscreen;
BOOL single_buffer;
CGDisplayModeRef original_mode;
BOOL send_halt_events;
ALLEGRO_MUTEX *halt_mutex;
ALLEGRO_COND *halt_cond;
BOOL halt_event_acknowledged;
/* For new (10.14+) vsyncing. */
CVDisplayLinkRef display_link;
ALLEGRO_MUTEX *flip_mutex;
Expand Down
61 changes: 61 additions & 0 deletions src/macosx/osxgl.m
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ -(void) viewDidMoveToWindow;
-(void) viewWillMoveToWindow: (NSWindow*) newWindow;
-(void) mouseEntered: (NSEvent*) evt;
-(void) mouseExited: (NSEvent*) evt;
-(void) viewWillStartLiveResize;
-(void) viewDidEndLiveResize;
/* Window delegate methods */
-(void) windowDidBecomeMain:(NSNotification*) notification;
Expand Down Expand Up @@ -519,6 +520,33 @@ -(void) viewDidChangeBackingProperties
}
#endif

-(void) viewWillStartLiveResize
{
ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr;
ALLEGRO_EVENT_SOURCE *es = &dpy->parent.es;

if (dpy->send_halt_events) {
al_lock_mutex(dpy->halt_mutex);
dpy->halt_event_acknowledged = false;
al_unlock_mutex(dpy->halt_mutex);

_al_event_source_lock(es);
if (_al_event_source_needs_to_generate_event(es)) {
ALLEGRO_EVENT event;
event.display.type = ALLEGRO_EVENT_DISPLAY_HALT_DRAWING;
event.display.timestamp = al_get_time();
_al_event_source_emit_event(es, &event);
}
_al_event_source_unlock(es);

al_lock_mutex(dpy->halt_mutex);
while (!dpy->halt_event_acknowledged) {
al_wait_cond(dpy->halt_cond, dpy->halt_mutex);
}
al_unlock_mutex(dpy->halt_mutex);
}
}

-(void) viewDidEndLiveResize
{
[super viewDidEndLiveResize];
Expand All @@ -541,6 +569,11 @@ -(void) viewDidEndLiveResize
event.display.height = NSHeight(content);
_al_event_source_emit_event(es, &event);
ALLEGRO_INFO("Window finished resizing %d x %d\n", event.display.width, event.display.height);

if (dpy->send_halt_events) {
event.display.type = ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING;
_al_event_source_emit_event(es, &event);
}
}
_al_event_source_unlock(es);
}
Expand Down Expand Up @@ -1102,6 +1135,19 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
CVDisplayLinkStart(dpy->display_link);
}

static void init_halt_events(ALLEGRO_DISPLAY_OSX_WIN *dpy)
{
const char* value = al_get_config_value(al_get_system_config(), "osx", "allow_live_resize");
if (value && strcmp(value, "false") == 0) {
dpy->send_halt_events = true;
}
else {
dpy->send_halt_events = false;
}
dpy->halt_mutex = al_create_mutex();
dpy->halt_cond = al_create_cond();
}

/* create_display_fs:
* Create a fullscreen display - capture the display
*/
Expand Down Expand Up @@ -1139,6 +1185,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
_al_event_source_init(&display->es);
dpy->cursor = [[NSCursor arrowCursor] retain];
dpy->display_id = CGMainDisplayID();
init_halt_events(dpy);

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

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

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

al_destroy_cond(dpy->halt_cond);
al_destroy_mutex(dpy->halt_mutex);
if (dpy->flip_mutex) {
al_destroy_mutex(dpy->flip_mutex);
al_destroy_cond(dpy->flip_cond);
Expand Down Expand Up @@ -2489,6 +2540,15 @@ static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)
#endif
}

static void acknowledge_drawing_halt(ALLEGRO_DISPLAY *display)
{
ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display;
al_lock_mutex(dpy->halt_mutex);
dpy->halt_event_acknowledged = true;
al_signal_cond(dpy->halt_cond);
al_unlock_mutex(dpy->halt_mutex);
}

ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_win(void)
{
static ALLEGRO_DISPLAY_INTERFACE* vt = NULL;
Expand Down Expand Up @@ -2519,6 +2579,7 @@ static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)
vt->set_display_flag = set_display_flag;
vt->set_icons = set_icons;
vt->update_render_state = _al_ogl_update_render_state;
vt->acknowledge_drawing_halt = acknowledge_drawing_halt;
_al_ogl_add_drawing_functions(vt);
_al_osx_add_clipboard_functions(vt);
}
Expand Down

0 comments on commit 15c37bf

Please sign in to comment.