Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Suche Schnelle Alternative zu "CopyRect" (https://www.delphipraxis.net/122573-suche-schnelle-alternative-zu-copyrect.html)

Corpsman 18. Okt 2008 15:43


Suche Schnelle Alternative zu "CopyRect"
 
Hi Leuts,

Ich hab da mal vor Langer Zeit nen Screensaver geschrieben. Dieser geht auch richtig rockig schnell und hat 0 % CPU Load auf all meinen Systemen.

Wie der das Erreicht ist ganz Einfach, ich lagere alle Aufgaben Dank OpenGL auf die Grake aus.

Auf meinem Desktop Rechner ist das OK, den die Gforce 8800 gts von mir läuft eh immer mit Voller Rate.

Doch nu hab ich ja auch ein Notebook, da hab ich ebenfalls 0 % CPU load, aber da die Grake Gforce 8400 M wohl zwischen 3D und 2D mode umschalten kann ändert sich die Temperatur doch deutlich.

Soviel zum Hintergrund.

Nu Dachte ich mir, der Screensaver macht eh nur 2D ( nutzt also OpenGL eigentlich gar nicht in seiner eigentlichen 3D Eigenschaft )

Schreibe ich den Source einfach um, auf Ohne OpenGL und hab dafür dann ein bischen mehr CPU Load.

Also habe ich nun ein TBitmap genommen das in das ich "Reinrendere" und das ich am Ende dann mittels Canvas.draw auf meine Form1 ausgebe.

Zum Eigentlichen Problem.

Mein Screensaver geht her und Kopiert nun aus 10 weiteren ( deutlich kleineren ) Tbitmaps Teile in 1:1 auf das Temp TBitmap

Das macht er aber viel zu langsam, in der OpenGL variante machte ich das mit GlCallLists und da gings rockig.

Mit meinem Bisherigen Ansatz kriege ich gerade mal 16 FPS hin, ich will aber schon 60 ( und die braucht der Effeckt auch )haben ...

Bisher hab ich es mit 2 varianten probiert, einmal mittels Copyrect und einmal mittels Scanline ( scanline brachte dabei gerade mal 7 FPS ).

Hat von euch noch jemand ne Idee wie ich das hier beschleunigen könnte.

Delphi-Quellcode:
Procedure CopyRect(Const Source, Dest: Tbitmap; SourceX, SourceY, DestX, DestY: Integer);
Type
  PBGR = ^TBGR;

  TBGR = Record
    B, G, R: Byte;
  End;
Var
  p1, p2: PBGR;
  i, j: Integer;
  w, h: Integer;
Begin
  w := Dest.Width - 1;
  h := dest.height - 1;
  For j := 0 To 11 Do Begin
    If h >= DestY + j Then Begin
      p1 := source.ScanLine[SourceY + j];
      inc(p1, sourceX);
      p2 := Dest.ScanLine[DestY + j];
      inc(p2, DestX);
      For i := 0 To 7 Do
        If w >= DestX + i Then Begin
          p2^.B := p1^.B;
          p2^.G := p1^.G;
          p2^.R := p1^.R;
          inc(p2);
          inc(p1);
        End;
    End;
  End;
End;

Procedure TASCII_Font.RenderChar(Const Canvas: TBitmap; x, y: Integer; Number: integer; Color: Integer);
Var
  vx, vy: Integer;
Begin
  //  vx := (Number Mod 32) * Fcharwidth;
  vx := (Number Mod 32) Shl 3;// Fcharwidth = 8
  //  vy := (number Div 32) * FCharHeight;
  vy := (number Shr 5) * FCharHeight;// FCharHeight = 12

  //  Das hier gibt 7 FPS
  //  copyrect(fonts[color], Canvas, vx, vy, x, y);

  // Das hier gibt 16 FPS
  canvas.canvas.CopyRect(
    rect(x, y, x + FCharwidth, y + FCharHeight),
    fonts[color].canvas,
    rect(vx, vy, vx + FCharwidth, vy + FCharHeight));
End;

Luckie 18. Okt 2008 16:08

Re: Suche Schnelle Alternative zu "CopyRect"
 
Hast du es schon mal mit MSDN-Library durchsuchenBitBlt probiert?

MSSSSM 18. Okt 2008 21:04

Re: Suche Schnelle Alternative zu "CopyRect"
 
Nutzt du TImage?
Oder nimmst du ein TBitmap und renderst das auf die Form?
Nimm dann eine Paintbox bzw. den Canvas der Form.

Editz: Ach nee, das ist ja son erfahrener Typ :lol:

turboPASCAL 18. Okt 2008 21:50

Re: Suche Schnelle Alternative zu "CopyRect"
 
Zitat:

Zitat von Luckie
Hast du es schon mal mit MSDN-Library durchsuchenBitBlt probiert?

Mach das so, bzw. versuch es so.

Corpsman 19. Okt 2008 10:52

Re: Suche Schnelle Alternative zu "CopyRect"
 
OK thx, werde das mit BitBLT mal Austesten.

Ich nutzte immer TBitmap, da ich da am Leichtesten an die Ferben und Daten ran komme, ist TImage besser ?

Und ja ich rendere der art das ich sage

Delphi-Quellcode:
Begin
Bitmap.clear;
RendertoBitmap;
Form1.canvas.draw(0,0,Bitmap);
End;
@MSSSSM
Zitat:

Editz: Ach nee, das ist ja son erfahrener Typ
Mein Sarkassmus zu DE Compiler ist Kaputt, Was willst du mir damit sagen ?

[Edit]

Also ich hab das nu so

Delphi-Quellcode:
Procedure TASCII_Font.RenderChar(Const Canvas: TBitmap; x, y: Integer; Number: integer; Color: Integer);
Var
  vx, vy: Integer;
Begin
  //  vx := (Number Mod 32) * Fcharwidth;
  vx := (Number Mod 32) Shl 3;
  //  vy := (number Div 32) * FCharHeight;
  vy := (number Shr 5) * FCharHeight;

  BitBLT(canvas.Handle, x, y, 8, 12, fonts[color].Handle, vx, vy, SRCCOPY);
//  copyrect(fonts[color], Canvas, vx, vy, x, y);
//  canvas.canvas.CopyRect(
//    rect(x, y, x + FCharwidth, y + FCharHeight),
//    fonts[color].canvas,
//    rect(vx, vy, vx + FCharwidth, vy + FCharHeight));
End;
Probiert, was bassiert ist das ich deutlich mehr CPU Load bekomme, aber nichts sehe, d.h. ich habe BitBLT wohl Falsch parametrisiert, nur verstehe ich nicht was ich falsch gemacht haben soll..

Phantom1 19. Okt 2008 11:54

Re: Suche Schnelle Alternative zu "CopyRect"
 
probiers mal so:

Delphi-Quellcode:
BitBLT(canvas.Handle, x, y, 8, 12, fonts[color].canvas.Handle, vx, vy, SRCCOPY);

Corpsman 19. Okt 2008 15:52

Re: Suche Schnelle Alternative zu "CopyRect"
 
*g*

fast

Delphi-Quellcode:
  BitBLT(canvas.canvas.Handle, x, y, 8, 12, fonts[color].canvas.Handle, vx, vy, SRCCOPY);
Aber das Bringt auch nur 17-18 Frames.

Das ist zwar besser, aber immer noch gut 20 - 40 FPS zu wenig

Es scheint aber das BitBLT die Last besser auf die beiden CPU's verteilt als CopyRect ...

jfheins 19. Okt 2008 15:58

Re: Suche Schnelle Alternative zu "CopyRect"
 
Also wesentlich schneller als BitBlt kann man imho nichtkopieren ... demzufolge sollte der Flaschenhals woanders liegen ;)

Es sei denn ... was kopierst du denn da eigentlich?

P.S. Es ist verwirrend wenn du dein Bitmap canvas nennst :stupid:

Luckie 19. Okt 2008 16:31

Re: Suche Schnelle Alternative zu "CopyRect"
 
Zitat:

Zitat von Corpsman
Es scheint aber das BitBLT die Last besser auf die beiden CPU's verteilt als CopyRect ...

Diese Aussage ist Blödsinn. Eine API Funktion kann nicht gleichzeitig auf meherern CPUs ausgeführt werden.

Corpsman 20. Okt 2008 09:42

Re: Suche Schnelle Alternative zu "CopyRect"
 
Die BitBLT funktion wird ja knapp 200 - 400 mal pro Frame aufgerufen, daher denke ich das der Sceduler evtl ab und zu eine andere CPU zuteilt.

Nachdem ich an dem Programm lediglich die OpenGL Dinge gegen TBitmap ausgetauscht habe, fällt es mir auch schwer zu glauben das der Rest des Programmes eine Hohe CPU Load erzeugen soll.

Zudem erzeugt die OpenGl version ja gar keine CPU Load ...

Egal wie ich gehe davon aus das es so, einfach nicht schneller geht.

Ich habe da noch eine Idee die die OpenGL Befehle nachbaut, evtl macht dieser ansatz das schneller, aber da mus ich gut nen Tag dran Rumprogrammieren. Ich werde die Ergebnisse dann hier Posten.

EWeiss 20. Okt 2008 11:17

Re: Suche Schnelle Alternative zu "CopyRect"
 
Zitat:

Zudem erzeugt die OpenGl version ja gar keine CPU Load ...
Wie denn auch OpenGL nutzt die Grafikkarte und weniger die CPU.
Bei BItBlt ist das genau umgekehrt die API hat mit deiner Grafikkarte(Hardware) nix zu tun
Deshalb geht das voll auf die CPU

das einzigste was mit BitBlt gleich kommt ist GDI
GdipDrawImageRectRectI

Schau dir das Beispiel Blub von turboPascal an

gruss Emil

turboPASCAL 20. Okt 2008 12:12

Re: Suche Schnelle Alternative zu "CopyRect"
 
Wie gross sind denn die Bitmaps die du kopieren möchtest und wie wird das Endergebnis auf dem Bildschirm
angezeigt ?

Corpsman 20. Okt 2008 20:18

Re: Suche Schnelle Alternative zu "CopyRect"
 
die einzelbildchen werden ja aus großen rausgeschnitten und sind immer 8x12

das endergebniss wird dann wie bereits geschrieben mittels canvas.draw ausgegeben.

Blup 23. Okt 2008 15:07

Re: Suche Schnelle Alternative zu "CopyRect"
 
Ist das Pixelformat bei allen beteiligten Bitmaps "pfDevice", das heist gleich dem Ausgabegerät?

Corpsman 24. Okt 2008 08:04

Re: Suche Schnelle Alternative zu "CopyRect"
 
Nope ich hatte pf24bit.

Allerdings habe ich das Grad getestet, und mit pfDevice bekomme ich 2 - 3 FPS weniger als mit pf24bit. Keine Ahnung why, evtl mus der ja bei pf24bit wegen der nur 3 byte tatsächlich weniger kopieren, meine Screen Auflösung ist schlieslich 32 Bit = 4 Byte.

OldGrumpy 24. Okt 2008 23:12

Re: Suche Schnelle Alternative zu "CopyRect"
 
8x12 ist etwas krumm, schau doch mal ob 8x8 oder 8x16 bessere Ergebnisse im Speed bringen. Ausserdem kann es Speedvorteile bringen wenn aus einem zusammenhängenden Block gelesen werden kann (durchs Caching), schau doch mal ob Du die Reihenfolge der einzelnen Kopiervorgänge sortieren kannst bevor die durchgeführt werden.

Corpsman 25. Okt 2008 09:15

Re: Suche Schnelle Alternative zu "CopyRect"
 
Uff, sortieren ist halt auch "Teuer"

Witzigerweise konnte ich das Double Buffering ausmachen, und das hat mir auch noch mal 1-2 FPS gebracht, ohne das es Flackert ;)

und 8x12 ist es halt wegen der Font .. ( letzendes sind das ja Ascii Font teile die ich Kopiere ... )

Phantom1 25. Okt 2008 20:54

Re: Suche Schnelle Alternative zu "CopyRect"
 
Müssen es denn eigentlich 24bit bzw 16,7 mio farben sein? oder würden auch 15bit bzw 32767 farben reichen? denn wenn du alles auf pf15bit umstellst dürften nämlich die fps um ca 50% steigen.

Corpsman 26. Okt 2008 00:02

Re: Suche Schnelle Alternative zu "CopyRect"
 
in dem Programm selbst nutze ich nur 10 Verschiedene Farbwerte.

D.h. theoretisch würden sibat 4Bit reichen, Nur weis ich nicht in wie weit man das reinprogrammieren kann.

Momentan habe ich ein Arrey 0..9 das die RGB werte in Byte größe beinhaltet, deswegen eben 24bit...

Delphi-Quellcode:
 
Type
 
  Tvector3ub = Record
    x, y, z: Byte;
  End;

Const
 Colors: Array[0..9] Of Tvector3ub = (
    (x: 18; y: 29; z: 13),
    (x: 26; y: 43; z: 18),
    (x: 34; y: 57; z: 23),
    (x: 42; y: 71; z: 28),
    (x: 50; y: 85; z: 33),
    (x: 50; y: 87; z: 36),
    (x: 75; y: 129; z: 52),
    (x: 100; y: 171; z: 68),
    (x: 125; y: 213; z: 84),
    (x: 150; y: 255; z: 100));

Phantom1 26. Okt 2008 09:47

Re: Suche Schnelle Alternative zu "CopyRect"
 
Zitat:

Zitat von Corpsman
in dem Programm selbst nutze ich nur 10 Verschiedene Farbwerte.

Ums einfacher zu machen würde ich in dem fall warscheinlich mit 8bit arbeiten.

Zitat:

Zitat von Corpsman
Momentan habe ich ein Arrey 0..9 das die RGB werte in Byte größe beinhaltet, deswegen eben 24bit...

Könntest du evtl mal den kompletten sourcecode als download anbieten oder mir per pn zuschicken, dann könnte ich selbst mal schauen.

Corpsman 26. Okt 2008 09:53

Re: Suche Schnelle Alternative zu "CopyRect"
 
255 kriege ich in 8 bit aber doch nicht rein ...

naja, siehe PN

DeddyH 26. Okt 2008 10:25

Re: Suche Schnelle Alternative zu "CopyRect"
 
Zitat:

Zitat von Corpsman
255 kriege ich in 8 bit aber doch nicht rein ...

:gruebel: Hast Du Dich da ein wenig vertan?

Corpsman 26. Okt 2008 10:32

Re: Suche Schnelle Alternative zu "CopyRect"
 
Ich meinte 3 mal weil ja RGB .

Du hast Recht, so wie das da steht sieht das Komisch aus ;).

2^8= 256, ist mir aber schon klar

OldGrumpy 26. Okt 2008 13:10

Re: Suche Schnelle Alternative zu "CopyRect"
 
Bei 8 Bit Farbtiefe gibts grob gesagt eine Tabelle mit RGB-Werten und der "Farbwert" eines Pixels ist nur ein Index auf die Tabelle. Alternativ dazu kann man die Bits natürlich auch direkt aufteilen, 3/2/3 z.B. bei 8 Bit oder 5/5/6 bei 16 Bit. Gibt einige Möglichkeiten aus denen man sich die bequemste raussuchen kann. Auf jeden Fall sehe ich bei den Infos die Du hier bisher geliefert hast noch nicht wirklich wo da so ein Flaschenhals sein MUSS. Wenn da keine groben Implementationsschnitzer drin sind, sollte das eigentlich schon fluppen.

Corpsman 26. Okt 2008 16:15

Re: Suche Schnelle Alternative zu "CopyRect"
 
Also :

ich hatte einen Groben Schnitzer drin, und danke an Phantom1 er hat ihn gefunden.

Nun sind 56 FPS drin.

Letzendes hat Phantom1 nur verhindert das Teile des Bildes Doppelt gerendert werden. Danke an Phantom1

Die 8Bit sache mir ist klar wie das mit dem Aufteilen ansich giht, wie mans implementiert weis ich aber nicht.

Desweiteren ist das Zielcanvas ja 32 bit somit mus der Rechner noch zusätzliche Konvertierungen machen. D.h ich bin nicht sicher ob das was bringen würde...


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:26 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 by Thomas Breitkreuz