Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von wp_xyz »

In einem anderen Beitrag (viewtopic.php?p=121222#p121222) wurde behauptet, dass ein 200x200 Pixel Bitmap mit BGRABitmap 83mal schneller mit einer Zufallsfarbe gefüllt werden kann als bei einem TBitmap, wobei die Verfahren BGRABitmap.SetPixel() und TBitmap.Pixels[] erst auf Nachfrage genannt wurden. Außerdem wurde behauptet: "Wenn ich jetzt mit Bitmap.scanline gegen BGRA.data optimiere wird es wahrscheinlich noch übler für die TBitmap. "

Ich verstehe nicht wieso sich ein speicher-basierter Low-level Zugriff sich in der Geschwindigkeit zwischen BGRABitmap und TBitmap unterscheiden soll. Und nachdem kein Mensch ernsthaft ein großes TBitmap mit Hilfe der Pixels-Eigenschaft füllen wird, will ich diese Aussagen nicht unkommentiert stehen lassen.

Ich habe im Anhang mehrere Verfahren zum Füllen eines Bitmaps verwendet und die Zeit gemessen, ein 3000x3000 Bitmap mit blau zu füllen:
- BGRABitmap.SetPixel
- BGRABitmap.Data
- TBitmap.Pixels[]
- TBitmap.ScanLine (für 32-bit und 24-bit Pixel)
- TBitmap.RawImage.GetLineStart (für 32-bit und 24-bit)
- TBitmap und LazIntfImage

Die Werte streuen natürlich. Aber wie erwartet, ist TBitmap.Pixels[] gähnend langsam. Die anderen Bitmap Verfahren sind dagegen genauso schnell oder schneller als BGRABitmap.
Dateianhänge
speed_putpixel.png
speed_putpixel.png (15.48 KiB) 3849 mal betrachtet
speed_putpixel.zip
(2.87 KiB) 151-mal heruntergeladen

aro
Beiträge: 130
Registriert: Di 26. Jul 2011, 19:58
OS, Lazarus, FPC: Deepin 20.2; Lazarus 2.0.0 + dfsg-2
CPU-Target: 64Bit

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von aro »

Hallo,

das ist eigentlich ganz einfach. Von der Sache her ist ein Bitmap im Speicher neben den Angaben über Größe und Format eigentlich nur ein Speicherbereich, in dem jedes Pixel 1,2,3 oder 4 Byte belegt.
Man kann beim kopieren oder zeichnen problemlos und schnell diese Daten manipulieren und fertig.

Man kann natürlich so wie in TBitmap tausend mal einen neuen Gerätekontext erzeugen und wieder zerstören, Speicherinhalte kopieren und lustig durch alle Instanzen der Vorgängertypen hüpfen.

Wenn Du Dir mal den Quelltext anschaust, dann verstehst Du wieso das bei TBitmap so lange dauert.

Wenn Du was ganz schnelles brauchst dann nimm unter Windows DIBś, unter Linux BGRABitmap und für den Raspi direktes Schreiben in den Framebuffer.

Übrigens kann man BGRABitmap noch optimieren und es läuft auch noch nicht ganz fehlerfrei.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von Winni »

BGRA
aro hat geschrieben:
Fr 23. Apr 2021, 15:19
Hallo,
Wenn Du Dir mal den Quelltext anschaust, dann verstehst Du wieso das bei TBitmap so lange dauert.

Wenn Du was ganz schnelles brauchst dann nimm unter Windows DIBś, unter Linux BGRABitmap und für den Raspi direktes Schreiben in den Framebuffer.

Übrigens kann man BGRABitmap noch optimieren und es läuft auch noch nicht ganz fehlerfrei.
Ich hatte ja schon oben erläutert, dass TBitmap so langsam ist, weil es der minimale Kompromiss zwischen den verschiedenen Betriebssystemen ist.

Das schöne an BGRAbitmap ist ja genau, dass man eben nicht für jedes Betriebssystem neuen Code schreiben muss , sondern dass der gleiche Code auf den verschiedenen OS läuft.

Fehler gibt es überall. Den letzten Fehler in der TBitmap hab ich vor zwei Jahren entdeckt: ein Mem Leak. Falls Du Fehler in BGRAbitmap entdeckt hast: Immer her damit. Circular im internationalen Forum ist sehr schnell damit, die zu beheben.

Und wo kann man BGRAbitmap noch optimieren? Da bin ich gespannt! Immer her damit!

Winni

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von siro »

WOW,
ich wollte grad schreiben, mein Rechner ist dabei abgestürzt...... :shock: :mrgreen:

41 Sekunden

Anbei meine Zeiten:
Bitmap_Time.jpg
Bitmap_Time.jpg (46.39 KiB) 3816 mal betrachtet

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von wp_xyz »

Ich habe das Bild deshalb so groß gemacht, dass man die Zeit bei den schnellen Verfahren einigermaßen zuverlässig messen kann. Entsprechend wächst dann die Zeit bei der langsamsten Methode (und zum Ausgleich das Bild hier kleiner zu machen, wollte ich nicht).

Ja, dass Bitmap.Canvas.Pixels so lahm ist, war von Anfang an klar. Aber auch bei dir sieht man, dass die ScanLine Methode von TBitmap 5x schneller ist als die BGRABitmap Data Methode, die letztendlich dasselbe macht -- da gibt es einiges zu optimieren, aber nicht auf der TBitmap-Seite des Vergleichs.

aro
Beiträge: 130
Registriert: Di 26. Jul 2011, 19:58
OS, Lazarus, FPC: Deepin 20.2; Lazarus 2.0.0 + dfsg-2
CPU-Target: 64Bit

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von aro »

Hallo Winni,
Und wo kann man BGRAbitmap noch optimieren? Da bin ich gespannt! Immer her damit!

bevor ich Rentner wurde, stand ich vor dem Problem, auf einem Raspi eine kommerzielle Anwendung zu entwickeln mit anspruchsvoller Grafik, so wie ich das bisher mit DIB´s unter Windows mit Delphi gelöst habe. Als einzige sinnvolle Lösung blieb für mich eigentlich nur Lazarus unter Linux.
Zu der Zeit gab es leider noch kein BGRABitmap und TBitmap war viel zu langsam. Also habe ich eine komplett eigene Grafik entwickelt auf der Basis eines Records. ( Länge, Breite und Pointer für die Pixel) und sonst nichts! Alle Aktionen wurden ausschließlich durch kopieren der Pixel in den Pointern realisiert.
Auch Truetype -Schriften skalieren und an die gewünschte Stelle in den Speicherbereich zu kopieren habe ich völlig neu und anders als bisher gefunden gelöst.
Da ich es bisher nicht geschafft habe unter Linux64 die Pixel direkt in den Framebuffer zu kopieren, so wie auf dem Raspi, bin ich im Moment dabei BGRABitmap mit meiner Lösung zu einer super - schnellen und ressourcensparenden Lösung verbinden. Jetzt warte ich erst mal, das der Fehler in BGRABitmap.TextSize() behoben wird.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von Winni »

Hi!

Astreiner Test:

BGRAbitmap ind LazIntfImage geben blau.

Aber Bitmap Scanline und Bitmap RawImage (32) ergeben unter Linux überhaupt kein Bild, während Scanline und Bitmap RawImage (24) 2/3 grau plus 1/3 schwarz ergeben.

Was nützen mir die hohen Geschwindigkeiten, wenn ich nix sehe.

Suse Tumbleweed (64), fpc 3.2, laz 2.0.12

So ist der Test unbrauchbar. Jedenfalls plattformübergreifend.

Winni

PS Screenshot hinzugefügt
Dateianhänge
Scanline24.png
Scanline24.png (75.98 KiB) 3792 mal betrachtet
Zuletzt geändert von Winni am Fr 23. Apr 2021, 18:56, insgesamt 1-mal geändert.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von Winni »

aro hat geschrieben:
Fr 23. Apr 2021, 18:38
Hallo Winni,
Jetzt warte ich erst mal, das der Fehler in BGRABitmap.TextSize() behoben wird.
Hi!

Erzähl, wo der Fehler ist. Ich habe viel damit gearbeitet und nix entdeckt.

Winni

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von wp_xyz »

OK, ich hätt's natürlich testen sollen, dann wäre mir diese Blamage erspart geblieben. Das Problem kann man aber natürlich mit ein paar IFDEF's beheben, und die neue Version hier im Anhang läuft korrekt unter Win32/qt/qt5/gtk2/cocoa (im Prinzip auch unter gtk3, aber da sind rot und blau vertauscht, bei allen, auch bei BGRABitmap, aber ich bin dem nicht nachgegangen, weil auch Bitmap.Canvas.Pixels abstürzt, so dass ich vermute, dass gtk3 hier noch einen Bug hat).

Trotzdem: In diesem Post geht es um die Geschwindigkeit und das immer wieder verbreitete Statement, dass BGRABitmap so schnell ist. Das stimmt nur im Vergleich zu Bitmap.Canvas.Pixels.

Dass BGRABitmap die Byte-Reihenfolge automatisch richtig macht, ist natürlich ein nicht zu leugnender Vorteil gegenüber den ScanLine-Varianten. Doch LazIntfImage macht das auch richtig, und ist genauso schnell wie BGRABitmap.

Ich will BGRABitmap nicht schlecht reden - versteht mich nicht falsch. Das ist eine Wahnsinns-Bibliothek, aber nur, wenn man sie wirklich braucht. Für viele kleine Sachen allerdings würde ich mir nie so einen Dinosaurier ins Projekt holen.
Dateianhänge
speed_putpixel.zip
(3.24 KiB) 150-mal heruntergeladen

aro
Beiträge: 130
Registriert: Di 26. Jul 2011, 19:58
OS, Lazarus, FPC: Deepin 20.2; Lazarus 2.0.0 + dfsg-2
CPU-Target: 64Bit

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von aro »

Hallo Winni,

ich habe Deine Antwort noch mal gelesen und wollte sie so nicht stehen lassen.

Du schreibst :
Ich hatte ja schon oben erläutert, dass TBitmap so langsam ist, weil es der minimale Kompromiss zwischen den verschiedenen Betriebssystemen ist.
Diesen Unsinn glauben die meisten, weil es die offizielle Version ist. Die Ursachen liegen ganz wo anders. Und da muss ich etwas weiter ausholen:

Turbo - Pascal von Borland war mal zu DOS - Zeiten der beste Compiler der Welt und damit habe ich auch meine berufliche Laufbahn begonnen.

Im Delphi - Compiler leben die Gene dieses Compiler weiter. Ergänzt wurde das ganze durch die geniale Technologie der Komponenten. Aber warum auch immer hat man dann grottenschlechte Komponenten in Umlauf gebracht. Die waren so schlecht, das sie durch sinnloses Gehüpfe durch alle Instanzen bis zum 40 -fachen der eigentlichen notwendigen Zeit benötigt haben. Das ist der Grund, warum ich seit DELPHI4 fast nur noch eigene Komponenten verwendet habe!
Mit DELPHI XE habe ich es dann noch einmal versucht und endgültig entschieden, nur noch die IDE und den Compiler mit meinen eigenen Komponenten zu verwenden.

Lazarus versucht möglichst nah an Delphi zu bleiben und hat damit die Sinnlosigkeit der Komponenten durch zusätzlichen Code für unterschiedliche Betriebssysteme erweitert.

TBitmap ist zu komplex um als Beispiel gut geeignet zu sein. TEdit ist einfacher gestrickt und deshalb besser geeignet.

Um Text in einem Editfenster auszugeben sind zwei Dinge notwendig. Man muss dem Betriebssystem eine Zeichenkette übergeben und das Betriebssystem "malt" dann jedes Zeichen skaliert nach einer Funktion die in der ausgewählten Trueschrift - Datei gespeichert ist.
Man kann natürlich bevor man in dem Betriebssystem oder der entsprechenden Schnittstelle die Funktion aufruft sinnlos durch alle Instanzen hüpfen, wie es Delphi und leider auch Lazarus tun. Obwohl die meiste Zeit für das eigentliche malen des Zeichnen benötigt wird hat es Delphi geschafft die 40- fache Zeit zu verbraten! Ich tue es nicht !

Nach dem WINDOWS 10 im Übermut beim letzten Update der Meinung war, das es mein komplettes Benutzerverzeichnis einfach mal löschen sollte, gibt es für mich nur noch Linux und damit auch nur noch Lazarus. Jetzt starte ich den Turbo, in dem ich eine Komponente nach der anderen ausmiste, so wie ich es in Delphi getan habe. Und vollkommen unbeeindruckt was andere davon halten ! Viel zu lange hat MICROSOFT entschieden, was ich mit meinen Computer machen darf !

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von sstvmaster »

Hallo aro,

dann stelle doch deinen Code der Allgemeintheit zur Verfügung, damit aus den langsamen Lazarus Komponenten schnelle Turbo Pascal Komponenten werden.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von Winni »

Hallo!

Ich glaube die Dikussion bzgl. der verschiedenen Bitmap-Formate und der zugehörigen Geschwindigkeiten geht in eine falsche Richtung.

Das überzeugendste Argument für BGRAbitmap wahren seinerzeit die Fließkomma-Koordinaten, womit BGRA ein echtes Antialiasing bietet und die Zeit der zackigen Konturen und der eckigen Buchstaben ein Ende hatte.

Des weiteren kümmert sich BGRA um die Internas der Betriebssysteme und spart mir so immens Zeit.

Und BGRA biete eine derartige Fülle von Funktionen, die ich mir nicht mehr selbst ausdenken muss.
Ich zähle hier nur mal einen Teil auf- bevor es ermüdent wird:
* Alpha-Kanal (Transparenz) von Hause aus: Blue Green Red Alpha. Also keine Klimmzüge mehr unter Windows notwendig.
* Füllen aller erdenklichen geometrischen Formen entweder algorithmisch oder mit einer Bitmap
* Zahlreiche geometrische Funktion bis hin zu FillQuadPerspectiveMappingAntialias: 4 Original Eckpunkte rein, 4 Zielpunkte für die Ausgabe, fertig ist die Perspektive
* Unzählige Filter wie Rotation, Schärfen, Unscharf, Emboss, Verpixelung, Sphere, und und und
* Ein eingebauter s/w-Scanner. Eigentlich für den internen Gebrauch gedacht, aber astrein auch für s/w-Icons brauchbar
* Einen BGRAcanvas2D der sich stark an HTML5 anlehnt
* Effekte wie Phong mit dem sich sehr gut Pseudo-3D-Effekte erzielen lassen
* und und und

Dem Argument "BGRA ist fett" wird entgegengewirkt, indem es in zahlreiche Units aufgesplittet ist und man nur die benötigten einbinden muss.

Ich kenne keine Grafik-Bibliothek, die derart komplett ist. Und die permanent erweitert wird. SVG ist gerade die aktuelle Baustelle. Mit Vorsicht schon halbwegs benutzbar.

Winni

PS.: Wen es interessiert: Zum Start mal die BGRAdefaultBitmap.pas durchlesen
PS2.: Und ein intelligentes (nicht rekursives) FloodFill. gtk2 kann das immer noch nicht.

aro
Beiträge: 130
Registriert: Di 26. Jul 2011, 19:58
OS, Lazarus, FPC: Deepin 20.2; Lazarus 2.0.0 + dfsg-2
CPU-Target: 64Bit

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von aro »

Hallo sstvmaster,
Hallo aro,

dann stelle doch deinen Code der Allgemeintheit zur Verfügung, damit aus den langsamen Lazarus Komponenten schnelle Turbo Pascal Komponenten werden.
Das geht leider noch nicht, da TBGRABitmap noch nicht fehlerfrei läuft. Siehe mein Beitrag : TBGRABitmap Absturz durch .TextSize() Nachvollziehbar mit kurzem Quelltext

Ein wesentlicher Punkt meiner Entwicklung, die ich vor Jahren mal für den Raspi benötigt hatte, ist es Texte auf meine Grafik in Trueschrift und mit echtem Antialiasing zu kopieren. Und zwar viel einfacher, schneller und Resourcenschonender als es derzeit üblich ist. Aber dazu benötige ich unbedingt die exakte Breite des Strings in Pixel, was derzeit noch nicht funktioniert!

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von Winni »

aro hat geschrieben:
So 25. Apr 2021, 18:06
Aber dazu benötige ich unbedingt die exakte Breite des Strings in Pixel, was derzeit noch nicht funktioniert!
Hi aro!

Ich hatte Dich oben schon gebeten, zu zeigen, wo es bei TextSize hapert.

Mir sind keine Probleme bekannt und im BGRA Board habe ich auch nix gelesen.
Außerdem gibt es simple Workarounds - falls da wirklich was sein sollte.

Winni

aro
Beiträge: 130
Registriert: Di 26. Jul 2011, 19:58
OS, Lazarus, FPC: Deepin 20.2; Lazarus 2.0.0 + dfsg-2
CPU-Target: 64Bit

Re: Geschwindigkeit TBitmap im Vergleich zu BGRABitmap

Beitrag von aro »

Hallo Winni,
Hi aro!

Ich hatte Dich oben schon gebeten, zu zeigen, wo es bei TextSize hapert.
Hier noch mal die Wiederholung :
Das geht leider noch nicht, da TBGRABitmap noch nicht fehlerfrei läuft. Siehe mein Beitrag : TBGRABitmap Absturz durch .TextSize() Nachvollziehbar mit kurzem Quelltext
Lade Dir bitte die paar Zeilen Dateianhang runter und probiere es selbst aus. Möglicherweise verwendest Du ja ein anderes Betriebssystem oder eine andere Lazarus - Version.
Für den Entwickler wäre es sicher sehr interessant ob der Fehler immer auftritt, oder nur bei einer bestimmten Konstilation.

Antworten