Graphic slowdown with a very specific combination of options
Max Savenkov

In my game, I'm experiencing nasty single-frame jumps in frame time in some very specific circumstances.

There are a lot of drawing going on each frame, but only one particular operation leads to slowdown when it happens. I have a texture, content of which I change sometimes according to some game events. When that happens, I draw a pre-made image over that texture. The texture itself is rendered to screen in every frame.

Simplified, the code for updating the texture looks like this:

  int a,b,c;
  al_get_blender( &a, &b, &c );

  ALLEGRO_BITMAP *old = al_get_target_bitmap();
  al_set_target_bitmap( alTrgImg->GetBitmap() );
  al_draw_bitmap( alImg->GetBitmap(), x, y, 0 );
  al_set_target_bitmap( old );

  al_set_blender( a, b, c );

From my own al_get_time()-based profiling, I gather that slowdown happens inside al_flip_display() whenever I run this code. Amount of slowdown is quite noticeable. When usually I get 16ms per frame (with VSync enabled), here I get up to 65ms or even 100ms!

This only happens if I:

1) Use DirectX Allegro render
2) Enable VSync
3) Run game in Fullscreen

If I change any of this, the game runs just fine without any slowdowns. If I run the game without VSync, I can get up to ~1000FPS without any slowdowns, so it's not as if this operation with texture is very expensive!

So far, I failed to track down this problem to any specific code inside al_flip_display() with CPU profilers (Visual Studio built-in profiler and AMD CodeXL), and I lack knowledge to use GPU profilers (I looked at results from NVidia's tool, but couldn't interpret it in any useful way).

I also was unable to reproduce this problem with a smaller example, so I guess I must be doing something else wrong. Somewhere.

I already spent a lot of evening debugging on this, and I'm stumped, so, I'm asking for any advice, or suggestion for a tool, or any other help.

Chris Katko

I'm not familiar with your exact problem, so I'm sure someone with better advice will come along but for a quick thought:

Are you sure both bitmaps are on the videocard instead of system bitmaps?

Are those bitmaps locked?

I seem to recall both of those issues causing problems like that.

Max Savenkov

Yes, I'm sure they are video bitmaps, and they are not explicitly locked.

What I'm doing here - updating and reuploading a texture - can be quite slow, but then again - the problem doesn't show up until I enable VSync, so I guess it's not just a general speed problem with what I'm doing (even using frame-limiter with limit set to 60FPS does not lead to the same problem as using VSync).

Trent Gamblin

You need to use ALLEGRO_NO_PRESERVE_TEXTURE. See the docs.

Max Savenkov

Setting ALLEGRO_NO_PRESERVE_TEXTURE did help, thank you, didn't think of this myself. It makes sense then, that the problem was only present with DirectX/fullscreen modes. However, I can't quite see why it only appeared with VSync enabled.

The problem is, I NEED to preserve this texture, because I do not re-create it every frame, but instead add to it from time to time. I'll have to think what to do here. I could, for example, also draw images into a separate memory texture, and when I need to recreate, use this memory texture as a mask. Or I could remember all coordinates of images I've drawn, and recreate modified state of texture from that...

Trent Gamblin

Yeah you'll need to figure something out to manually keep that texture preserved, depending on your needs...


I keep all my assets in one zip file in memory, and only load bitmaps if they are needed. I have a loader which checks if a bitmap is loaded, if it is, it returns it, and if it is not, it loads it. Bitmaps may only be accessed through this loader via special resource handles, and never directly. Also, when a bitmap is requested it is pushed on top of the most recently used list. Then, when some memory threashold is reached, items on the bottom of this list can be purged. So, I don't need much to do, actually, in case bitmaps are lost: I just need to purge my whole most recently used list, and that's it.

Trent Gamblin

It's different because he's drawing into a bitmap (creating it at runtime.)


Really. It seems I missed that.

Thread #614893. Printed from