Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to draw pixels in FireMonkey

I have made the following code:

procedure TForm15.Button1Click(Sender: TObject);
var
  Bitmap1: TBitmap;
  im: TImageControl;
  Color: TColor;
  Scanline: PAlphaColorArray;
  x,y,i: Integer;
begin
  for i:= 1 to 100 do begin
    im:= ImageControl1;
    Bitmap1:= TBitmap.Create(100,100);
    try
      for y:= 0 to 99 do begin
        ScanLine:= Bitmap1.ScanLine[y];
        for x:= 0 to 99 do begin
          ScanLine[x]:= Random(MaxInt);
        end;
      end;
      ImageControl1.Canvas.BeginScene;
      ImageControl1.Canvas.DrawBitmap(Bitmap1, RectF(0,0,Bitmap1.Width, Bitmap1.Height)
                                     ,im.ParentedRect,1,true);
      ImageControl1.Canvas.EndScene;
    finally
      Bitmap1.Free;
    end;
  end;
end;

Is there a faster way to draw pixels in Firemonkey?
I aim to make a demo program using Conway's game of life.

like image 934
Johan Avatar asked Jan 24 '12 14:01

Johan


1 Answers

All the time is spent performing these two lines of code:

ImageControl1.Canvas.BeginScene;
ImageControl1.Canvas.EndScene;

You can delete all the code that works with the bitmap and the code that actually draws the bitmap and it makes not one iota of difference to the runtime. In other words, the bottleneck is the scene code not the bitmap code. And I see no way for you to optimise that.

My test code looked like this:

Stopwatch := TStopwatch.StartNew;
for i:= 1 to 100 do begin
  ImageControl1.Canvas.BeginScene;
  ImageControl1.Canvas.EndScene;
end;
ShowMessage(IntToStr(Stopwatch.ElapsedMilliseconds));

This has the same elapsed time as your code, 1600ms on my machine. If you remove the BeginScene, DrawBitmap and EndScene calls then your code runs in 3ms on my machine.

like image 169
David Heffernan Avatar answered Nov 12 '22 21:11

David Heffernan