Warum ist die Frame-Rate in WPF Unregelmäßig und Nicht Beschränkt Auf Monitor Refresh?

Ich bin das Messen der Zeit zwischen frames in einer einfachen WPF-animation. Perforator, sagt die app führt bei ~60fps, so erwartete ich die Zeit zwischen den frames auf ~16,6 ms mit wenig Abweichung.

    public MainWindow()
    {
    ...
        CompositionTarget.Rendering += Rendering;
    }

    List<long> FrameDurations = new List<long>();
    private long PreviousFrameTime = 0;
    private void Rendering(object o, EventArgs args)
    {
        FrameDurations.Add(DateTime.Now.Ticks - PreviousFrameTime);
        PreviousFrameTime = DateTime.Now.Ticks;
    }

Zwei Dinge haben mich überrascht:

  • Zeit zwischen den frames ist ziemlich unregelmäßig
  • Zeit zwischen frames von ~8ms. Ich hatte erwartet, dass die Bildwiederholrate des Monitors würde eine untere Schranke für die Zeit zwischen frames (ie. 60 Hz = 16,6 ms zwischen jedem frame, und alles, was schneller ist sinnlos).

Warum ist die Frame-Rate in WPF Unregelmäßig und Nicht Beschränkt Auf Monitor Refresh?

Y - Zeit zwischen frames in Zecken (in 10.000 ticks = 1ms)

X - Frame-count -

Mögliche Störfaktoren

  • Timer-Ungenauigkeit
  • Wenn CompositionTarget.Rendering nicht wirklich korrelieren die Zeichnung der single-frame

Das Projekt, das ich verwende: SimpleWindow.zip

===Edit

Markus darauf hingewiesen, ich könnte mit RenderingEventArgs.RenderingTime.Zecken anstelle von DateTime.Nun.Zecken. Ich wiederholte den Lauf und bekam sehr unterschiedliche Ergebnisse. Der einzige Unterschied ist das timing-Methode:

DateTime.Nun.Zecken

Warum ist die Frame-Rate in WPF Unregelmäßig und Nicht Beschränkt Auf Monitor Refresh?

RenderingEventArgs.RenderingTime.Zecken

Warum ist die Frame-Rate in WPF Unregelmäßig und Nicht Beschränkt Auf Monitor Refresh?

Daten aus RenderingEventArgs produziert Daten, die viel näher der erwartete 16,6 ms/frame, und es ist konsistent.

  • Ich bin mir nicht sicher, warum DateTime.Jetzt und RenderingEventArgs würde produzieren, die sehr unterschiedliche Daten.
  • Vorausgesetzt RenderingEventArgs ist die Herstellung von korrekten Zeiten, es ist noch ein wenig befremdlich ist, dass diese Zeiten nicht den erwarteten 16,6 ms.

Wenn die Anzeige aktualisieren alle 16,6 ms und WPF aktualisiert wird jeden mit 14,9 ms, können wir erwarten, dass eine race-condition führen würde reißen. Das heißt, etwa jeden 10ten frame WPF wird versucht, zu schreiben sein Bild während der Anzeige zu Lesen versucht, das Bild.

  • Die Stopwatch-Klasse ist der Weg zu gehen, um zu vermeiden, timer-Ungenauigkeit
  • diese "könnten" nützlich sein: rhnatiuk.wordpress.com/2008/12/21/wpf-video-playback-problems - ich bin nicht sicher, wie relevant dieses Problem ist, aber ich denke, es existiert noch heute.
  • Zeit der Messung gar nicht gebraucht! Sie können cast EventArgs zu RenderingEventArgs, um die RenderTime
  • Ich vermute Roman ist auf etwas. Ich möchte seinen Artikel enthalten Daten. Ohne Daten, seine Artikel liest sich wie eine Meinung (Urteil, aber noch nicht 'Tat').
  • Natürlich! Ich fühle mich dumm. Danke 🙂
  • Generiert man ein video frame in WPF und die Anzeige-Ausgabe-Gerät ist in der Mitte des Rahmens, wird WPF Verzögerung der Anwendung code bis zum start des nächsten Rahmens und dann die Daten anzeigen, oder wird WPF sofort einen snapshot der Anzeige von Daten und zur Rückkehr, so dass eine Treiber-task zum kopieren der Daten in den display-Puffer auf die entsprechende Zeit? Meine Vermutung wäre, dass es tut letzteres, was bedeuten würde, dass die Zeiten, in denen die macht ergänzen wäre random, auch wenn Sie angezeigt wird, synchronisiert mit der physischen Ausgabe.
  • irgendeine Idee, wie ich testen kann Theorie?
  • Überprüfen Sie die Ergebnisse mit einer Stoppuhr-Objekt. Die Zeit zurückgegeben, die von DateTime.Nun kann man nicht mehr genau; ein Stoppuhr-Objekt, auf einem einzelnen CPU-Kern soll vieles besser werden. Beachten Sie, dass auf einigen multi-core-Maschinen, ein Stoppuhr-Objekt erstellt auf einem Kern und Lesen auf einem anderen kann ausgeschaltet werden durch einen bestimmten Betrag die in der Regel konstant für ein gegebenes paar von Kernen, es sei denn, die Maschine neu gestartet wird.

InformationsquelleAutor Tristan | 2011-04-28
Schreibe einen Kommentar