AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Canvas-Methoden ab Windows 6.x / Vista oft sehr verzögert

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

Ein Thema von Delphi-Laie · begonnen am 11. Nov 2015 · letzter Beitrag vom 12. Nov 2015
Antwort Antwort
Seite 1 von 2  1 2   
Delphi-Laie

Registriert seit: 25. Nov 2005
1.412 Beiträge
 
Delphi 10.1 Berlin Starter
 
#1

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

  Alt 11. Nov 2015, 21:29
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

Geändert von Delphi-Laie (12. Nov 2015 um 08:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.200 Beiträge
 
Delphi 5 Professional
 
#2

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

  Alt 11. Nov 2015, 21:37
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

Geändert von Dalai (11. Nov 2015 um 21:39 Uhr)
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.412 Beiträge
 
Delphi 10.1 Berlin Starter
 
#3

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

  Alt 11. Nov 2015, 21:45
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!
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)
Online

Registriert seit: 29. Mai 2002
36.855 Beiträge
 
Delphi 2006 Professional
 
#4

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

  Alt 11. Nov 2015, 22:53
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.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General
Online

Registriert seit: 16. Jan 2004
Ort: Bendorf
4.807 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

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

  Alt 12. Nov 2015, 07:41
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.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.412 Beiträge
 
Delphi 10.1 Berlin Starter
 
#6

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

  Alt 12. Nov 2015, 08:32
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!
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
734 Beiträge
 
#7

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

  Alt 12. Nov 2015, 11:13
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.
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden

Geändert von Memnarch (12. Nov 2015 um 11:15 Uhr)
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.412 Beiträge
 
Delphi 10.1 Berlin Starter
 
#8

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

  Alt 12. Nov 2015, 11:27
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!!
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)
Online

Registriert seit: 29. Mai 2002
36.855 Beiträge
 
Delphi 2006 Professional
 
#9

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

  Alt 12. Nov 2015, 12:00
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.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.412 Beiträge
 
Delphi 10.1 Berlin Starter
 
#10

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

  Alt 12. Nov 2015, 12:50
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.

Geändert von Delphi-Laie (12. Nov 2015 um 19:48 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2018 by Daniel R. Wolf