First let me congratulate those that have coded the graphics subsystem in Lazarus. It's rare to find such complete implementation of EVERYTHING in one library. I have been going over the classes and units these past two days - and man you guys have been busy!
But I am a bit worried about graphics performance in my Lazarus components.
I coded a small image viewer (code here:
http://delphimax.wordpress.com/2010/09/20/platform-independent-image-component-for-lazarus/) but the speed of Draw() and Copy() (a.k.a "blitting") and Fillrect to the background is well... slow to say the least (on the mac - not so much on windows).
The same code runs flawlessly on Delphi with no lagging (i use winapi bitblt in delphi), but on my mac - wich is a very fast and powerfull machine, it lags behind in higher resolutions.
The natural solution would be to backbuffer the loaded image in a DIB and then use blitting all the way -- but is bitblt emulated in Lazarus? I seem to remember someone saying that. If so, does it call a pixelwriter for each pixel to copy - or does it copy data row-by-row? Is it a wrapper for a call to the native OS, or implemented in pure pascal?
Also, I noticed in the pixmap unit that the Canvas parameter is passed as static rather than constant. That's a lot of CPU overhead for a parameter that is never altered, it will be copied for each call (!) It should be const, especially the procedures that are called hundreds if not thousands of times (such as pixelwriters).
You can also gain some speed by passing parameters in records, and it doesnt make the code harder to maintain either, for example:
Type
PDrawLineInfo = ^TDrawLineInfo;
TDrawlineInfo = Record
ldiFormat:TPixelFormat;
ldix1:Integer;
ldiy1:Integer;
(.. etc..)
End;
(* The method below has little stack penalty and the compiler
will probably use a register when optimizing.
Either way the overhead is avoided which is
critical when it comes to graphics performance *)
Procedure FastDrawLine(Const Info:PDrawLineInfo);
Begin
(* No testing here. This method should only be called by
the canvas implementation AFTER everything is OK.
Including clipping *)
end;
Also passing raw pixeldata as static longwords should be avoided. You can get a speed boost by typecasting the data:
(* this is quite slow *)
Procedure WritePixel(MyPixel:TRGBQuadData;TargetAddr:TUniPTR);
Begin
(.. do stuff ..)
end;
(* This is faster when called hundreds of times.
It will be even faster by passing an info-record pointer
if more variables are required *)
Procedure WritePixel32(Const MyPixel;var Target);
Begin
TRGBQuad(target):=TRGBQuad(mypixel);
end;
Are there any tips to how i can speed up normal canvas drawing? Any equ. to DIBS that are platform independent? There is no hope in hell that i can port over my graphics-editor to Lazarus for Mac & Linux using the normal canvas interface. This is a real bummer for me, I'm sort of banking on Lazarus for Mac development in 2011
Any plans for a revision of the wonderfull graphics sub-system?