|
Crazy "random" slowdown |
aniquilator
Member #9,841
May 2008
|
Hello folks. The explanation: So, i "finished" my integration of the graphic module, but I'm finding some crazy problems in some situations.. For example this:Explanation after the code 1const int width = 1280;
2const int height = 720;
3
4int main()
5{
6 try
7 {
8 Graphic::Addon::System::set();
9 Input::Addon::System::set();
10 Graphic::Display display("TESTE GORGON Framework rev 207+", width, height);
11 Input::Keyboard keyboard;
12
13 std::vector<Graphic::Image> images;
14 //images.push_back( Graphic::Image("hakumen_normal_map.pcx") );
15 Graphic::Image a("hakumen.pcx");
16 //images.push_back( Graphic::Image("hakumen_normal_map.pcx") );
17
18
19 Core::Point position(150,150);
20
21 float zoom = 1;
22
23 display.setAsTarget();
24 while(1)
25 {
26
27 keyboard.update();
28 if( keyboard.getKey( Input::Key::ESCAPE ).isPressed() )
29 {
30 break;
31 }
32 else if( keyboard.getKey( Input::Key::LEFT_ALT ).isPressed() && keyboard.getKey( Input::Key::ENTER ).isPressed() )
33 {
34 display.toogleFullScreen();
35 }
36
37 if ( keyboard.getKey( Input::Key::RIGHT ).isPressed() ) { position.addX(5.5); }
38 else if ( keyboard.getKey( Input::Key::LEFT ).isPressed() ) { position.subX(5.5); }
39 if ( keyboard.getKey( Input::Key::DOWN ).isPressed() ) { position.addY(5.5); }
40 else if ( keyboard.getKey( Input::Key::UP ).isPressed() ) { position.subY(5.5); }
41
42 if ( keyboard.getKey( Input::Key::W ).isPressed() ) { zoom-= 0.1; }
43 else if ( keyboard.getKey( Input::Key::S ).isPressed() ) { zoom+= 0.1; }
44 if(zoom < 0 ) zoom = 0;
45 display.clear(Graphic::Color(1.0f ,0.0f ,0.5f, 1.0 ) ); //limpa a tela
46
47 a.draw(position, a.getWidth()*zoom, a.getHeight()*zoom, Graphic::Mirroring::Normal );
48
49 al_flip_display();
50
51 }
52 }
53 catch(Core::Exception& exception)
54 {
55 exception.writeInLog();
56 std::cout << "exception" << std::endl;
57 }
58 Graphic::System::halt();
59 return 0;
60}
I load a image and displays it in the screen... aplying some scale.. //images.push_back( Graphic::Image("hakumen_normal_map.pcx") ); Graphic::Image a("hakumen.pcx"); //images.push_back( Graphic::Image("hakumen_normal_map.pcx") );
If a uncoment the first line, all my program becomes soooo slow. I know that its difficult to know whats happing wihout knowing the Image code and all. But all it does is load a allegro image and puts it inside. I have used the Allegro Debug version and got the allegro.log, and surprise.. I dont know why, but when it becomes slow to hell I got lots of: opengl D ogl_bitmap.c:649 ogl_lock_region [ 8,60037] Locking backbuffer opengl D ogl_bitmap.c:846 ogl_unlock_region [ 8,75334] Unlocking backbuffer
I think it calls this every step of the game. Please help, I'm getting crazy here, today I passed more than 3 hours running the debug mode, and finding nothing ... |
Edgar Reynaldo
Major Reynaldo
May 2007
|
You should post your Graphic::Image class constructor. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Mark Oates
Member #1,146
March 2001
|
For my own curiosity and slightly unrelated to your question, could you talk briefly about your framework, what it aims to do and how it's generally constructed? -- |
aniquilator
Member #9,841
May 2008
|
So.. I think I found whats causing this whole mess... 1void Image::load(const std::string& pFileName,const ImageLoader& pImageLoader)
2 {
3 setImageBase(System::get().getImage(), true);
4 create(350,350);
5 setAsTarget();
6 lock();
7 for(int i =0; i<getHeight(); ++i)
8 {
9 for(int j =0; j<getWidth(); ++j)
10 {
11 System::get().drawPixel( Core::Point(j, i), Color(1.0, 1.0, 0.0, 1.0) );
12 }
13 }
14 unlock();
15
16 //pImageLoader.load(*this, pFileName);
17 }
In this code, I'm forcing the load to paint each pixel of the image manually with green... Now what I have discovered... If I create a image small, the program runs fine, if the image is big, than, welcome slowdown. What do you think? Now, Mark Oates: So, after that I made my framework all in c++. The main goals: multiplataform, working in a system based in backends: You choose the lib that will render, like, allegro, sdl, allegro5. Why? I wanted to have the most plataforms possible. and some other modules that I will remove when I have ported them all. This framework works with lua, as a script language, and chipmunk as a physics lib. Besides, I have a Editor, with sprites, animations and sound packages. After the framework middle age, I started to program a game engine totally based in scripts. And this engine is almost done, you program all your game with lua, and use the framework files, for sprites, audio, animations in your game. Um.. I think thats it. XD |
Elias
Member #358
May 2000
|
aniquilator said: So what I think is: if there are many put pixel operations the program goes slow... Yes, both al_draw_pixel and al_put_pixel are very slow. Avoid them unless in special cases, like maybe use al_draw_pixel for certain particle effects. al_put_pixel is used on locked surfaces - usually just locking in a known format like RGBA then directly modifying the buffer is faster. But al_put_pixel can be easier to understand if speed doesn't matter and in some special cases you might lock to an unknown format in which case you need al_put_pixel. -- |
aniquilator
Member #9,841
May 2008
|
Elis thats no the case.. Like I said, this kind of operations is occuring very much: opengl D ogl_bitmap.c:649 ogl_lock_region [ 8,60037] Locking backbuffer opengl D ogl_bitmap.c:846 ogl_unlock_region [ 8,75334] Unlocking backbuffer And I dont know why. |
Elias
Member #358
May 2000
|
Well, al_draw_pixel() will take as long as al_draw_bitmap() - which is quite slow, considering it only draws a single pixel. What for are you calling al_put_pixel? It doesn't really make sense except for directly modifying memory/locked bitmaps. If you want to draw a single pixel (e.g. for particle effects), use al_draw_pixel. -- |
aniquilator
Member #9,841
May 2008
|
I just use al_put_pixel in my loading functions. It happens, in my main loop, after put pixels and all. But in some cases this ogl_lock, unlock, is happening too much... |
someone972
Member #7,719
August 2006
|
What is the code for the draw() and clear() functions? ______________________________________ |
Elias
Member #358
May 2000
|
You should never use locking during the game... it will kill performance. (There's exceptions, like if you stream a video to a texture and have no other way to transfer the data.) -- |
aniquilator
Member #9,841
May 2008
|
Elias I'm not locking/unlocking during the game... 1void ImageBase::clear(const Color& pColor) const
2{
3 ALLEGRO_BITMAP* aux = al_get_target_bitmap();
4 al_set_target_bitmap(mData);
5 al_clear_to_color( gorgonColort2AllegroColor(pColor) );//just normal conversion, not big
6 al_set_target_bitmap(aux);
7}
8void ImageBase::draw
9(
10 const Core::Point& pPosition,
11 const int& pWidth,
12 const int& pHeight,
13 const Mirroring& pMirroring
14) const //drawScaled
15{
16 al_draw_scaled_bitmap
17 (
18 mData,
19 0, 0,
20 mWidth, mHeight,
21 pPosition.getX(), pPosition.getY(),
22 pWidth, pHeight,
23 gorgonMirroring2AllegroMirroring(pMirroring)//small conversion
24 );
25}
I was that the problem just happens for drawing operations. If I clear the image instead, it runs normal, but when I draw(every kind of draw),it becomes crazy. |
Elias
Member #358
May 2000
|
Why do you clear the bitmap you are drawing? I assume you draw everything to an intermediate buffer and then only draw that. Some (old) cards don't like that. I assume if you never change the target bitmap the slowdown disappears. -- |
aniquilator
Member #9,841
May 2008
|
I don't clear the bitmap I'm drawing, I just clear the display. display.clear(Graphic::Color(1.0f ,0.0f ,0.5f, 1.0 ) ); //limpa a tela a.draw(position, a.getWidth()*zoom, a.getHeight()*zoom, Graphic::Mirroring::Normal ); al_flip_display();
Btw, i made more test today, and I figure out, looking into the allegro locks that when the slowdown happens there is 2 locks into the bitmap, but only one unlock... But I explicity call lock, then unlock, one time each. And I putted a printf there, and i comproved that My calls are correct, one for each, but why the allegro are calling 2 locks? look at these lines in the log: opengl D ogl_bitmap.c:1076 _al_ogl_create_bitmap [ 0,75770] Creating OpenGL bitmap opengl D ogl_bitmap.c:1098 _al_ogl_create_bitmap [ 0,75775] Using dimensions: 350 350 opengl D ogl_bitmap.c:1107 _al_ogl_create_bitmap [ 0,75779] Chose format ABGR_8888 for OpenGL bitmap dtor D dtor.c:184 _al_register_destructor [ 0,77158] added dtor for object 0x944cd18, func 0xedc0db opengl D ogl_display.c:194 setup_fbo [ 0,77169] Created FBO: 1 opengl D ogl_bitmap.c:679 ogl_lock_region [ 0,77181] Locking non-backbuffer READWRITE display D xfullscreen.c:974 _al_xglx_handle_mmon_event [ 0,82355] got event 28 opengl D ogl_bitmap.c:892 ogl_unlock_region [ 0,96023] Unlocking non-backbuffer READWRITE The Slow: opengl D ogl_bitmap.c:1076 _al_ogl_create_bitmap [ 0,79280] Creating OpenGL bitmap opengl D ogl_bitmap.c:1098 _al_ogl_create_bitmap [ 0,79287] Using dimensions: 350 350 opengl D ogl_bitmap.c:1107 _al_ogl_create_bitmap [ 0,79291] Chose format ABGR_8888 for OpenGL bitmap dtor D dtor.c:184 _al_register_destructor [ 0,80180] added dtor for object 0x95339e8, func 0x8790db opengl D ogl_bitmap.c:679 ogl_lock_region [ 0,80190] Locking non-backbuffer READWRITE opengl D ogl_bitmap.c:671 ogl_lock_region [ 0,84405] Locking non-backbuffer WRITEONLY opengl D ogl_bitmap.c:888 ogl_unlock_region [ 0,84568] Unlocking non-backbuffer WRITEONLY dtor D dtor.c:214 _al_unregister_destructor [ 0,85012] removed dtor for object 0x9546ca8 OOOO This is driving me crazy.:( |
Elias
Member #358
May 2000
|
aniquilator said:
al_set_target_bitmap(mData); So "aux" and "mData" are the same? aniquilator said: Btw, i made more test today, and I figure out, looking into the allegro locks that when the slowdown happens there is 2 locks into the bitmap, but only one unlock... But I explicity call lock, then unlock, one time each. That would explain the slowness. What is the difference between your two logs? Or are you saying the same program, when you run it multiple times, will behave differently? Are you calling any graphics functions other than al_put_pixel or al_draw_pixel while a bitmap is locked? -- |
aniquilator
Member #9,841
May 2008
|
Aux is the previous target. To generate my logs, i have done this: to siulate the fast and normal behavior, I uncommented the second. Edit: Edit2: ImageBase::~ImageBase() { if(mData != NULL) { if( al_get_target_bitmap() == mData ) { al_set_target_bitmap(NULL); } al_destroy_bitmap(mData); } }
When I commented the al_set_target_bitmap() |
Elias
Member #358
May 2000
|
What for is that if? Why would you ever destroy the current target bitmap? Are you maybe trying to destroy a bitmap you don't own (like the backbuffer)? -- |
aniquilator
Member #9,841
May 2008
|
I putted that in the destructor just to erase the target if i would destroy the image. Just ti erase the trash pointer. But the funny fact is that, |
Thomas Fjellstrom
Member #476
June 2000
|
aniquilator said: It just becomes slow if I call al_set_target_bitmap(NULL)before creating my images, if I call after nothing happens. O.o Probably because at that point, allegro doesn't know what display to attach your bitmaps to, so it creates memory bitmaps. Which as you've noticed, is slow. -- |
van_houtte
Member #11,605
January 2010
|
Mark Oates said: For my own curiosity and slightly unrelated to your question, could you talk briefly about your framework, what it aims to do and how it's generally constructed? KGM v2.0 ----- Sometimes you may have to send 3-4 messages |
aniquilator
Member #9,841
May 2008
|
So to test this behavior, I have made a small program so simulate it.. 1int main()
2{
3 al_init();
4 al_init_image_addon();
5 al_install_keyboard();
6
7
8 ALLEGRO_DISPLAY *display = al_create_display(1280,780);
9 al_set_target_bitmap(NULL);
10 ALLEGRO_BITMAP* img = al_create_bitmap(820,840);
11 al_set_target_bitmap(img);
12 for(int i = 0; i < 820; ++i)
13 {
14 for(int j = 0; j < 840; ++j)
15 al_put_pixel(i,j,al_map_rgb(i,i,j));
16 }
17 al_set_target_backbuffer(display);
18 float i=0;
19 while (1)
20 {
21
22 ALLEGRO_KEYBOARD_STATE kstate;
23 al_get_keyboard_state(&kstate);
24
25 if (al_key_down(&kstate, ALLEGRO_KEY_ESCAPE)){break;}
26
27 al_clear_to_color(al_map_rgb_f(i,i,i));
28 al_draw_bitmap(img,20,20,0);
29 al_flip_display();
30 i+= 0.01;
31 if(i>1) i = 0;
32 }
33}
And if I comment the "al_set_target_bitmap(NULL);" it all work normal, it it remains there, slowdown. btw KGM 2.0 O.o ? I dont get. kkk |
van_houtte
Member #11,605
January 2010
|
----- Sometimes you may have to send 3-4 messages |
Elias
Member #358
May 2000
|
Well, as Tomasu said, never call al_set_target_bitmap(NULL) or you get memory bitmaps. -- |
|