video and system bitmaps crashing
Neil Walker

Hello,
I'm having problems with my system crashing when I call destroy_bitmap() when the bitmap is a system or video bitmap, but not when it is a memory bitmap. This is roughly what I am doing, I'm in 32bpp and my bitmaps are 32bpp, allegro is fully initialised and ready to go:

void someclass::LoadFunction()
{
 BITMAP* tmp;
 this->Image=load_bmp(filename,NULL);
 if(WantSystemBitmap)
 {
  tmp=create_system_bitmap(Image->w,Image->h);
  blit(Image,tmp,0,0,0,0,Image->w,Image->h);
  if(tmp)
  {
    destroy_bitmap(Image);
    Image=tmp;
  }
 }

Everything works fine and the graphic is displayed in the game.

4. On quitting I do this (allegro is still initialised, so no problems there).
if(Image) destroy_bitmap(Image);

Anyone got a clue as to what could be causing it to crash? the bitmap definitely exists on the call to destroy and can still be viewed ok, it's memory address is the same as when it was initially created. It has no sub-bitmaps, etc. It only crashes when it is a system bitmap, so I guess it must be something to do with the creation of the bitmap, but I can't see a fault.

Synapse Jumps

Your problem is not destroying them. You're setting Image to a deleted pointer. You need to do this:

1void someclass::LoadFunction()
2{
3 BITMAP* tmp=load_bmp(filename,NULL);
4 if(tmp){
5 if(WantSystemBitmap)
6 {
7 this->Image=create_system_bitmap(tmp->w,tmp->h);
8 blit(tmp,this->Image,0,0,0,0,Image->w,Image->h);
9 destroy_bitmap(tmp);
10 else
11 {
12 this->Image=create_bitmap(tmp->w,tmp->h);
13 blit(tmp,this->Image,0,0,0,0,Image->w,Image->h);
14 destroy_bitmap(tmp);
15 }
16 }
17 }

That should do 100% better

EDIT: On second look, you're not setting it to a NULL pointer, but try this way anyways. It should work better.
EDIT AGAIN: Also, try calling release_bitmap(someclass->Image); brefore deleting it? Maybe? I dunno. That might help shrugs

Neil Walker

I'll try it, but I don't see how it would work any better.

I'm getting lots of wierd things happening. If I display the same bitmap but have enabled paging/triple buffering these graphics all point to the wrong images. It's as if creating my 2 or 3 video bitmaps for the screen buffers is affecting system/video bitmaps I create from the above method in my first post, in that instead of pointing to the correct image they are pointing to another image.

Neil.

Thomas Harte
Quote:

It's as if creating my 2 or 3 video bitmaps for the screen buffers is affecting system/video bitmaps I create from the above method in my first post, in that instead of pointing to the correct image they are pointing to another image.

Which order are you allocating things in? Of course some freaky stuff has to be done to support Allegro's "unique" screen update system in DirectX and there seems to be a lot going on that isn't documented in the normal readme files. But to directly copy a large chunk of text from the top of src/win/wddbmp.c:

Allegro developers said:

The video bitmap allocation scheme works as follows:
* - the screen is allocated as a single DirectDraw surface (primary or overlay,
* depending on the driver) at startup,
* - the first video bitmap reuses the DirectDraw surface of the screen which is
* then assigned to flipping_page[0],
* - the second video bitmap allocates flipping_page[1] and uses it as its
* DirectDraw surface; it also destroys the single surface pointed to by
* flipping_page[0] and creates a DirectDraw flipping chain whose frontbuffer
* is connected back to flipping_page[0] and backbuffer to flipping_page[1],
* - the third video bitmap allocates flipping_page[2] and uses it as its
* DirectDraw surface; it also destroys the flipping chain pointed to by
* flipping_page[0] and flipping_page[1] and creates a new flipping chain
* whose frontbuffer is connected back to flipping_page[0], first backbuffer
* back to flipping_page[1] and second backbuffer to flipping_page[2].
*
* When a video bitmap is to be destroyed, the flipping chain (if it exists) is
* destroyed and recreated with one less backbuffer, and its surfaces are assigned
* back to the flipping_page[] array in order. If the video bitmap is not attached
* to the surface that was just destroyed, its surface is assigned to the video
* bitmap parent of the just destroyed surface.
*
* After triple buffering setup:
*
* screen video_bmp[0] video_bmp[1] video_bmp[2]
* \ | | |
* \ | | |
* page_flipping[0] page_flipping[1] page_flipping[2]
* (frontbuffer)-----(backbuffer1)-----(backbuffer2)
*
* After request_video_bitmap(video_bmp[1]):
*
* screen video_bmp[0] video_bmp[1] video_bmp[2]
* \ / |
* \ /\ |
* page_flipping[0] page_flipping[1] page_flipping[2]
* (frontbuffer)-----(backbuffer1)-----(backbuffer2)
*
* This ensures that every video bitmap keeps track of the actual part of the
* video memory it represents (see the documentation of DirectDrawSurface::Flip).

I'm not 100% sure what to make of all this, but it definitely seems you should allocate your video surfaces that may become the frame buffer first...

Neil Walker

I think (I'll look at the code tonight), but I'm first creating 3 (or 2 for paged) video bitmaps to cover the screen bitmaps, then I'm creating the smaller bitmaps from the memory bitmaps.

Thomas, was my code right or should I be doing it the way Synaps Jump recommended, as I can't see anything wrong with my code.

I should say, that when I'm getting errors with the video/system bitmaps seemingly looking at the wrong bitmap (though memory bitmaps work), only happens when I'm using sub-bitmaps of video or system bitmaps.

I can let you see my code if you wish, but it's spread over a couple of files :)

One final nail in my video/system bitmap is when I try and delete my surface bitmap, e.g. destroy_bitmap(page[0]) it crashes with a pointer error, but I've checked and I haven't got the screen locked for drawing and just a few seconds before this my game loop was showing the video pages fine.

Now, another problem I'm having that I noticed on a very simple example that just used textprintf_ex() was there was lots of white noise in blocks over my screen when I use video bitmaps for the surface. I'm simply using the code as shown in the allegro help file.

Thomas Harte

I can't see any real difference in validity between the two snippets of code in this thread. I have vague memories of receiving crashes on destroy_bitmap for video bitmaps when I felt I shouldn't many years ago, but I don't think Allegro.cc was around at the time and I don't think I submited a bug report. OS X Allegro doesn't support video or system bitmaps so I've had no real experience lately.

Andrei Ellman
Thomas Harte said:

I have vague memories of receiving crashes on destroy_bitmap for video bitmaps when I felt I shouldn't many years ago

Was this perchance related to using the Allegro mousecursor and not calling show_mouse(NULL) before destroying the bitmaps? Only now (post 4.2.0) has it been mentioned in the docs.

AE.

Neil Walker

Fixed a couple of things! which I guess might serve as something to remember for others!

1. my system was crashing at the end because I was calling set_gfx_mode(GFX_TEXT...) before I deleted my video bitmaps

2. I was experiencing white noise because I'd forgotton to clear the bitmaps prior to using them (memory were ok)

3. I was sometimes not seeing text because it was written to the screen object and I guess when you use paging/triple you shouldn't be doing this.

As for the code Thomas mentioned:

Quote:

  • - the first video bitmap reuses the DirectDraw surface of the screen which is then assigned to flipping_page[0],

  • When a video bitmap is to be destroyed, the flipping chain (if it exists) is

  • destroyed

I don't understand this, as it sounds like video_bitmaps are only used for screen buffers and are allocated to flipping_page[x]. What about normal bitmaps that you want to simply store in video memory?

Evert
Quote:

1. my system was crashing at the end because I was calling set_gfx_mode(GFX_TEXT...) before I deleted my video bitmaps

Indeed!

Quote:

1.10.7 create_video_bitmap
--------------------------
[...]
Returns a pointer to the bitmap on success, or NULL if you have
run out of video ram. Remember to destroy this bitmap before any subsequent call to set_gfx_mode().

Quote:

2. I was experiencing white noise because I'd forgotton to clear the bitmaps prior to using them (memory were ok)

In that case, your malloc() clears the returned memory. This isn't guarenteed and you can't count on it, even for memory bitmaps. Always clear bitmaps you just allocated.

Quote:

3. I was sometimes not seeing text because it was written to the screen object and I guess when you use paging/triple you shouldn't be doing this.

Correct. You draw onto the pages you allocate. This is mentioned in the docs, but I can understand if you missed it:

Quote:

1.10.7 create_video_bitmap
--------------------------

BITMAP *create_video_bitmap(int width, int height);
Allocates a video memory bitmap of the specified size. This can be
used to allocate offscreen video memory for storing source
graphics ready for a hardware accelerated blitting operation, or
to create multiple video memory pages which can then be displayed
by calling show_video_bitmap(). Read the introduction of this
chapter for a comparison with other types of bitmaps and other
specific details.

Warning: video memory bitmaps are usually allocated from the same space as the screen bitmap, so they may overlap with it; it is therefore not a good idea to use the global screen at the same time as any surfaces returned by this function.

Neil Walker

The reason for all these crap coding errors was that my framework is a large beast now and triple/paging was put in at the end so I had to go through all my code and check whether all the stuff that accessed the current buffer was valid code and/or had to change, and as this is the first time I've used system/video bitmaps and paging/triple buffering it took a few re-reads of the code to find them all as the code by itself looks ok, just in the context of video buffers isn't.

But yes, I did read those bits, they are the reason why I fixed my code. God bless the Allegro manual ;)

I've only my mysterious switching sub-bitmaps when using video/system memory as the parent to look at now :)

Evert

Well, what I sortof meant to say was, if you think there are things that can be improved in the manual to make some of these caveats more obvious, feel free to say so.

Neil Walker

Not really, the manual is a reference guide and serves it's purpose brilliantly.

Maybe if someone wrote a programming guide to go with it, that would be a different story, as that would tie the stuff together.

Neil.

Thread #557972. Printed from Allegro.cc