[krita] krita: Show current fps and whether the frames are dropped in the tooltip of the drop frames button

Dmitry Kazakov dimula73 at gmail.com
Fri Dec 18 17:38:02 UTC 2015


Git commit 39b50d9cba25902cc8d84e8a6789bc66f9fa74ff by Dmitry Kazakov.
Committed on 18/12/2015 at 17:37.
Pushed by dkazakov into branch 'master'.

Show current fps and whether the frames are dropped in the tooltip of the drop frames button

1) The buttons becomes red if the frames a dropped
2) The tool tip shows the following values:
    * Effective FPS --- the visible speed of the clip
    * Real FPS --- how many real frames per second is shown (always smaller)
    * Frames dropped --- percentage of the frames dropped

CC:kimageshop at kde.org

M  +39   -6    krita/plugins/extensions/dockers/animation/animation_docker.cpp
M  +37   -12   krita/ui/canvas/kis_animation_player.cpp
M  +6    -0    krita/ui/canvas/kis_animation_player.h

http://commits.kde.org/krita/39b50d9cba25902cc8d84e8a6789bc66f9fa74ff

diff --git a/krita/plugins/extensions/dockers/animation/animation_docker.cpp b/krita/plugins/extensions/dockers/animation/animation_docker.cpp
index 08a523a..698ab21 100644
--- a/krita/plugins/extensions/dockers/animation/animation_docker.cpp
+++ b/krita/plugins/extensions/dockers/animation/animation_docker.cpp
@@ -187,6 +187,7 @@ void AnimationDocker::setCanvas(KoCanvasBase * canvas)
         connect(m_canvas->animationPlayer(), SIGNAL(sigFrameChanged()), this, SLOT(slotGlobalTimeChanged()));
         connect(m_canvas->animationPlayer(), SIGNAL(sigPlaybackStopped()), this, SLOT(slotGlobalTimeChanged()));
         connect(m_canvas->animationPlayer(), SIGNAL(sigPlaybackStopped()), this, SLOT(updatePlayPauseIcon()));
+        connect(m_canvas->animationPlayer(), SIGNAL(sigPlaybackStatisticsUpdated()), this, SLOT(updateDropFramesIcon()));
         connect(m_animationWidget->doublePlaySpeed,
                 SIGNAL(valueChanged(double)),
                 m_canvas->animationPlayer(),
@@ -456,17 +457,49 @@ void AnimationDocker::updateLazyFrameIcon()
 
 void AnimationDocker::updateDropFramesIcon()
 {
-    KisConfig cfg;
+    qreal effectiveFps = 0.0;
+    qreal realFps = 0.0;
+    qreal framesDropped = 0.0;
+    bool isPlaying = false;
+
+    KisAnimationPlayer *player =
+        m_canvas && m_canvas->animationPlayer() ?
+        m_canvas->animationPlayer() : 0;
+
+    if (player) {
+        effectiveFps = player->effectiveFps();
+        realFps = player->realFps();
+        framesDropped = player->framesDroppedPortion();
+        isPlaying = player->isPlaying();
+    }
 
+    KisConfig cfg;
     const bool value = cfg.animationDropFrames();
 
     m_dropFramesAction->setIcon(value ?
-                               KisIconUtils::loadIcon("dropframe") :
-                               KisIconUtils::loadIcon("dropframe"));
+                                KisIconUtils::loadIcon(framesDropped > 0.05 ? "droppedframes" : "dropframe") :
+                                KisIconUtils::loadIcon("dropframe"));
 
-    m_dropFramesAction->setText(QString("%1 (%2)")
-                               .arg(KisAnimationUtils::dropFramesActionName)
-                               .arg(KritaUtils::toLocalizedOnOff(value)));
+
+    QString text;
+
+    if (!isPlaying) {
+        text = QString("%1 (%2)")
+            .arg(KisAnimationUtils::dropFramesActionName)
+            .arg(KritaUtils::toLocalizedOnOff(value));
+    } else {
+        text = QString("%1 (%2)\n"
+                       "%3\n"
+                       "%4\n"
+                       "%5")
+            .arg(KisAnimationUtils::dropFramesActionName)
+            .arg(KritaUtils::toLocalizedOnOff(value))
+            .arg(i18n("Effective FPS:\t%1", effectiveFps))
+            .arg(i18n("Real FPS:\t%1", realFps))
+            .arg(i18n("Frames dropped:\t%1\%", framesDropped * 100));
+    }
+
+    m_dropFramesAction->setText(text);
 }
 
 void AnimationDocker::slotUpdateIcons()
diff --git a/krita/ui/canvas/kis_animation_player.cpp b/krita/ui/canvas/kis_animation_player.cpp
index 6fd2601..6128f45 100644
--- a/krita/ui/canvas/kis_animation_player.cpp
+++ b/krita/ui/canvas/kis_animation_player.cpp
@@ -34,31 +34,31 @@
 #include "kis_signal_auto_connection.h"
 #include "kis_image_animation_interface.h"
 #include "kis_time_range.h"
+#include "kis_signal_compressor.h"
 
-#ifdef PLAYER_DEBUG_FRAMERATE
 #include <boost/accumulators/accumulators.hpp>
 #include <boost/accumulators/statistics/stats.hpp>
 #include <boost/accumulators/statistics/rolling_mean.hpp>
 
 using namespace boost::accumulators;
 typedef accumulator_set<qreal, stats<tag::rolling_mean> > FpsAccumulator;
-#endif /* PLAYER_DEBUG_FRAMERATE */
+
 
 struct KisAnimationPlayer::Private
 {
 public:
     Private(KisAnimationPlayer *_q)
         : q(_q),
-#ifdef PLAYER_DEBUG_FRAMERATE
-          realFpsAccumulator(tag::rolling_window::window_size = 12),
-          droppedFpsAccumulator(tag::rolling_window::window_size = 12),
-#endif /* PLAYER_DEBUG_FRAMERATE */
+          realFpsAccumulator(tag::rolling_window::window_size = 24),
+          droppedFpsAccumulator(tag::rolling_window::window_size = 24),
+          droppedFramesPortion(tag::rolling_window::window_size = 24),
           dropFramesMode(true),
           nextFrameExpectedTime(0),
           expectedInterval(0),
           expectedFrame(0),
           lastTimerInterval(0),
-          lastPaintedFrame(0)
+          lastPaintedFrame(0),
+          playbackStatisticsCompressor(1000, KisSignalCompressor::FIRST_INACTIVE)
           {}
 
     KisAnimationPlayer *q;
@@ -77,11 +77,11 @@ public:
 
     KisSignalAutoConnectionsStore cancelStrokeConnections;
 
-#ifdef PLAYER_DEBUG_FRAMERATE
     QElapsedTimer realFpsTimer;
     FpsAccumulator realFpsAccumulator;
     FpsAccumulator droppedFpsAccumulator;
-#endif /* PLAYER_DEBUG_FRAMERATE */
+    FpsAccumulator droppedFramesPortion;
+
 
     bool dropFramesMode;
 
@@ -92,6 +92,8 @@ public:
     int lastTimerInterval;
     int lastPaintedFrame;
 
+    KisSignalCompressor playbackStatisticsCompressor;
+
     void stopImpl(bool doUpdates);
 
     int incFrame(int frame, int inc) {
@@ -120,6 +122,9 @@ KisAnimationPlayer::KisAnimationPlayer(KisCanvas2 *canvas)
             SIGNAL(dropFramesModeChanged()),
             SLOT(slotUpdateDropFramesMode()));
     slotUpdateDropFramesMode();
+
+    connect(&m_d->playbackStatisticsCompressor, SIGNAL(timeout()),
+            this, SIGNAL(sigPlaybackStatisticsUpdated()));
 }
 
 KisAnimationPlayer::~KisAnimationPlayer()
@@ -257,7 +262,8 @@ void KisAnimationPlayer::uploadFrame(int frame)
         //          << ppVar(m_d->lastTimerInterval);
 
         if (m_d->dropFramesMode) {
-            frame = m_d->incFrame(m_d->expectedFrame, qMax(0, qRound(framesDiffNorm)));
+            const int numDroppedFrames = qMax(0, qRound(framesDiffNorm));
+            frame = m_d->incFrame(m_d->expectedFrame, numDroppedFrames);
         } else {
             frame = m_d->expectedFrame;
         }
@@ -268,6 +274,8 @@ void KisAnimationPlayer::uploadFrame(int frame)
         m_d->expectedFrame = m_d->incFrame(frame,  1);
 
         m_d->timer->start(m_d->lastTimerInterval);
+
+        m_d->playbackStatisticsCompressor.start();
     }
 
     if (m_d->canvas->frameCache()) {
@@ -285,7 +293,6 @@ void KisAnimationPlayer::uploadFrame(int frame)
         emit sigFrameChanged();
     }
 
-#ifdef PLAYER_DEBUG_FRAMERATE
     if (!m_d->realFpsTimer.isValid()) {
         m_d->realFpsTimer.start();
     } else {
@@ -297,19 +304,37 @@ void KisAnimationPlayer::uploadFrame(int frame)
             numFrames += m_d->lastFrame - m_d->firstFrame + 1;
         }
 
+        m_d->droppedFramesPortion(qreal(int(numFrames != 1)));
+
         if (numFrames > 0) {
             m_d->droppedFpsAccumulator(qreal(elapsed) / numFrames);
         }
 
+#ifdef PLAYER_DEBUG_FRAMERATE
         qDebug() << "    RFPS:" << 1000.0 / rolling_mean(m_d->realFpsAccumulator)
                  << "DFPS:" << 1000.0 / rolling_mean(m_d->droppedFpsAccumulator) << ppVar(numFrames);
-    }
 #endif /* PLAYER_DEBUG_FRAMERATE */
+    }
 
     m_d->lastPaintedFrame = frame;
 
 }
 
+qreal KisAnimationPlayer::effectiveFps() const
+{
+    return 1000.0 / rolling_mean(m_d->droppedFpsAccumulator);
+}
+
+qreal KisAnimationPlayer::realFps() const
+{
+    return 1000.0 / rolling_mean(m_d->realFpsAccumulator);
+}
+
+qreal KisAnimationPlayer::framesDroppedPortion() const
+{
+    return rolling_mean(m_d->droppedFramesPortion);
+}
+
 void KisAnimationPlayer::slotCancelPlayback()
 {
     stop();
diff --git a/krita/ui/canvas/kis_animation_player.h b/krita/ui/canvas/kis_animation_player.h
index b056cfd..06e1d35 100644
--- a/krita/ui/canvas/kis_animation_player.h
+++ b/krita/ui/canvas/kis_animation_player.h
@@ -46,6 +46,10 @@ public:
 
     void forcedStopOnExit();
 
+    qreal effectiveFps() const;
+    qreal realFps() const;
+    qreal framesDroppedPortion() const;
+
 public Q_SLOTS:
     void slotUpdate();
     void slotCancelPlayback();
@@ -53,9 +57,11 @@ public Q_SLOTS:
     void slotUpdatePlaybackSpeed(double value);
     void slotUpdatePlaybackTimer();
     void slotUpdateDropFramesMode();
+
 Q_SIGNALS:
     void sigFrameChanged();
     void sigPlaybackStopped();
+    void sigPlaybackStatisticsUpdated();
 
 private:
     void connectCancelSignals();


More information about the kimageshop mailing list