[calligra/krita-animation-pentikainen] 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 Jan 1 20:19:41 UTC 2016
Git commit c86dd0ba98797188f2742d6bd7335d2dd63e5932 by Dmitry Kazakov.
Committed on 01/01/2016 at 17:54.
Pushed by dkazakov into branch 'krita-animation-pentikainen'.
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/calligra/c86dd0ba98797188f2742d6bd7335d2dd63e5932
diff --git a/krita/plugins/extensions/dockers/animation/animation_docker.cpp b/krita/plugins/extensions/dockers/animation/animation_docker.cpp
index f825c2a..72d4592 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(),
@@ -454,17 +455,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("lazyframeOn") :
- KisIconUtils::loadIcon("lazyframeOff"));
+ 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 ffc9c25..92d70d1 100644
--- a/krita/ui/canvas/kis_animation_player.cpp
+++ b/krita/ui/canvas/kis_animation_player.cpp
@@ -33,31 +33,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;
@@ -76,11 +76,11 @@ public:
KisSignalAutoConnectionsStore cancelStrokeConnections;
-#ifdef PLAYER_DEBUG_FRAMERATE
QElapsedTimer realFpsTimer;
FpsAccumulator realFpsAccumulator;
FpsAccumulator droppedFpsAccumulator;
-#endif /* PLAYER_DEBUG_FRAMERATE */
+ FpsAccumulator droppedFramesPortion;
+
bool dropFramesMode;
@@ -91,6 +91,8 @@ public:
int lastTimerInterval;
int lastPaintedFrame;
+ KisSignalCompressor playbackStatisticsCompressor;
+
void stopImpl(bool doUpdates);
int incFrame(int frame, int inc) {
@@ -119,6 +121,9 @@ KisAnimationPlayer::KisAnimationPlayer(KisCanvas2 *canvas)
SIGNAL(dropFramesModeChanged()),
SLOT(slotUpdateDropFramesMode()));
slotUpdateDropFramesMode();
+
+ connect(&m_d->playbackStatisticsCompressor, SIGNAL(timeout()),
+ this, SIGNAL(sigPlaybackStatisticsUpdated()));
}
KisAnimationPlayer::~KisAnimationPlayer()
@@ -256,7 +261,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;
}
@@ -267,6 +273,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()) {
@@ -284,7 +292,6 @@ void KisAnimationPlayer::uploadFrame(int frame)
emit sigFrameChanged();
}
-#ifdef PLAYER_DEBUG_FRAMERATE
if (!m_d->realFpsTimer.isValid()) {
m_d->realFpsTimer.start();
} else {
@@ -296,19 +303,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 ef166ce..0040a20 100644
--- a/krita/ui/canvas/kis_animation_player.h
+++ b/krita/ui/canvas/kis_animation_player.h
@@ -46,7 +46,12 @@ public:
void forcedStopOnExit();
+ qreal effectiveFps() const;
+ qreal realFps() const;
+ qreal framesDroppedPortion() const;
+
public slots:
+
void slotUpdate();
void slotCancelPlayback();
void slotCancelPlaybackSafe();
@@ -56,6 +61,7 @@ public slots:
signals:
void sigFrameChanged();
void sigPlaybackStopped();
+ void sigPlaybackStatisticsUpdated();
private:
void connectCancelSignals();
More information about the kimageshop
mailing list