views:

349

answers:

2

I have 3 Bitmap point .

Bitmap* totalCanvas = new Bitmap(400, 300, PixelFormat32bppARGB);  // final canvas
Bitmap* bottomLayer  = new Bitmap(400, 300,PixelFormat32bppARGB); // background
Bitmap* topLayer = new Bitmap(XXX); // always changed.

I will draw complex background on bottomLayer. I don't want to redraw complex background on totalCanvas again and again, so I stored it in bottomLayer.

TopLayer changed frequently. I want to draw bottomLayer to totalCanvas. Which is the fastest way?

Graphics canvas(totalCanvas); 
canvas.DrawImage(bottomLayer, 0, 0);  step1
canvas.DrawImage(topLayer ,XXXXX);   step2

I want step1 to be as fast as possible. Can anyone give me some sample? Thanks very much!

Thanks for unwind's answer. I write the following code:

Graphics canvas(totalCanvas); 
for (int i = 0; i < 100; ++i)
{
canvas.DrawImage(bottomLayer, 0,0);
}

this part takes 968ms... it is too slow...

+1  A: 

Almost all GDI+ operations should be implemented by the driver to run as much as possible on the GPU. This should mean that a simple 2D bitmap copy operation is going to be "fast enough", for even quite large values of "enough".

My recommendation is the obvious one: don't sweat it by spending time hunting for a "fastest" way of doing this. You have formulated the problem very clearly, so just try implementing it that clearly, by doing it as you've outlined in the question. Then you can of course go ahead and benchmark it and decide to continue the hunt.

A simple illustration:

A 32 bpp 400x300 bitmap is about 469 KB in size. According to this handy table, an Nvidia GeForce 4 MX from 2002 has a theoretical memory bandwidth of 2.6 GB/s. Assuming the copy is done in pure "overwrite" mode, i.e. no blending of the existing surface (which sounds right, as your copy is basically a way of "clearing" the frame to the copy's source data), and an overhead factor of four just to be safe, we get:

(2.6 * 2^30 / (4 * 469 * 2^10)) = 1453

This means your copy should run at 1453 FPS, which I happily assume to be "good enough".

unwind
Thanks!, I tried but it seems not fast enough...
A: 

If at all possible (and it looks like it from your code), using DrawImageUnscaled will be significgantly faster than DrawImage. Or if you are using the same image over and over again, create a TextureBrush and use that.

The problem with GDI+, is that for the most part, it is unaccelerated. To get the lightening fast drawing speeds you really need GDI and BitBlt, which is a serious pain in the but to use with GDI+, especially if you are in Managed code (hard to tell if you are using managed C++ or straight C++).

See this post for more information about graphics quickly in .net.

Kris Erickson