Description
So I have this user report where closing the program on Ubuntu ends up hanging while destroying the display. (I unfortunately cannot reproduce on Mint, and don't have Ubuntu).
The root cause is probably some bad mix of other atexit handlers, since calling the allegro shutdown function directly (and then exiting) prevents any hanging.
ZQuestClassic/ZQuestClassic#975 (comment)
- glReadPixels(x, gl_y, w, h, ****** hangs on opengl read
get_glformat(format, 2),
get_glformat(format, 1),
ogl_bitmap->lock_buffer);
- ok = ogl_lock_region_nonbb_readwrite_fbo(bitmap, ogl_bitmap,
x, gl_y, w, h, format);
- ok = ogl_lock_region_nonbb_readwrite(bitmap, ogl_bitmap,
x, gl_y, w, h, format, &restore_fbo);
- lr = bitmap->vt->lock_region(bitmap, xc, yc, wc, hc, format, flags);
- return al_lock_bitmap_region(bitmap, 0, 0, bitmap->w, bitmap->h, format, flags);
- if (!(src_region = al_lock_bitmap(src, lock_format, ALLEGRO_LOCK_READONLY)))
- if (!transfer_bitmap_data(bitmap, clone)) {
- clone = al_clone_bitmap(bitmap);
- al_convert_bitmap(bitmap);
- _al_convert_to_memory_bitmap(b);
- convert_display_bitmaps_to_memory_bitmap(d); ******* convert to memory bitmaps
- display->vt->destroy_display(display); ******* destroy display
- al_destroy_display(_a5_display);
- _a5_destroy_screen();
- gfx_driver->exit(screen);
- return _set_gfx_mode(card, w, h, v_w, v_h, TRUE);
- set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
- (*func)();
- allegro_exit();
Please excuse the mix of allegro4/5 here. This stack is just the atexit handler of allegro4 shutting down its gfx driver, which involves destroying the allegro 5 display. The application has created bitmaps with the ALLEGRO_MEMORY_BITMAP
flag set, so it tries to preserve them during the shutdown process. For a reason unknown to me, the program hangs while locking the opengl bitmap. FWIW, this behavior has never been reported for Windows or OSX.
I have no idea why locking the bitmap would be hanging, so short of solving the root cause, I looked for a workaround: converting these bitmaps to memory bitmaps is a peculiar thing to do on shutdown, so I wondered how I could best suppress this behavior for the case where the program is shutting down. I considered iterating all the bitmaps and unsetting the ALLEGRO_MEMORY_BITMAP
flag, but there is no public interface to get all the bitmaps (and my program does not store them anywhere).
I see that the ALLEGRO_DISPLAY
struct has a bitmaps
member, so my ask is: can we expose this in a public method?