Offscreen Bitmap wurde schon gesagt und ist deine Lösung. Bitmaps sind sehr wohl schneller zu zeichnen als direkt auf den Bildschirm.
Eine weitere Optimierung ist es ausgehend von dieser Offscreen Bitmap nur diejenigen rechteckigen Bereiche auf den Bildschirm zu kopieren die auch tatsächlich verändert wurden. Nehmen wir mal an das deine Meßpunkte grafisch örtlich in Gruppen auftreten, also ungleichmäßig auf dem Zeichenbereich verteilt sind. Dann ist es sinnvoll die Bitmap in NxM große Teilbereiche zu zerlegen und diese Teilbereich nach Veränderungen auf den Bildschirm zu kopieren. Diese Technik habe ich bei meinem Game Of Live Spiel so angewendet, weil auch dort ab einem bestimmten Spielfortschritt sich nur wenige Bildschirmbereiche tatsächlich verändern. Den Source solltest du hier in der
DP finden können. Man verhindert damit effektiv das man über das komplette Neuzeichnen der Bitmap tatsächlich zb. nur 10% wirkliche Veränderungen und 90% unveränderte Bereiche neu gezeichnet werden.
Ein weiterer Vorteil, wenn man das alles schon hat, ist es nun das diese Bereiche einzelnen Threads zugeordnet werden. Dh. mehrere Thread arbeiten parallel und sind immer für Teilbereiche der Grafik zuständig. Sie zeichnen ihre Änderungen in separate Bitmaps und der Mainthread baut aus diesen Einzelnbitmaps quasi das Bildschirm Bild auf.
Und noch eine Möglichkeit besteht darin das eigentliche Kopieren der Teilbereiche der Offscreen Bitmap asynchron zu deren Veränderungen zu machen. Dh. man verändert zb. die Teilbereiche der Bitmap ca. 1000 mal in der Sekunde, zeichnet diese veränderten Teilbereich aber nur alle 20 Milliesekunden tatsächlich neu auf den Bildschirm. Das geht weil bei 20ms Aktualisierung schluß ist für unsere Augen, wir können nicht schneller sehen als 50 Frames pro Sekunde. Normalerweise reichen aber auch 2-4 Aktualisierungen des Bildschirmes pro Sekunde aus. Du sparst damit also die Prozessorzeit für Funktionen wie Invalidate und alles was normalerweise eben 1000 mal pro Sekunde nötigt wäre aber eigentlich sinnlos ist.
Man optimiert quasi Stück für Stück sein Program und der konzeptionelle Ansatz den du wählst entscheidet ob obige Optimierungen später möglich/einbaubar sind.
Eine weitere Möglichkeit ist es ein TPanel (Windowshandle erforderlich) hinter die TPainBox zu legen (TPaintBox ist alClient im TPanel). Nun fängt man die Windowsbotschaft wm_EraseBkGnd vom TPanel ab und tut darin einfach nichts
wm_EraseBkGnd löscht den Bildschirmbereich dieses TPanels -> ergo TPainBox, jedesmal wenn man Invalidate aufgerufen hat. Das führt dann zum besagten Flackern. Im OnPaint() muß man bei jedem auftreffenden wm_EraseBkGnd dann ntürlich die Offscreen Bitmap komplett neu zeichnen oder zumindestens in den Bereichen die mit GetClipRgn(Canvas.Handle) als neu zu zeichnen enthalten sind. Das kannst du mit IsRectVisible(Canvas.Handle, TRect) überprüfen wenn du mit der Teilbereichs-Logik arbeiten möchtest.
Über wm_EraseBkGnd kannst du also schonmal aktiv das Flackern beseitigen, vorrausgesetzt du rufst im OnPaint() der TPainbox nicht als erstes FillRect(ClientRect) oder sowas auf.
Gruß Hagen