liballeg / allegro5

The official Allegro 5 git repository. Pull requests welcome!
https://liballeg.org
Other
1.84k stars 281 forks source link

Ubuntu hangs on `convert_display_bitmaps_to_memory_bitmap` when destroying display / feature request for getting all bitmaps #1575

Open connorjclark opened 3 weeks ago

connorjclark commented 3 weeks ago

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.

https://github.com/ZQuestClassic/ZQuestClassic/pull/975#issuecomment-2308641432

 - 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?

SiegeLord commented 3 weeks ago

Perhaps related to https://github.com/liballeg/allegro5/issues/1549 ? I don't have better suggestions than shutting down Allegro manually.

I see that the ALLEGRO_DISPLAY struct has a bitmaps member, so my ask is: can we expose this in a public method?

Can you explain what you want this for?

SiegeLord commented 3 weeks ago

Oh I see, I read what you said more closely... let me think.