Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   GDI+ Performance Tipps (https://www.delphipraxis.net/162456-gdi-performance-tipps.html)

Neutral General 23. Aug 2011 18:11

GDI+ Performance Tipps
 
Hallo,

Beschäftige mich seit ein paar Tagen etwas mit GDI+.

Mein Code ist momentan folgender:
(Nutze die GDI+ Library von http://www.bilsen.com/gdiplus/index.shtml)

Delphi-Quellcode:
type
 TForm1 = class(TForm)
    ApplicationEvents1: TApplicationEvents;
    procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
    procedure FormCreate(Sender: TObject);
  private
    FAngle: Single;
    FBild1, FBild2: IGPBitmap;
    FBack: IGPBitmap;
  public
    { Public-Deklarationen }
  end;

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  FBild1 := TGPBitmap.Create('Background.jpg');
  FBild1.ConvertFormat(PixelFormat32bppPARGB,DitherTypeNone,PaletteTypeOptimal);
  FBild2 := TGPBitmap.Create('Typ.png');
  FBild2.ConvertFormat(PixelFormat32bppPARGB,DitherTypeNone,PaletteTypeOptimal);

  FBack := TGPBitmap.Create(Width,Height);
end;
Jetzt das eigentliche Zeichnen:

Delphi-Quellcode:
procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
var Attr: IGPImageAttributes;
    Matrix: TGPColorMatrix;
    Graph1, Graph2: IGPGraphics;
begin
  // Zum Zeichnen auf das Offscreen-Bitmap
  Graph1 := TGPGraphics.Create(FBack);
  // Hintergrund malen
  Graph1.DrawImage(FBild1,0,0);
 
  // ColorMatrix initialisieren (--> Alpha Transparenz 60%)
  Matrix.SetToIdentity;
  Matrix.M[3,3] := 0.6;
 
  // Image-Attributes erstellen für Transparent-Color = Blau und Alpha Transparenz (s.o).
  Attr := TGPImageAttributes.Create;
  Attr.SetColorKey(TGPColor.Blue,TGPColor.Blue,ColorAdjustTypeBitmap);
  Attr.SetColorMatrix(Matrix,ColorMatrixFlagsDefault,ColorAdjustTypeBitmap);
 
  // Rotierendes, Alpha-Transparentes Bild mit Transparent-Color (blau) zeichnen
  Graph1.TranslateTransform(FBild2.Width / 2,FBild2.Height / 2);
  Graph1.RotateTransform(FAngle);
  Graph1.DrawImage(FBild2,-FBild2.Width / 2,-FBild2.Height / 2,
                   FBild2.Width,FBild2.Height,0,0,FBild2.Width,
                   FBild2.Height,TGPUnit.UnitPixel,Attr);
  Graph1.ResetTransform;

  // Zum Zeichnen des Offscreen-Bitmaps auf das Formular
  Graph2 := TGPGraphics.Create(Canvas.Handle);
  Graph2.DrawImage(FBack,0,0);

  FAngle := FAngle + 1;

  Done := false;
end;
Jetzt wäre meine Frage wie man da (und auch generell) noch ein paar FPS rauskitzeln kann.
Z.B. hat das setzen des Pixelformats der Bitmaps auf PixelFormat32bppPARGB die Framerate quasi verdoppelt.

Gibt es sonst noch irgendwelche Tricks?
Auch bzgl. Dingen, die in meinem Beispiel-Code vllt. nicht benutzt werden.

Gruß
Neutral General

rollstuhlfahrer 23. Aug 2011 20:03

AW: GDI+ Performance Tipps
 
Jetzt gäbe es da noch die Rückfrage, um wie viele fps es sich denn handelt. Mehr als 60 stellt der Bildschirm eh nicht dar, solange es ein TFT ist.

Bernhard

Namenloser 23. Aug 2011 20:12

AW: GDI+ Performance Tipps
 
Betriebssystem wäre eventuell auch noch relevant, da GDI+ unter manchen Betriebssystemen Hardwarebeschleunigung nutzt und unter anderen nicht. Konkret helfen kann ich leider nicht... habe GDI+ selbst noch nie verwendet.

EWeiss 23. Aug 2011 20:23

AW: GDI+ Performance Tipps
 
Ich würde die Bilder nicht ins PixelFormat32bppPARGB Konvertieren sondern direkt das richtige Format verwenden.
Bei den Konvertieren hast du keine kontrolle darüber wie groß die Dateien eigentlich werden.

Lieber prüfen ob deine Bilder das richtige Format verwenden anstatt sie zu Konvertieren.

Delphi-Quellcode:
   if FBild1 <> 0 then
   begin
     GdipGetImagePixelFormat(FBild1, format);
     if format = PixelFormat32bppARGB then  // Accept files with alpha channel
     begin
       GdipCreateHBITMAPFromBitmap(pointer(FBild1), hbmReturn, $000000);
       if hbmReturn <> 0 then
          Result := hbmReturn;
     end;

     GdipDisposeImage(FBild1);
   end;
Ob das jetzt einen Einfluss auf die gewünschte FPS hat ist fraglisch.
Obwohl die größe einer Datei schon einfluss darauf haben könnte!

PS:
Verstehe jetzt auch nicht warum du ein *.png Konvertieren musst.
Hat das nicht immer das PixelFormat32bppARGB ?
Wenn du nicht sicher bist kannst du ja vorher erstmal prüfen ob es vorhanden ist
ansonsten Konvertierst du etwas das schon im richtigen Format vorliegt.

Dann verwendest du quasi einen Wrapper welcher zwischen deiner Anwendung und der GdiPlus.dll rumwurschtelt
Das kann auch nochmal zu performance problemen führen.
Warum dann nicht direkt die Unit für GDIplus aus D2010 (Denke die gibt es doch Oder? )


gruss

Neutral General 23. Aug 2011 22:42

AW: GDI+ Performance Tipps
 
@rollstuhlfahrer & NamenLozer:

Das ist sehr unterschiedlich. Auf einem schwächeren Computer (Intel Core Duo 1,8GHz) (Win 7) bekomme ich ca. 15 FPS, bei mir Zuhause auf einem i5 4x2,66GHz (Win 7) bekomme ich ca. 45 FPS (Ohne Ändern des Pixelformats sind es gerade mal 25).

Wobei die FPS aber auch sehr davon abhängen wie viel überhaupt sichtbar ist. Wenn ich das Formular sehr klein mache und man nur noch einen kleinen Ausschnitt sieht (250x350) bekomme ich fast 100 FPS.

Wobei es mir aber ganz unabhängig von den bisherigen FPS um darum ging von euch ggf. kleinere oder größere Tricks/Tipps zu erfahren um das ganze noch ein bisschen besser/schneller zu machen.

@EWeiss:

Ja könnte noch prüfen ob das Bild nicht schon in diesem Format vorliegt.
Habe im Internet einen Post gefunden in dem jemand empfiehlt dieses Pixelformat zu verwenden (weil: weiß ich nicht mehr genau). Hab es dann ausprobiert und es hat tatsächlich einen deutlichen Geschwindigkeitsschub gebracht ;)

Der Wrapper wird sicher ein bisschen ausbremsen. Aber ich würde fast behaupten, dass man das kaum spüren dürfte, da die Methoden der Klassen größtenteils 1:1 die GDI+ Funktionen kapseln und dadurch nicht viel mehr Overhead als der zusätzliche Methodenaufruf entstehen sollte.


Mir ging es auch um allgemeine Tipps wie
"Verwende niemals das-und-das, weil das ist total langsam! Machs lieber so-und-so!"

Falls da jemand aus seiner Erfahrung irgendetwas derartiges berichten kann, würde ich mich freuen :)

EWeiss 23. Aug 2011 23:26

AW: GDI+ Performance Tipps
 
Zitat:

Ja könnte noch prüfen ob das Bild nicht schon in diesem Format vorliegt.
War nur ein Tip von mir ;)
Macht nicht wirklich sinn alles doppelt zu machen.

gruss

ehX 24. Aug 2011 00:28

AW: GDI+ Performance Tipps
 
Zitat:

Verwende niemals das-und-das, weil das ist total langsam! Machs lieber so-und-so!"
Sorry, aber muss sein:
Verwende niemals GDI+, weil das ist total langsam. Machs lieber mit Direct2D oder auch OpenGL....vor Allem....in der derzeitigen W7-Welt, warum noch was neues mit GDI+ entwicklen?


*duck* :duck:


P.S: Ja, es IST komplizierter und JA, nicht jeder 0815-Consumer-PC kann es gut...aber der kann auch kein GDI+ gut (schnell) rendern.
Also: Blut lecken und das richtige für Grafik nehmen :-)

Folgender Artikel solle auch darüber Aufschluss geben, warum GDI+ zwar hardwarebeschleunigt, aber dennoch veraltet und unterlegen ist, bzw. für neue Projekte nicht mehr verwendet werden sollte:
http://blogs.msdn.com/b/directx/arch...d-and-gdi.aspx

P.P.S: Sobald du die GPU mal unter Kontrolle hast, magst du nie mehr zurück zur CPU oder Pseudo-GPU-Beschleunigung für das Rendering, glaub mir :)

Neutral General 24. Aug 2011 12:05

AW: GDI+ Performance Tipps
 
Hallo,

Ja DirectX ist immer sone Sache :mrgreen:
Hab es bisher nie geschafft so richtig da rein zu kommen.

Man findet überall im Internet Initialisierungs-Code für DX (D3D), aber dann hört es auch schon fast auf.
Und dann bin ich immer etwas erschlagen von den tausenden Funktionen und Konstanten und weiß nicht mehr wo ich da jetzt weiter ansetzen soll.

Das was ich jetzt mit GDI+ mache war auch weil ich mir mal ein paar GDI+ Kenntnisse aneignen wollte.
Ob ich damit irgendwas ernsthaftes programmiert hätte, kann ich nicht sagen ;)

EWeiss 24. Aug 2011 13:35

AW: GDI+ Performance Tipps
 
Zitat:

warum noch was neues mit GDI+ entwicklen?
Weil es spass macht?
Und nicht jeder das machen muss was dir so vorschwebt?

Und Messbar langsamer?
Denke mal nicht.
Nur weil die Zeichenoperationen von der GPU, quasi ausgelagert werden ist das nicht schneller für mich.
Rechne die auslastung der GPU auf die CPU um dann ist es genauso langsam..
Es wird also nur suggestiert das man mit DX schneller ist.

Zitat:

P.P.S: Sobald du die GPU mal unter Kontrolle hast, magst du nie mehr zurück zur CPU oder Pseudo-GPU-Beschleunigung für das Rendering, glaub mir
Bla, bla

Ich gebe nichts auf Blogs die irgendwelche vergleiche ziehen vor allem dann nicht wenn es der Hersteller selber ist.


gruss

Namenloser 24. Aug 2011 13:55

AW: GDI+ Performance Tipps
 
Zitat:

Zitat von EWeiss (Beitrag 1119285)
Und Messbar langsamer?
Denke mal nicht.
Nur weil die Zeichenoperationen von der GPU, quasi ausgelagert werden ist das nicht schneller für mich.
Rechne die auslastung der GPU auf die CPU um dann ist es genauso langsam..
Es wird also nur suggestiert das man mit DX schneller ist.

Ähm wat. Und ob GPUs bei Grafikverarbeitungen schneller (und effizienter) sind... das liegt einfach an der anderen Architektur. Der Unterschied ist gewaltig (eine GPU ist u.U. locker 1000× so schnell wie eine CPU, wenn nicht mehr).

Messbar ist der Unterschied also auf jeden Fall. Spürbar nicht unbedingt, je nachdem, was man macht...

Neutral General 24. Aug 2011 13:55

AW: GDI+ Performance Tipps
 
Klar, man muss ja die GDI+ nicht direkt als tot hinstellen und ich denke für viele Sachen ist GDI+ um einiges besser geeignet und auch einfacher als DX.

Allerdings ist DirectX schon schneller als die GDI+. Denke nicht, dass man damit Echtzeit-Graphik mit mehr als vllt. 30 FPS darstellen kann (Es sei denn es hat ne Auflösung von 300x200 oder so).

Aber dafür ist die GDI+ meiner Meinung nach auch nicht Gedacht. Um so schöne Programme zu machen wie EWeiss bietet sich GDI+ an. Für Spiele ist DX sicher besser geeignet.

DeddyH 24. Aug 2011 13:59

AW: GDI+ Performance Tipps
 
Eben, um einen Nagel in die Wand zu schlagen benutzt man zweckmäßigerweise einen Hammer. Zum Auswechseln von Zündkerzen ist er aber nur sehr bedingt geeignet. Es kommt also auf den Verwendungszweck an, welches Werkzeug die bessere Wahl ist.

EWeiss 24. Aug 2011 14:07

AW: GDI+ Performance Tipps
 
Zitat:

Zitat von NamenLozer (Beitrag 1119293)
Zitat:

Zitat von EWeiss (Beitrag 1119285)
Und Messbar langsamer?
Denke mal nicht.
Nur weil die Zeichenoperationen von der GPU, quasi ausgelagert werden ist das nicht schneller für mich.
Rechne die auslastung der GPU auf die CPU um dann ist es genauso langsam..
Es wird also nur suggestiert das man mit DX schneller ist.

Ähm wat. Und ob GPUs bei Grafikverarbeitungen schneller (und effizienter) sind... das liegt einfach an der anderen Architektur. Der Unterschied ist gewaltig (eine GPU ist u.U. locker 1000× so schnell wie eine CPU, wenn nicht mehr).

Messbar ist der Unterschied also auf jeden Fall. Spürbar nicht unbedingt, je nachdem, was man macht...

Erstelle eine Anwendung in DX und mit GDI+
Nimm ne Grafikkarte welche das Rendern über GPU nicht unterstützt
Dann sage mir ist DX schneller oder nicht ? ;)

Was ist dann noch Messbar!
Wenn schon vergleiche anstellen dann zu gleichen bedingungen.

Zitat:

Eben, um einen Nagel in die Wand zu schlagen benutzt man zweckmäßigerweise einen Hammer.
Was ich sage :) Bin deiner Meinung!

Zitat:

Für Spiele ist DX sicher besser geeignet.
Jup

gruss

Namenloser 24. Aug 2011 15:21

AW: GDI+ Performance Tipps
 
Zitat:

Zitat von EWeiss (Beitrag 1119305)
Erstelle eine Anwendung in DX und mit GDI+
Nimm ne Grafikkarte welche das Rendern über GPU nicht unterstützt

derp.

ehX 24. Aug 2011 16:56

AW: GDI+ Performance Tipps
 
Zitat:

Nimm ne Grafikkarte welche das Rendern über GPU nicht unterstützt
Dann sage mir ist DX schneller oder nicht ?

Was ist dann noch Messbar!
Wenn schon vergleiche anstellen dann zu gleichen bedingungen.
Das sind die gleichen Bedingungen, wenn man DirectX die Basis raubt (keine DX-Graka)?
Wobei selbst onboard-Chips, die vor 5-10 jahren hergestellt wurden, das bereits ganz ok können..

Dem mit dem "es wird einem nur suggeriert, dass DX schneller ist" kann ich nicht zustimmen...ich arbeite ja selbst mit DX / OpenGL und hab auch ein paar Sachen mit GDI(+) gemacht.
Weiss nicht, aber die beiden als Äquivalent in der Performance darzustellen, ist wie zu sagen "Ja, und? Ein Porsche kann im Stadtverkehr ja auch nur 50 fahren wie mein Fiesta, da merkt man ja keinen Unterschied"
Naja, ich glaube, die Diskussion ist müßig...
Jeder macht das, was ihm Spass macht, und gut ist :-)
Ich wollte Neutral General eigentlich nur den Tipp geben, es mal damit zu versuchen.
Denn was für GDI(+) und den Spassfaktor angeht, gilt für DX/OpenGL noch mehr: Es macht tierisch Spass, damit herumzuexperimentieren, wenn man mal Blut geleckt hat und man hat fast unbegrenzte Möglichkeiten, wenn man es mal verstanden hat.

EWeiss 24. Aug 2011 17:27

AW: GDI+ Performance Tipps
 
Zitat:

Jeder macht das, was ihm Spass macht, und gut ist
:thumb:

gruss

brechi 24. Aug 2011 20:03

AW: GDI+ Performance Tipps
 
schonmal versucht nicht jedes mal TGPGraphics zu erstellen sondern einmal global?
Und unter GDI funktioneirt pf24Bit eignetlich immer am schnellsten, kenn mich mi GDI+ net wirklch aus

Neutral General 24. Aug 2011 21:09

AW: GDI+ Performance Tipps
 
Zitat:

Zitat von brechi (Beitrag 1119416)
schonmal versucht nicht jedes mal TGPGraphics zu erstellen sondern einmal global?
Und unter GDI funktioneirt pf24Bit eignetlich immer am schnellsten, kenn mich mi GDI+ net wirklch aus

Hallo,

Also das Problem bei TGPGraphics ist, dass die HDCs sich dauernd ändern und man dann nach ner halben Sekunde ins nichts malt. Hab das schon ausprobiert.

Also von der GDI weiß ich nur dass TBitmap + Scanline im pf32Bit Modus um einiges schneller ist als im 24-Bit Modus. Und das Pixelformat dass ich bei GDI+ gerade verwende war gefühlt auch das schnellste.

VT 30. Jul 2013 16:14

AW: GDI+ Performance Tipps
 
@Neutral General

Den größten Performancesprung kannst du machen indem du den VCL internen Rendercode aushebelst (erklär ich jetzt mal nicht, bei bedarf nachhaken) und du TGPCachedBitmap verwendest anstatt TGPImage. Die "cached bitmaps" werden im optimierten Format für den Canvas abgelegt und sind somit rasend schnell mit GDI+ gezeichnet über TGPGraphics.DrawCachedBitmap().


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz