English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. C/C++ (https://eab.abime.net/forumdisplay.php?f=118)
-   -   Crash on FreeBitMap when depth > 1? (https://eab.abime.net/showthread.php?t=107148)

Warty 29 May 2021 05:39

Crash on FreeBitMap when depth > 1?
 
3 Attachment(s)
This problem has been driving me nuts for a while, but I want to get back into my program and finish it up (for a given definition of "finish") now that 3.2 is out.

Here's what's happening:
- I open a screen with interleaved bitmap mode (SA_Interleaved=true)
- I load IFFs from deluxepaint into bitmaps
- I use those as "icons" on the screen, and user can drag them around.
- On app shutdown, I go through all my "icon" objects, and free them.
- In freeing icons, I call FreeBitMap
- if I am in depth 1, it is fine. no crash.
- if depth is 3, it crashes every single time.

Looking at the bitmap structures in Bebbo's GCC toolchain debugger, they look the way I would expect them to:
- the single depth bitmap has one plane.
- the depth 3 interleaved bitmap has 3 planes, and they start offset from each by one word.

My guess is that freebitmap frees the first plane, and that hoses the 2nd and 3rd plane, so they cause a crash, but I'm just guessing. And that seems weird to me, that the system wouldn't know what to do with interleaved bitmaps. So it's probably something I'm doing that I don't know I'm doing, but what?

Here's is how I'm creating the bitmaps:
Code:

        // attempt to load and process the icon and mask data

        // allocate a new bitmap
        the_icon->bitmap_ = AllocBitMap(pixel_width, pixel_height, the_depth, BMF_DISPLAYABLE|BMF_INTERLEAVED, NULL);

        if (the_icon->bitmap_== NULL)
        {
                LOG_ERR(("Icon_New %d: Could not allocate space for a copy of the icon bitmap", __LINE__));
                goto error;
        }

        // initialize the bitmap. requirement per autodocs:
                        // Initialize various elements in the BitMap structure to
                        // correctly reflect depth, width, and height.
                        // Must be used before use of BitMap in other graphics calls.
        InitBitMap( the_icon->bitmap_, the_depth, pixel_width* the_depth, pixel_height );

        // pass pointer to our new bitmap to routine that will read IFF bitmap and blit into ours
        if ( (General_GetBitMapFromIFFImage(the_icon->bitmap_path_, &the_icon->bitmap_, pixel_width, pixel_height)) == false)

In General_GetBitMapFromIFFImage, the IFF gets opened, then I blit from it's bitmap to the one I set up before:
Code:

                                // copy the bitmap using the blitter
                                // LOGIC: skipping the temp buffer for the blitter. I don't believe it's needed, because this shouldn't be an overlap situation. appears OS will do it anyway if needed.
                                        //TempA - If the copy overlaps exactly to the left or right
                                        //        (i.e. the scan line addresses overlap), and TempA is
                                        //        non-zero, it points to enough chip accessable memory
                                        //        to hold a line of A source for the blit (ie CHIP RAM).
                                        //        BitBitMap will allocate (and free) the needed TempA if
                                        //        none is provided and one is needed.  Blit overlap is
                                        //        determined from the relation of the first non-masked
                                        //        planes in the source and destination bit maps.
                                unsigned long the_plane_count = BltBitMap(iff_bitmap, 0, 0, *the_dest_bitmap, 0, 0, pixel_width, pixel_height, 0xC0, 0xFF, NULL);

On destroying the icon, I do waitblit() because docs said to do it:
Code:

        if (the_icon->bitmap_ != NULL)
        {
                WaitBlit();
                FreeBitMap(the_icon->bitmap_);
        }

Anything obvious jump out?

a/b 29 May 2021 07:44

AllocBitMap() does all the work, you shouldn't call InitBitMap() afterwards because it will mess up the bitmap structure (it will mark it as non-interleaved: pad is set to 0 and not to a magic word indicating interleaved bitmap).

Warty 29 May 2021 15:20

Thanks a/b! So nice to be able to exit the app without a system crash again. ;)

So... is there still a use case for InitBitMap, or was it really kind of made unnecessary by the AllocBitMap() call? I seem to remember that there was a point where that didn't exist, and you had it init each bitplane. Fuzzy.

a/b 29 May 2021 15:54

It's an old KS1.x call that you can use it if you're allocating manually (or use static buffers). As long as it's not interleaved because InitBitMap cannot know that (it would need another parameter so you could e.g. pass the flags), and didn't really have to because at the time interleaved bitmaps hadn't been supported out of the box.
You could do some hocus-pocus with bitmap->pad afterwards to fix that but it's not really a good idea :P.

Warty 29 May 2021 17:03

I have enough bad ideas of my own, don't think I'll add that one. ;)

Thanks!


All times are GMT +2. The time now is 23:40.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.04156 seconds with 11 queries