Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » is_same_bitmap bug?

This thread is locked; no one can reply to it. rss feed Print
 1   2 
is_same_bitmap bug?
axilmar
Member #1,204
April 2001

I have the following code:

1#include <allegro.h>
2 
3int main() {
4 allegro_init();
5 install_keyboard();
6 install_timer();
7 install_mouse();
8
9 set_color_depth(16);
10 set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
11 show_mouse(screen);
12
13 BITMAP *bmp = create_video_bitmap(SCREEN_W, SCREEN_H);
14 while (is_same_bitmap(screen, bmp))
15 bmp = create_video_bitmap(SCREEN_W, SCREEN_H);
16
17 line(bmp, 0, 0, 100, 100, makecol(255, 0, 0));
18 readkey();
19 return 0;
20}

I am trying to create a buffer in video ram that does not overlap the screen...the function is_same_bitmap reports that bmp is not the same bitmap as the screen, but when I draw a line in bmp, the line is displayed. Is this a bug?

EDIT: the same happens when GFX_AUTODETECT_WINDOWED is used.

A J
Member #3,025
December 2002
avatar

perhaps.

how much memory does your gfx card have ?
what system ?
what OS ?

___________________________
The more you talk, the more AJ is right. - ML

axilmar
Member #1,204
April 2001

allegro version: 4.2.0
O/S: WinXP SP2
video memory: 128 MB ram
chipset: Mobile Intel(R) 915GM/GMS,910GML Express Chipset Family

Elias
Member #358
May 2000

Yes, seems to be a bug. Does it also happen without the while?

And what do you get if you add

printf("%x %x\n", screen->id, bmp->id);

somewhere?

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

axilmar
Member #1,204
April 2001

I get "80000000 80000000".

EDIT:

If I remove the 'while', then it works: a different bitmap is created.

Elias
Member #358
May 2000

The attached patch might work, but I'm not sure what consequences it has, since is_same_bitmap(screen) is used several times in the source, and it seems to have worked so far.

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

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

while (is_same_bitmap(screen, bmp))
bmp = create_video_bitmap(SCREEN_W, SCREEN_H);

That's a nasty memory leak you have there. And is not gauranteed to do what you want. On non-Windows platforms, video bitmaps are always sub-bitmaps of the screen, so that would always be true.

The way to get an off-screen video buffer is to create a screen-sized video bitmap after set_gfx_mode and use it as a 'screen' replacement, then create another screen-sized buffer. You need to remember to destroy video bitmaps that you're no longer using since they use system-wide shared memory that may not be freed even after your process ends.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

axilmar
Member #1,204
April 2001

Quote:

That's a nasty memory leak you have there. And is not gauranteed to do what you want. On non-Windows platforms, video bitmaps are always sub-bitmaps of the screen, so that would always be true.

I am aware of that...the code is just an example.

Quote:

The way to get an off-screen video buffer is to create a screen-sized video bitmap after set_gfx_mode and use it as a 'screen' replacement, then create another screen-sized buffer. You need to remember to destroy video bitmaps that you're no longer using since they use system-wide shared memory that may not be freed even after your process ends.

You mean calling create_video_bitmap twice? what shall I do with the first bitmap? shall I destroy it after I create the second one?

Kitty Cat
Member #2,815
October 2002
avatar

If you're doing page-flipping, you'd use the two as the two buffers. I'm not sure if you can destroy the initial video bitmap like that, since Allegro-Windows does some funky behind-the-scene hacks to get it to work.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

axilmar
Member #1,204
April 2001

I am not using the first bitmap; I only want to get a video bitmap as a back buffer which will I use for VRAM blitting.

EDIT:

Elias, thanks for the patch, but I better wait for the bug to be solved in a future Allegro release.

For now, I create two video bitmaps, destroy the 1st one, keep the 2nd one.

Elias
Member #358
May 2000

The patch was just to fix that is_same_bitmap apparently won't work for windows video bitmaps, it wouldn't really help with your problem.

If you want VRAM blitting, you must not use 'screen', but instead as first call to create_video_bitmap create a bitmap which is SCREEN_W x SCREEN_H big and use that instead. It's simply how Allegro was designed.

(Allegro 4.3 will do this in a better way and automatically HW accelerate stuff without the need to mess with video bitmaps.)

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

axilmar
Member #1,204
April 2001

But 'create_video_bitmap' returns the screen the first time it is called.

Elias
Member #358
May 2000

Well, whenever you use video_bitmaps with Allegro, you should not use screen, but that first screen-sized bitmap created by the first call to create_video_bitmap.

As the documentation says:

Quote:

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.

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

axilmar
Member #1,204
April 2001

The only reason the documentation says so is because graphics will be mixed. I do not think there is any other problem. I have always used 'screen' in page flipping environments anyway and never had a problem.

But my problem is not with 'create_video_bitmap', but with 'is_same_bitmap'.

Elias
Member #358
May 2000

Well, per design you should not use screen if you use video bitmaps, as the documentation states. If it works now, that could change any time (although realistically, I doubt someone will change the Allegro 4.2.x DirectX driver much - so you should be safe).

is_same_bitmap wouldn't help you much, since the correct way would be to return true for any video bitmap and screen. The only bug is that currently it seems to always return false.

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

Thomas Fjellstrom
Member #476
June 2000
avatar

As has been said, if you are using video bitmaps, DO NOT use "screen". The first SCREEN_W/_H area is always going to be allocated from the same area as "screen", and they are NOT the same bitmaps, they just happen to share the same origin.

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

axilmar
Member #1,204
April 2001

Actually, they are not the same BITMAP objects, but they are the same bitmaps: they share the same drawing surface.

So it is ok to use 'screen' along with any video bitmap created, and this is what I have done.

I wanted to use 'is_same_bitmap' because I wanted to know when a video page is not the same as the screen...and I want to use 'screen' in my library, because it is the expected Allegro interface: clients of my library can use their drawing routines which draw on the screen, whereas I can do whatever I want with it.

Elias
Member #358
May 2000

Simply create a video bitmap sized exactly SCREEN_W times SCREEN_H before any other video bitmpas then (and don't delete it, since DirectX might actually re-use the memory otherwise). That will make sure no other video_bitmaps will overlap with the visible screen.

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

Evert
Member #794
November 2000
avatar

Quote:

So it is ok to use 'screen' along with any video bitmap created,

Yes and no. It's ok as long as you create (and don't use) a dummy video bitmap sized SCREEN_W x SCREEN_Hbefore all others, but it's still not recommended.

Quote:

I wanted to use 'is_same_bitmap' because I wanted to know when a video page is not the same as the screen...

This will be platform dependent; if you're using it in this way the result will not be reliable or portable across different platforms.

axilmar
Member #1,204
April 2001

Elias said:

Simply create a video bitmap sized exactly SCREEN_W times SCREEN_H before any other video bitmpas then (and don't delete it, since DirectX might actually re-use the memory otherwise).

Why not delete it? DirectX won't reuse the memory because it is used for 'screen'.

Evert said:

This will be platform dependent; if you're using it in this way the result will not be reliable or portable across different platforms.

Is it platform dependent due to a bug or due to design? maybe this platform dependency should be written in the docs.

Anyway, what I've done is to create a video bitmap of SCREEN_W, SCREEN_H size and then create the video page I want. The first bitmap is destroyed right after the second bitmap is created.

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

but they are the same bitmaps: they share the same drawing surface.

Nope. the "screen" has a separate vtable, as well as the "screen" may also be the size of VRAM, not just SCREEN_W, SCREEN_H.

Video Bitmap != Screen Bitmap. Ever.

Quote:

Why not delete it? DirectX won't reuse the memory because it is used for 'screen'.

Wrong again. The main "screen" is a wee different from video bitmaps created by allegro. the first created Video Bitmap is always taken from the same area (weather or not its the same size, you can have multiple small video bitmaps be allocated from the same space that "screen" is using).

Quote:

The first bitmap is destroyed right after the second bitmap is created.

[edited out stuff here] Once you create a video bitmap, FORGET about "screen". Just use the first two video bitmaps created, and switch between them. That IS the proper way.

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

Evert
Member #794
November 2000
avatar

Quote:

Is it platform dependent due to a bug or due to design?

Neither. It is platform dependent due to differences between platforms.

Quote:

maybe this platform dependency should be written in the docs.

It is. Check the docs for VRAM_SINGLE_SURFACE: if this is defined, then all video bitmaps are children of the screen bitmap.

As an aside, this is also why you should use SCREEN_W and SCREEN_H , not screen->w and screen->h, and why you should never pass screen directly to save_bitmap().

axilmar
Member #1,204
April 2001

Thomas Fjellstrom said:

Nope. the "screen" has a separate vtable

Which part of the "they are not the same BITMAP objects" you did not understand?

Quote:

as well as the "screen" may also be the size of VRAM, not just SCREEN_W, SCREEN_H.

Hey, that's basic allegro knowledge...otherwise SCREEN_W and SCREEN_H would not have been there.

Quote:

Once you create a video bitmap, FORGET about "screen". Just use the first two video bitmaps created, and switch between them. That IS the proper way.

But I am not implementing a page flipping algorithm. I am writing a GUI library and I just want to blit the GUI buffer to the screen. So I am using one video bitmap and the screen.

And I do not want to use the first page allocated, because the 'screen' value could be set to anything the user of my library desires.

The solution I am using works perfectly under Windows, both in windowed and full screen mode. Wouldn't it work for Linux?

Evert said:

Neither. It is platform dependent due to differences between platforms.

Due to design then.

Quote:

It is. Check the docs for VRAM_SINGLE_SURFACE: if this is defined, then all video bitmaps are children of the screen bitmap.

Yes, but it does not say anything about 'is_same_bitmap'.

The problem is neither of what you or anyone else keeps referring to. The problem is that the function 'is_same_bitmap' does not work as expected: when I write to one bitmap, the drawing appears in the other bitmap, but the function 'is_same_bitmap' does not report any relationship between the two bitmaps.

Elias
Member #358
May 2000

Quote:

The solution I am using works perfectly under Windows, both in windowed and full screen mode.

I would expect it to fail, depending on windows and directx version. It's simply not an officially supported mode of operation, AFAICT.

Quote:

Wouldn't it work for Linux?

No, Linux and OSX will generally return NULL for create_video_bitmap.

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

Evert
Member #794
November 2000
avatar

Quote:

The problem is neither of what you or anyone else keeps referring to. The problem is that the function 'is_same_bitmap' does not work as expected: when I write to one bitmap, the drawing appears in the other bitmap, but the function 'is_same_bitmap' does not report any relationship between the two bitmaps.

Actually, Elias already said in his first post that that was probably a bug.
Leaving that aside, the point made is that you are using video bitmaps diferently from how they are intended and the results can be unreliable.

Quote:

And I do not want to use the first page allocated, because the 'screen' value could be set to anything the user of my library desires.

No one should ever set screen to anything else than what it's set at after a call to set_gfx_mode(). I'm not sure if that's what you meant though?

Quote:

Linux and OSX will generally return NULL for create_video_bitmap.

The X11 driver fakes video bitmaps if the virtual screen is larger than the actual screen.

 1   2 


Go to: