I'm just playing around with FireMonkey to see if graphical painting is any faster than GDI or Graphics32 (my library of choice at the moment).
To see how fast it is, I've performed some tests, but I run into some odd behaviour:
Drawing thin lines (<1.5 pixel wide) seems to be extremely slow compared thicker lines:
- Vertical axis: cpu ticks to paint 1000 lines
- Horizontal axis: line tickness*
The results are quite stable; drawing always becomes much faster once line thickness is more than 1 pixel wide.
In other libraries there seem to be fast algorithms for single lines, and thick lines are slower because a polygon is created first, so why is FireMonkey the other way around?
I mostly need single-pixel lines, so should I paint lines in a different way maybe?
The tests were run with this code:
// draw random lines, and copy result to clipboard, to paste in excel
procedure TForm5.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var
i,iWidth:Integer;
p1,p2: TPointF;
sw:TStopWatch;
const
cLineCount=1000;
begin
Memo1.Lines.Clear;
// draw 1000 different widths, from tickness 0.01 to 10
for iWidth := 1 to 1000 do
begin
Caption := IntToStr(iWidth);
Canvas.BeginScene;
Canvas.Clear(claLightgray);
Canvas.Stroke.Kind := TBrushKind.bkSolid;
Canvas.Stroke.Color := $55000000;
Canvas.StrokeThickness :=iWidth/100;
sw := sw.StartNew;
// draw 1000 random lines
for I := 1 to cLineCount do
begin
p1.Create(Random*Canvas.Width,Random*Canvas.Height);
p2.Create(Random*Canvas.Width,Random*Canvas.Height);
Canvas.DrawLine(p1,p2,0.5);
end;
Canvas.EndScene;
sw.Stop;
Memo1.Lines.Add(Format('%f'#9'%d', [Canvas.StrokeThickness, Round(sw.ElapsedTicks / cLineCount)]));
end;
Clipboard.AsText := Memo1.Text;
end;
Update
@Steve Wellens: Indeed, vertical lines and horizontal lines are a lot faster. There's actually a difference between horizontal ones and vertical ones:
Diagonal lines: blue, Horizontal lines: green, Vertical lines: red
With vertical lines, there's a sharp difference between lines that are less than 1 pixel wide. With diagonal lines there's a slope between 1.0 and 1.5.
The strange thing is that there's hardly any difference between painting a horizontal line of 1 pixel and painting one of 20 pixels. I guess this is where hardware acceleration starts making a difference?