Krita Source Code Documentation
Loading...
Searching...
No Matches
KisStrokeSpeedMonitor.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QGlobalStatic>
10#include <QMutex>
11#include <QMutexLocker>
12
14#include "kis_paintop_preset.h"
16
17#include "kis_config.h"
18#include "kis_config_notifier.h"
20
21
23
24
26{
27 static const int averageWindow = 10;
28
30 : avgCursorSpeed(averageWindow),
31 avgRenderingSpeed(averageWindow),
32 avgFps(averageWindow)
33 {
34 }
35
39
40 qreal cachedAvgCursorSpeed = 0;
41 qreal cachedAvgRenderingSpeed = 0;
42 qreal cachedAvgFps = 0;
43
44 qreal lastCursorSpeed = 0;
45 qreal lastRenderingSpeed = 0;
46 qreal lastFps = 0;
47 bool lastStrokeSaturated = false;
48
49 QByteArray lastPresetMd5;
51 qreal lastPresetSize = 0;
52
53 bool haveStrokeSpeedMeasurement = true;
54
55 QMutex mutex;
56};
57
59 : m_d(new Private())
60{
61 connect(KisImageConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(resetAccumulatedValues()));
62 connect(KisImageConfigNotifier::instance(), SIGNAL(configChanged()), SIGNAL(sigStatsUpdated()));
63 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged()));
64
66}
67
71
76
81
83{
84 m_d->haveStrokeSpeedMeasurement = value;
85}
86
88{
89 m_d->avgCursorSpeed.reset(m_d->averageWindow);
90 m_d->avgRenderingSpeed.reset(m_d->averageWindow);
91 m_d->avgFps.reset(m_d->averageWindow);
92}
93
95{
96 KisConfig cfg(true);
97 m_d->haveStrokeSpeedMeasurement = cfg.enableBrushSpeedLogging();
99 Q_EMIT sigStatsUpdated();
100}
101
102void KisStrokeSpeedMonitor::notifyStrokeFinished(qreal cursorSpeed, qreal renderingSpeed, qreal fps, KisPaintOpPresetSP preset)
103{
104 if (qFuzzyCompare(cursorSpeed, 0.0) || qFuzzyCompare(renderingSpeed, 0.0)) return;
105
106 QMutexLocker locker(&m_d->mutex);
107
108 const bool isSamePreset =
109 m_d->lastPresetName == preset->name() &&
110 qFuzzyCompare(m_d->lastPresetSize, preset->settings()->paintOpSize());
111
112 //ENTER_FUNCTION() << ppVar(isSamePreset);
113
114 if (!isSamePreset) {
116 m_d->lastPresetName = preset->name();
117 m_d->lastPresetSize = preset->settings()->paintOpSize();
118 }
119
120 m_d->lastCursorSpeed = cursorSpeed;
121 m_d->lastRenderingSpeed = renderingSpeed;
122 m_d->lastFps = fps;
123
124
125 static const qreal saturationSpeedThreshold = 0.30; // cursor speed should be at least 30% higher
126 m_d->lastStrokeSaturated = cursorSpeed / renderingSpeed > (1.0 + saturationSpeedThreshold);
127
128
129 if (m_d->lastStrokeSaturated) {
130 m_d->avgCursorSpeed(cursorSpeed);
131 m_d->avgRenderingSpeed(renderingSpeed);
132 m_d->avgFps(fps);
133
134 m_d->cachedAvgCursorSpeed = m_d->avgCursorSpeed.rollingMean();
135 m_d->cachedAvgRenderingSpeed = m_d->avgRenderingSpeed.rollingMean();
136 m_d->cachedAvgFps = m_d->avgFps.rollingMean();
137 }
138
139 Q_EMIT sigStatsUpdated();
140
141
142 ENTER_FUNCTION() <<
143 QString(" CS: %1 RS: %2 FPS: %3 %4")
144 .arg(m_d->lastCursorSpeed, 5)
145 .arg(m_d->lastRenderingSpeed, 5)
146 .arg(m_d->lastFps, 5)
147 .arg(m_d->lastStrokeSaturated ? "(saturated)" : "");
148 ENTER_FUNCTION() <<
149 QString("ACS: %1 ARS: %2 AFPS: %3")
150 .arg(m_d->cachedAvgCursorSpeed, 5)
151 .arg(m_d->cachedAvgRenderingSpeed, 5)
152 .arg(m_d->cachedAvgFps, 5);
153}
154
156{
157 return m_d->lastPresetName;
158}
159
161{
162 return m_d->lastPresetSize;
163}
164
166{
167 return m_d->lastCursorSpeed;
168}
169
171{
172 return m_d->lastRenderingSpeed;
173}
174
176{
177 return m_d->lastFps;
178}
179
181{
182 return m_d->lastStrokeSaturated;
183}
184
186{
187 return m_d->cachedAvgCursorSpeed;
188}
189
191{
192 return m_d->cachedAvgRenderingSpeed;
193}
194
196{
197 return m_d->cachedAvgFps;
198}
float value(const T *src, size_t ch)
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static KisConfigNotifier * instance()
bool enableBrushSpeedLogging(bool defaultValue=false) const
static KisImageConfigNotifier * instance()
A simple wrapper class that hides boost includes from QtCreator preventing it from crashing when one ...
const QScopedPointer< Private > m_d
static KisStrokeSpeedMonitor * instance()
void notifyStrokeFinished(qreal cursorSpeed, qreal renderingSpeed, qreal fps, KisPaintOpPresetSP preset)
void setHaveStrokeSpeedMeasurement(bool value)
static bool qFuzzyCompare(half p1, half p2)
#define ENTER_FUNCTION()
Definition kis_debug.h:178
KisRollingMeanAccumulatorWrapper avgFps
KisRollingMeanAccumulatorWrapper avgRenderingSpeed
KisRollingMeanAccumulatorWrapper avgCursorSpeed