Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert (https://www.delphipraxis.net/187255-canvas-methoden-ab-windows-6-x-vista-oft-sehr-verzoegert.html)

Delphi-Laie 11. Nov 2015 21:29

Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Hallo Delphifreunde!

Seit Jahren bastele ich an meinem Lieblingsprogamm, dem Sortierkino. Es läuft soweit auch zu meiner Zufriedenheit.

Einen Wermutstropfen gibt es dabei aber leider doch: Seit Windows mit der Majorversion 6 (konkret bei Windows 7, 8.1 und 10, andere stehen mir nicht zur Verfügung, ich vermute aber wegen der internen Ähnlichkeit, daß es schon ab Vista auftritt) ist irgendetwas bei der Darstellung bzw. graphischen Ausgabe oft sehr verzögert. Das zeigt sich wie folgt: Ich lasse ein Array in einer Schleife mit Linien darstellen, i.d.R. eine neue Startmenge, die es als nächste zu sortieren gilt. Oft geht das annehmbar schnell (bis Windows XP grundsätzlich), jedoch ist das ab Windows 7 oft deutlich verzögert, ja geradezu quälend langsam. Das tritt aber nur sporadisch, wenn auch ziemlich oft auf.

Nun glaubte ich, mit dem Setzen von Prioritäten im Umfeld dieser Schleife, und dabei gleich die "volle Ladung":

Delphi-Quellcode:
SetPriorityClass(GetCurrentProcess,REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
for l:=0 to pred(Form1.SpinEdit2.Value) do linie_zeichnen(l,false);
SetPriorityClass(GetCurrentProcess,NORMAL_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_NORMAL)
diesem unerwünschten Programmverhalten ein Schnippchen schlagen zu können, aber so simpel kann ich mein Ziel nicht erzwingen. linie_zeichnen ist etwas komplexer:

Delphi-Quellcode:
procedure linie_zeichnen(x:word;darueber_loeschen:boolean);
begin
application.processmessages;
if ((Form1.ComboBox1.ItemIndex=4) or (Form1.ComboBox1.ItemIndex=20)) and not Form1.Visible
then Form2.Canvas.Pen.Color:=clblack
else Form2.Canvas.Pen.Color:=Menge[x].farbe;
Form2.Canvas.MoveTo(x,pred(Form1.SpinEdit3.Value));
Form2.Canvas.LineTo(x,Form1.SpinEdit3.Value-Menge[x].schluessel);
if darueber_loeschen then
  begin
  Form2.Canvas.Pen.Color:=clWhite;
  Form2.Canvas.LineTo(x,0)
  end;
if sortierung_laeuft and bremse_erlaubt then for x:=1 to bremse do windows.beep(0,0)
end;
Ich weiß nicht einmal, an welchen Befehlen es konkret liegt, haber aber genrell Canvas (mit seinen Methoden) im Verdacht. Ich kann auch insbesondere nicht irgendwelche Canvas-Befehle weglassen, ohne die Ausgabe bis zur Unkenntlichkeit zu verunstalten, was die Fehlersuche erschwert. Am anfänglichen application.processmessages und der ohnehin nur optionalen Bremsschleife zum Schluß liegt es jedenfalls nicht.

Ist dieses Verhalten für Canvas normal? Ist es irgendwie zu ändern? Oder hat Windows ab Vista einfach mehr Macht, in die Programmablaufgeschwindigkeit einzugreifen? Mir fällt auch oft ein verzögerter Start beim Sortieren auf, bevor das Sortieren so richtig Fahrt aufnimmt.

Was mich besonders irritiert, ist, daß es eben nur sporadisch ab Windows 7 (oder Vista?) auftrittt, aber in jedem Falle leider viel zu oft.

Vielen Dank im voraus und freundlicher Gruß

Delphi-Laie

Dalai 11. Nov 2015 21:37

AW: Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Wie sieht die Sache mit Classic Theme aus (nur bis Win7)? Dann wird die gesamte GUI durch die CPU gerendert und nicht mehr durch die Grafikkarte. Vielleicht macht das einen Unterschied.

Das Ändern irgendwelcher Prioritäten bringt übrigens nur dann etwas, wenn die CPU zu tun hat, mehr oder weniger voll ausgelastet ist.

MfG Dalai

Delphi-Laie 11. Nov 2015 21:45

AW: Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Zitat:

Zitat von Dalai (Beitrag 1321210)
Wie sieht die Sache mit Classic Theme aus (nur bis Win7)?

Das könnte schon ein, wenn nicht der Grund sein. Werde ich morgen ausprobieren - vielen Dank für Deinen Hinweis!

Luckie 11. Nov 2015 22:53

AW: Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Delphi-Quellcode:
SetPriorityClass(GetCurrentProcess,REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
Autsch. Man kann seinen Rechner natürlich auch mit Gewalt lahm legen.

Effektiver ist es erst auf ein Bitmap im Speicher zu zeichnen und dieses regelmäßig auf den Canvas zu kopieren.

Neutral General 12. Nov 2015 07:41

AW: Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Wie Luckie schon sagte, Die Prozess/Thread-Priorität so hochzuschrauben wird mehr Probleme machen als helfen.
Bist du sicher, dass du das Application.Processmessages in deinem linie_zeichnen brauchst? Wenn dann sollte es
reichen wenn du das einmal nach der Schleife aufrufst, wenn überhaupt!

Zum anderen solltest du zuerst auf ein Bitmap zeichnen und dieses Bitmap mit Canvas.Draw auf einen Schlag auf das Formular zeichenen.
Das wird die Performance stark verbessern denke ich.

Delphi-Laie 12. Nov 2015 08:32

AW: Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Dalai: Vielen Dank, der Grund für dieses Verhalten scheint schon gefunden zu sein, denn im Thema "Windows klassisch" verzögert sich die Zeilenausgabe nicht - ist zumindest bisher nicht passiert. Dein Spürsinn stimmte.

Luckie: Ja, das war mir fast klar, daß eine derart brachiale Methode bei den Profis nicht gut ankommt. Ich werde es auch wieder entfernen, zumal es nichts nützt. Es war ein Versuch, basierend auf den mir bis dato zur Verfügung stehenden Kenntnissen.

Neutral General: Ja, das application.processmessages benötige ich, damit ich die Algorithmen abbrechenbar halten kann (Tastendruck oder Mausklick auf das Formular, auf dem gezeichnet bzw. dargestellt wird).

Luckie und Neutral General: Danke für den Hinweis, ich werde mich jetzt mit TBitmap und dem Kopieren desselben auf das Canvas beschäftigen.

Nochmals besten Dank an Euch alle!

Memnarch 12. Nov 2015 11:13

AW: Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Seitdem Windows eine komplett DirectX/hardwarebeschleunigte Oberfläche hat (schätze das gilt ab WIndows 7 wegen Direct2D), zeichnen die GDI methoden nun halt nicht mehr direkt. Die genaue Pipeline hab ich aber nicht mehr im Kopf.
Versuch dich mal mit dem Direct2D canvas ab Windows 7 wens wirklich butterweich sein soll.

Ne bitmap dazwischen ist auch ne option, da BitBlt wiederum Hardwarebeschleunigt ist.

Delphi-Laie 12. Nov 2015 11:27

AW: Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Zitat:

Zitat von Memnarch (Beitrag 1321273)
Versuch dich mal mit dem Direct2D canvas ab Windows 7 wens wirklich butterweich sein soll.

Nun, das ist wahrscheinlich nicht mehr nötig, denn ich habe es mit Bitmap.Canvas hinbekommen. Das funktioniert zu meiner Zufriedenheit - zwar auch mit einer leicht wahrnehmbaren Verzögerung, aber dieser sporadische elend langsame Bildaufbau ist wohl nunmehr Geschichte.

Leute, Ihr seid großartig, besten Dank!!

Luckie 12. Nov 2015 12:00

AW: Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Ok. Es funktioniert. Dann können wir ja damit anfangen den Code zu verschönern:
Delphi-Quellcode:
procedure linie_zeichnen(x:word;darueber_loeschen:boolean);
begin
application.processmessages;
if ((Form1.ComboBox1.ItemIndex=4) or (Form1.ComboBox1.ItemIndex=20)) and not Form1.Visible
then Form2.Canvas.Pen.Color:=clblack
else Form2.Canvas.Pen.Color:=Menge[x].farbe;
Form2.Canvas.MoveTo(x,pred(Form1.SpinEdit3.Value));
Form2.Canvas.LineTo(x,Form1.SpinEdit3.Value-Menge[x].schluessel);
if darueber_loeschen then
  begin
  Form2.Canvas.Pen.Color:=clWhite;
  Form2.Canvas.LineTo(x,0)
  end;
if sortierung_laeuft and bremse_erlaubt then for x:=1 to bremse do windows.beep(0,0)
end;
Hier hast du mindestens zwei Abhängigkeiten von der Oberfläche drin und zu dem noch von zwei Formularen. Die Wiederverwendbarkeit geht da gegen null. Mach daraus eine Klasse, der du die nötigen Werte übergibst und sag der Funktion auf welchen Canvas sie zeichnen soll. Dann ist es egal, woher die benötigten Werte kommen und auf welchen Canvas das ganze gezeichnet wird.

Delphi-Laie 12. Nov 2015 12:50

AW: Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert
 
Ach Luckie, Du bist so gut zu mir und hast natürlich auch recht. Mein Code ist sicher kaum "semiprofessionell". Von Klassen habe ich aber nun überhaupt keine Ahnung, und wer sollte meinen Code wiederverwenden, wenn nicht mal ich ihn erneut an anderer Stelle gebrauchen könnte? Laß mal gut sein, herzlichen Dank! Meine neue Version ist soeben auch in diesem Forum veröffentlicht worden, und sie tut genau das, was sie soll - jetzt ohne diese Schwachstelle.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:26 Uhr.
Seite 1 von 2  1 2      

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