Delphi FireMonkey Canvas performance issues
I am trying to make 2D game in Delphi XE5/XE6 with FireMonkey, and I need to keep multiplatformity - I need Windows and Android build. For now, game is just drawn with lines, circles, rectangles or other polygons and I use Canvas ( TPaintBox
on whole screen and OnPaint event to paint). Problem is, I think that performance is extremely low, even when FireMonkey should use GPU acceleration. I made this performance test which draw 1000 rectangles on random XY positions:
procedure Paint(Canvas: TCanvas);
var
I: Integer;
X, Y: Single;
begin
Canvas.BeginScene;
Canvas.Clear($ffffffff);
Canvas.Fill.Color := $ffff0000;
for I := 0 to 10000 do begin
X := Random(500);
Y := Random(400);
Canvas.FillRect(TRectF.Create(X, Y, X + 20, Y + 20), 0, 0, [], 1);
end;
Canvas.EndScene;
end;
I measured approach thru this function and I get these results:
Windows PC - Core2Duo 3.2GHz, GeForce 660Ti - pretty strong for such simple task - it took 20 miliseconds
Android Phone - HTC One X (4 core, 1 GHz, Tegra 3 CPU/GPU) - it took 50-60 milisends (not as big difference against PC, as i thought)
However I think that both devices should be able to draw not 10 000, but 100 000, or even milions rectanges (my PC with GTX 660 Ti for sure) in one frame (assuming at least 25 FPS, so in about 40 miliseconds), but I can reach this with FireMonkey, even when Delphi creators brags that it is lightnight fast and GPU accelerated. And if I replace rectangle with circle (FillArc method), when I draw 100 circles, it took about same time as 10 000 rectangles. Same with outputing letters (one-char texts). What am I doing wrong? Is there any mistake I can't see? Or it is just problem of FireMonkey? Or it is normal?
What another way I should choose than Canvas for fast drawing when I need to keep compatibility with Windows and Android?
The Firemonkey canvas on Windows is probably not using the GPU. If you are using XE6 you can
set the global variable FMX.Types.GlobalUseGPUCanvas to true in the initialization section.
Documentation
Otherwise, in XE5 stick a TViewPort3D on your Form. Stick a TLayer3D in the TViewPort3D and change it's to Projection property to pjScreen. Stick your TPaintBox on the TLayer3D.
Another alternative could be there is an OpenGL canvas unit
You could also parallel process your loop but they will only make your test faster and maybe not your real world game (Parallel loop in Delphi)
When you draw a circle in canvas (ie GPUCanvas) then you draw in fact around 50 small triangles. this is how GPUCanvas work. it's even worse with for exemple Rectangle with round rect. I also found that Canvas.BeginScene and Canvas.endScene are very slow operation. you can try to put form.quality to highperformance to avoid antialiasing, but i didn't see that it's change really the speed.
链接地址: http://www.djcxy.com/p/96700.html