Same code - slow on Windows, fast on Linux - timer fires too slow?
Jacob Moena

I am using the "standard" Allegro main loop code.

I set the timer to fire at 60 times per second:

m_timer.reset(al_create_timer(1.0 / 60.0));

Then, the main loop:

1void Application::run() 2{ 3 bool done = false; 4 bool redraw = true; 5 double old_time = al_get_time(); 6 double time_now = 0.0; 7 double delta_time = 0.0; 8 9 uint64_t counted_frames = 0; 10 11 OnUserCreate(); 12 13 al_start_timer(m_timer.get()); 14 15 while (1) 16 { 17 al_wait_for_event(m_queue.get(), &m_event); 18 19 m_average_fps = counted_frames / al_get_time(); 20 if (m_average_fps > 2000000) 21 { 22 m_average_fps = 0; 23 } 24 25 switch (m_event.type) 26 { 27 case ALLEGRO_EVENT_TIMER: 28 time_now = al_get_time(); 29 delta_time = time_now - old_time; 30 OnUserUpdate(delta_time); 31 old_time = time_now; 32 redraw = true; 33 break; 34 35 case ALLEGRO_EVENT_KEY_DOWN: 36 37 al_get_keyboard_state(&m_keyboard_state); 38 if (al_key_down(&m_keyboard_state, ALLEGRO_KEY_ESCAPE)) 39 { 40 done = true; 41 } 42 if (al_key_down(&m_keyboard_state, ALLEGRO_KEY_P)) 43 { 44 save_screenshot(); 45 } 46 break; 47 case ALLEGRO_EVENT_DISPLAY_CLOSE: 48 done = true; 49 break; 50 } 51 52 if (done) 53 break; 54 55 if (redraw && al_is_event_queue_empty(m_queue.get())) 56 { 57 render(); 58 redraw = false; 59 } 60 ++counted_frames; 61 } 62}

In my Game object is the render function, that gets called when the timer fires:

1bool Game::OnUserRender() 2{ 3 static uint64_t frames = 0; 4 static double average_fps = 0.0; 5 6 average_fps = frames / al_get_time(); 7 8 al_draw_textf(m_font.get(), al_color_name("blanchedalmond"), 10.0, 60.0, 0, "Deltatime : %.2f", m_delta_time); 9 al_draw_textf(m_font.get(), al_color_name("blanchedalmond"), 10.0, 90.0, 0, "FPS : %.2f", m_average_fps); 10 al_draw_textf(m_font.get(), al_color_name("blanchedalmond"), 10.0, 120.0, 0, "Actual FPS : %.2f", average_fps); 11 12 //m_pixelator.get()->blendAlpha(al_color_name("darkred"), 0.04); 13 14 ++frames; 15 16 return true; 17}

On Windows, no matter how fast I configure the timer, it refuses to fire beyond 25 frames per second. Or, am I missing something obvious? ???

On Linux, it works fine. Even in debug mode: 60 FPS, even for the render.

I am attaching a screenshot of it running in Linux. And I will add a screenshot from my Windows box after I reboot.

By the way, I am using Allegro 5.2.6

Attached screenshot from Windows.
Notice how the render FPS is only 25 / 26.
It doesn't matter what mode I compile it in, debug or release.

Attached another screenshot, showing that it stays the same, even when I set the timer to 6000 frames per second :P

Chris Katko
Jacob Moena

Thanks for the tip! :)

I turned vsync off, and it still locks the trigger at 25.

Now I will figure out how to run fullscreen, and see if it's the same issue. :)

Chris Katko

Yeah sorry i misread that. 25 shouldn't be vsync related.

Jacob Moena

I figured it out! ;D

It turns out that al_draw_scaled_bitmap is doggone slow. :P

I replaced it with al_draw_bitmap but that is not something I am happy with.

I am writing an old school raycaster, and my display buffer is 320 * 200.

My application takes a scaling factor which is what the window gets created with: width and height multiplied by the scale.
I am using a scale of four at the moment.

Is there any other way to scale that to fit the screen?

Here is the code that I left out from the original post:

1void Application::render() 2{ 3 al_set_target_bitmap(m_display_buffer.get()); 4 al_clear_to_color(al_map_rgb(0, 0, 0)); 5 6 update_display_buffer(); 7 8 al_set_target_backbuffer(m_display.get()); 9 //al_draw_scaled_bitmap(m_display_buffer.get(), 0, 0, m_width, m_height, 0, 0, m_width * m_scale, m_height * m_scale, 0); 10 al_draw_bitmap(m_display_buffer.get(), 0, 0, 0); 11 OnUserRender(); 12 13 al_draw_text(m_title_font.get(), al_color_name("blanchedalmond"), 10.0, 10.0, 0, "PixelWolf"); 14 15 al_flip_display(); 16}

I attached proof that it works, but it is obviously not acceptable for my application :-*

Funny that al_draw_scaled_bitmap is working fine on Linux, what gives?


As it turns out, when I use al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP | ALLEGRO_NO_PRESERVE_TEXTURE); it works!

I was using ALLEGRO_MEMORY_BITMAP because I read that it was way faster when you are making use of direct pixel access, but apparently it isn't.

I am happy now! It works splendidly - move along ;D
Also, 40 FPS in debug mode is rather nice as well, considering that my code is laden with STL and I am using Visual Studio ;p

Chris Katko

40 fps still sounds incredibly slow but I don't know what your hardware is, and how much drawing you're doing.

Jacob Moena

Visual Studio is incredibly slow in debug mode when using the STL.
Even when setting _NO_DEBUG_HEAP to 1.
GCC is much faster :)

What am I doing?

Well . . .
I am plotting pixels. Each frame I update the display_buffer, like this:

1void Application::update_display_buffer() 2{ 3 m_screenlock = al_lock_bitmap(m_display_buffer.get(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); 4 5 for (int y = 0; y < m_height; ++y) 6 { 7 for (int x = 0; x < m_width; ++x) 8 { 9 ALLEGRO_COLOR color = m_pixelator.get()->getPixel(x, y); 10 al_put_pixel(x, y, color); 11 } 12 } 13 14 al_unlock_bitmap(m_display_buffer.get()); 15}

The "Pixelator" keeps a lot of pixels in buffers, and I use it to build the scene. I can copy, plot, draw, swap buffers, ... I am using it to write a raycaster. I got good results in SDL, SFML was too slow, and Raylib was nice, but could not provide what I need.
I landed on Allegro in the end, and I ported to code over in less than two days, and I think I have finally found a framework I can be happy with.
Funny thing, Allegro (with Djgpp) was what I started out with, back in the day.

My machine is not terrible, but certainly not top of the line: AMD Ryzen 3 1200 Quad-Core Processor 3.10 GHz, with 8 gigs of RAM, and sporting a GeForce GTX 1050 TI with (I think) 4 gb video RAM.

I will probably using Allegro threads to speed up the raycasting, maybe.
I will post about my project soon, when I have ported everything over and it runs properly. :D

I am now on my Linux box. GCC runs this at 60 frames per second in debug mode.
So, blame it on VC for being overly burdensome with debug code.
I am not really worried. For now anyway ;D

Edgar Reynaldo

IMHO, you should ditch VS and go for MinGW-W64 and Code::Blocks, for Windows at least.

Uploading 320x240 to the video card with WRITE_ONLY should be pretty fast, no matter what machine you're on. It's downloading from the video card that is slow.

Jacob Moena

No, definitely not Code::Blocks, it doesn't cut it. I tried it, and it didn't impress me. I don't intend to bash it, because it is open source, and all. And choice is a good thing!
MinGW-W64 is great, but I prefer to use GCC on Linux, or - put another way - why GNU for Windows when you can GNU the real deal? :)

However, perhaps I will try and hook up Clang with Visual Studio. Thanks for encouragement :D

I switched to LLVM (clang-cl) in Visual Studio, but - alas! - the Allegro Nuget packages are only configured for v141 and v142. A pity. I will have to look into that RealSoonNow, won't I? :)

I tried MinW-64, and is GCC 8 really the latest version? I can't use it because it doesn't fully support C++17. Unfortunately. :) Oh, I see that Msys has it.

Edgar Reynaldo

I'm a bit disappointed that MinGW-W64 is still on GCC 8 too. But I only use C++11 so it doesn't really bother me.

What don't you like about CB? What can VS do that CB can't? VS's idea of projects and solutions is an abomination in my opinion, and it's not a very good IDE. It's GUI sucks and is really inefficient if you ask me.

Can't deal with the STL? Sounds like a good enough reason to dump it for me. But is that VS's fault or cl?

Jacob Moena

The debugging environment in Visual Studio is still unmatched :)

Visual Studio 2013 - 2015 was bad. But I am happy with Visual Studio 2019.
With Nuget, using Allegro is as easy to get up and running as it is on Linux with CMake.

The dated WxWidgets interface of Code::Blocks is not something that will win me over. I generally prefer the native option on my platforms. So Visual Studio on Windows, or Visual Studio Code with CMake.
When I want to use GCC, I will do that on my Linux box.
KDevelop once in a while, but mostly VSCode. That editor is snappy :)

That said, if I could afford to, I would switch to CLion. That is the best IDE for C and C++ programming, in my very humble opinion ;D

Edgar Reynaldo

I do all my debugging with GDB. Does everything I need. I use it from the command line though, no interactive GUI for the debugger, but CB would work if I wanted to use it that way.

Jacob Moena

I very much prefer to work in a console in Linux :)

Also, I have to admit that I have yet to dive into the mysteries of GDB. I am aware that it can be quite effective, provided you know what you're doing (which I don't).
I usually get by with VSCode which actually has a decent GUI interface to GDB.

Edgar Reynaldo

I will admit that I don't like CB on Linux much. Right click drag scrolling doesn't work, which is one of my most necessary and favorite features of CB on Windows.

I still haven't found an IDE I like to use on Linux yet, recommendations?

Jacob Moena

If you have the money, CLion. I am sure they've got a trial that you can install. I found the Clang integration to be sublime! :)

I am switching between KDevelop and VSCode (not an IDE), but used to be quite happy with QtCreator.
I tried it recently, after having been away from C and C++ programming for a long while, and they changed their CMake support to the point of me wondering if they don't intend to support CMake like they did. I don't care for their native project format, so I guess I am also shopping for a decent IDE.

But, if you haven't tried KDevelop and QtCreator, please do.

If Visual Studio solution and project files are an abomination, then Code::Blocks files are too. They are practically identical: simple XML files :D

Yes, they were awful once upon a time, but that was long ago.
Take a look ->

The whole solution consists of PixelWolf.sln, PixelWolf.vcxproj, and PixelWolf.vcxproj.filters.

That said, it is very atypical of me to commit any project files to a repository because I usually use CMake and treat those as generated build files. But not with Allegro as I use Nuget with it.

Edgar Reynaldo

.cbp files are self contained and don't end up with 10 different directories of crap in them like VS. Nothing wrong with XML when it is used properly. And CB .workspace files are super simple too. Project management is NOT a strong suit of VS.


On linux I use gvim, with a custom .gvimrc for better readability.

I'm also having a script called gtab that open things inside a tab, and support multiple gvim instances. It will be uploaded to a git before the end of the day, because I like to share my shit. (Done: )

I have CodeBlocks installed but I'm not starting it a lot, and QTCreator / AndroidStudio because I need them for some projects that were already done with them.

Thread #618372. Printed from