Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Reusing bitmaps after creating a new display

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Reusing bitmaps after creating a new display
torhu
Member #2,727
September 2002
avatar

I've implemented switching between fullscreen and windowed modes in my game. I destroy the old display, then create a new one. The next step is to reload the bitmaps, so I don't get FPS in the single digits. Just loading them from disk again works fine.

Then I tried using al_clone_bitmap() to speed up the process:

  for (i = 0; i < NUMBER_OF_BITMAPS; i++) {
    old = bitmaps[i];
    if (!(bitmaps[i] = al_clone_bitmap(old)))
      exit_message("Feil under konvertering av bitmaps til nytt display.");
    al_destroy_bitmap(old);
  }

After doing this, some of the bitmaps have been replaced by just white boxes. Any ideas?

Trent Gamblin
Member #261
April 2000
avatar

I'm not sure, but I'm going to be committing a change soon that should help. It adds an ALLEGRO_PRESERVE_TEXTURE flag (default off so nothing changes) that when used, will save your textures in system memory. Then in combination with ALLEGRO_CONVERT_BITMAP, you can simply destroy a display and create a new one and all the bitmaps are automatically converted.

torhu
Member #2,727
September 2002
avatar

Ok, cool. I was under the impression that reuploading of bitmaps to the video card would happen automatically with 5.1, but I guess that's not the case? I'm using 5.0.5, by the way.

Trent Gamblin
Member #261
April 2000
avatar

Yeah, I guess if your scenario is like... user presses button, toggle fullscreen, then you don't really need the ALLEGRO_PRESERVE_TEXTURE flag, in which case your code should work, provided that you are not cloning the bitmaps after destroying the display... but then they should be converted to memory bitmaps so I don't know why it isn't working. The use case for the ALLEGRO_PRESERVE_TEXTURE flag is when the bitmaps can become invalidated at any time, such as hotplugging monitors.

Short answer: not sure, can you post more code?

torhu
Member #2,727
September 2002
avatar

This is the code that does the switching, and creates the lovely white boxes. I tried waiting until after I created the new display with destroying the old one, but that didn't work. When switching from fullscreen to windowed, I got a window of the correct size, but that had no title bar, and was glued to the top left of the screen. Like the old and the new display conflicted somehow.

#SelectExpand
1void toggle_fullscreen_mode(ALLEGRO_EVENT_QUEUE* event_queue) 2{ 3 int i; 4 ALLEGRO_BITMAP *old; 5 bool window = al_get_new_display_flags() & ALLEGRO_WINDOWED; 6 7 al_destroy_display(display); 8 al_set_new_display_flags(window ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED); 9 display = al_create_display(GFX_WIDTH, GFX_HEIGHT); 10 11 /* if it didn't work, go back to the previous mode */ 12 if (!display) { 13 al_set_new_display_flags(window ? ALLEGRO_WINDOWED : ALLEGRO_FULLSCREEN); 14 display = al_create_display(GFX_WIDTH, GFX_HEIGHT); 15 } 16 assert(display); 17 18 /* redo some of the setup that was originally done by init(), main(), and 19 graphics_init() */ 20 al_hide_mouse_cursor(display); 21 al_set_window_title(display, WINDOW_TITLE); 22 al_register_event_source(event_queue, al_get_display_event_source(display)); 23 if (!(font = al_grab_font_from_bitmap(font_bitmap, 4, font_ranges))) 24 exit_message("Feil under konvertering av font til nytt display."); 25 26 /* have to reupload all bitmaps to the graphics card */ 27 for (i = 0; i < NUMBER_OF_BITMAPS; i++) { 28 old = bitmaps[i]; 29 if (!(bitmaps[i] = al_clone_bitmap(old))) 30 exit_message("Feil under konvertering av bitmaps til nytt display."); 31 al_destroy_bitmap(old); 32 } 33 backgr = bitmaps[BACKGR_IMAGE]; 34}

Trent Gamblin
Member #261
April 2000
avatar

Does 5.0.5 have the bitmap auto-conversion that Elias and Matthew added? If so it seems like it's not working. In fact, some part of me thinks that I fixed a bug in that code while doing the ALLEGRO_PRESERVE_TEXTURE code... actually I'm almost sure of it. I can send you a patch to that file so you can look for changes I made, if you want, but you'll have to just ignore the big chunks I added... the only thing holding this patch up from being committed to 5.1 is that there is a race condition I couldn't pin down and put in an al_rest(1) for the time being (in the iphone display creation code).

torhu
Member #2,727
September 2002
avatar

I'm not sure if the auto-conversion is present in 5.0.5 or not. I can't find it in the docs. Working around it by loading the files from disk again works fine at the moment, since I have only 30 relatively small bitmaps.

Matthew Leverton
Supreme Loser
January 1999
avatar

The auto conversion stuff is not in 5.0. It needs more testing before that happens.

And before you commit anything that alters its behavior, you should probably post on AD first just to make sure the bug isn't actually a feature. Elias wrote the code, so I don't know it is implemented, but I know how it's supposed to work.

Trent Gamblin
Member #261
April 2000
avatar

Ok, I looked at it and I didn't actually change anything except adding a conditional branch. But it shouldn't matter AFAIK, destroying a display has always been supposed to convert to memory bitmaps. One quick fix might be to clone the bitmaps before destroying the display (save them in an array or some such, then copy them back.) Sounds like a hack though. This really sounds like the problems I was having with hot-plugging displays, except my textures were all black or had some noise in them. Are you using D3D or OpenGL?

torhu
Member #2,727
September 2002
avatar

Looks I'm using Direct3D, I checked the log file. I tried cloning all the bitmaps (with al_clone_bitmap) after calling al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP), before destroying the old display. Then I called al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP) after destroying the old and creating the new display, and then cloned all bitmaps again. But it just crashed.

Trent Gamblin
Member #261
April 2000
avatar

Did you destroy the video bitmaps after cloning them, before destroying the display?

torhu
Member #2,727
September 2002
avatar

Yes.

EDIT:
It did actually work, I just had a bug in my code. Sorry about that.

This code works:

#SelectExpand
1void toggle_fullscreen_mode(ALLEGRO_EVENT_QUEUE* event_queue) 2{ 3 int i; 4 ALLEGRO_BITMAP *old; 5 ALLEGRO_BITMAP *backup[NUMBER_OF_BITMAPS]; 6 bool window = al_get_new_display_flags() & ALLEGRO_WINDOWED; 7 8 al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); 9 for (i = 0; i < NUMBER_OF_BITMAPS; i++) { 10 old = bitmaps[i]; 11 if (!(backup[i] = al_clone_bitmap(old))) 12 exit_message("Feil under kopiering av bitmaps før fullskjermsbyte."); 13 al_destroy_bitmap(old); 14 } 15 16 al_destroy_display(display); 17 al_set_new_display_flags(window ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED); 18 display = al_create_display(GFX_WIDTH, GFX_HEIGHT); 19 20 /* if it didn't work, go back to the previous mode */ 21 if (!display) { 22 al_set_new_display_flags(window ? ALLEGRO_WINDOWED : ALLEGRO_FULLSCREEN); 23 display = al_create_display(GFX_WIDTH, GFX_HEIGHT); 24 } 25 assert(display); 26 27 /* redo some of the setup that was originally done by init(), main(), and 28 graphics_init() */ 29 al_hide_mouse_cursor(display); 30 al_set_window_title(display, WINDOW_TITLE); 31 al_register_event_source(event_queue, al_get_display_event_source(display)); 32 if (!(font = al_grab_font_from_bitmap(font_bitmap, 4, font_ranges))) 33 exit_message("Feil under konvertering av font til nytt display."); 34 35 /* have to reupload all bitmaps to the graphics card */ 36 al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); 37 for (i = 0; i < NUMBER_OF_BITMAPS; i++) { 38 old = backup[i]; 39 if (!(bitmaps[i] = al_clone_bitmap(old))) 40 exit_message("Feil under konvertering av bitmaps til nytt display."); 41 al_destroy_bitmap(old); 42 } 43 backgr = bitmaps[BACKGR_IMAGE]; 44}

Trent Gamblin
Member #261
April 2000
avatar

So I wonder if the conversion is happening too late in the d3d driver..

Matthew Leverton
Supreme Loser
January 1999
avatar

But it shouldn't matter AFAIK, destroying a display has always been supposed to convert to memory bitmaps.

Reading back through the discussion, it looks like no definitive answer was ever given regarding that.

There were three things suggested:

  1. Only bitmaps marked as CONVERT would be downgraded. Other video bitmaps would be invalidated (0x0 zombies).


  2. All video bitmaps would be downgraded to memory and implicitly tagged as auto-convert


  3. All video bitmaps would be downgraded to memory, but the convert tag would not be added. (Thus video bitmaps which were not explicitly tagged would be stuck as memory.)

I'm not sure which Elias implemented. I would prefer the first option because it is the most consistent: Allegro only tries to manage bitmaps marked with the auto-convert tag.

Trent Gamblin
Member #261
April 2000
avatar

Yes, I was talking about before the AUTO_CONVERT flag was introduced. At that time there was no conversion except for destroy display->displays video bitmaps converted to memory, and all platforms did it. I'm not sure either which of those 3 is used now, but I guess it could be relevant. I'd have to ask Elias which is used, which might tell us why the first code snippet of torhu's didn't work.

Elias
Member #358
May 2000

I think destroying a display always converts all display bitmaps to memory bitmaps (if it is the last display sharing the bitmaps). Both in 5.0 and 5.1. The reason was to never have zombie bitmaps I think. I'm all for changing it, so that a VIDEO bitmap would never be a MEMORY bitmap unless it is set to auto convert (which it would be by default).

The drawback is that we'd have to introduce the concept of zombie bitmaps, i.e. bitmaps which cannot be drawn at all, not even as memory bitmaps. The only valid operation on them would be destroying them.

--
"Either help out or stop whining" - Evert

torhu
Member #2,727
September 2002
avatar

When I tried just destroying the old display and creating a new one, all the bitmaps seemed to be ok. So the automatic conversion to memory bitmaps works. It's when I cloned them after creating the new display that some of them turned into white boxes.

EDIT:
Nevermind, I just tried it and got white boxes anyway.

Matthew Leverton
Supreme Loser
January 1999
avatar

Elias said:

The drawback is that we'd have to introduce the concept of zombie bitmaps, i.e. bitmaps which cannot be drawn at all, not even as memory bitmaps. The only valid operation on them would be destroying them.

If video bitmaps were to be invalidated, Peter's comment was:

Quote:

They should be 0x0 bitmaps without any data associated.
We should allow al_create_bitmap to create 0x0 bitmaps anyway

I'm not sure if he meant that those bitmaps should be able to be drawn (null op) or not.

Regardless of whether they can or not, I still prefer it (zombie bitmaps) because I think it makes it easier to document, explain, and understand when conversions happen: if you don't set the conversion flag, the bitmap will never be converted, and if you destroy the last display, the bitmap is lost.

torhu
Member #2,727
September 2002
avatar

The al_clone_bitmap() call in the first loop in my function has a tendency to return NULL. Is there a limit to how many bitmaps I can create or something? I destroy the old ones, but maybe there's some resource that gets depleted.

Thomas Fjellstrom
Member #476
June 2000
avatar

Video Bitmaps live in the video card memory, if you run out of that, it tends to fail.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

torhu
Member #2,727
September 2002
avatar

Yes, but the video memory should be freed when I call al_destroy_bitmap, right?

Thomas Fjellstrom
Member #476
June 2000
avatar

yeah, but if you just create too many, then you have no recourse.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

torhu
Member #2,727
September 2002
avatar

I think I have no more than 32 bitmaps at any given time, so it's not the number of bitmaps that the problem.

Thomas Fjellstrom
Member #476
June 2000
avatar

It's not really the number that matters, but the amount of video memory they use up, and how much free video memory you have.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Arthur Kalliokoski
Second in Command
February 2005
avatar

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

 1   2 


Go to: