Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_fps_decoration.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QApplication>
10#include <QPainter>
11#include "kis_canvas2.h"
15#include <QGraphicsScene>
16#include <QGraphicsPixmapItem>
17#include <QGraphicsDropShadowEffect>
18
19const QString KisFpsDecoration::idTag = "fps_decoration";
20
22 : KisCanvasDecoration(idTag, view)
23 , m_font(QApplication::font())
24 , m_pixmap(1, 1) // need non-zero pixmap for initial setup
25{
26 setVisible(true);
27
28 m_shadow = new QGraphicsDropShadowEffect(this);
29 m_shadow->setBlurRadius(0.5);
30 m_shadow->setOffset(0);
31 m_shadow->setColor(QColor(0x30, 0x30, 0x30));
32
33 m_scene = new QGraphicsScene(this);
34 m_pixmapItem = m_scene->addPixmap(m_pixmap);
35 m_pixmapItem->setGraphicsEffect(m_shadow);
36}
37
41
42void KisFpsDecoration::drawDecoration(QPainter& gc, const QRectF& /*updateRect*/, const KisCoordinatesConverter */*converter*/, KisCanvas2* /*canvas*/)
43{
44 // we always paint into a pixmap instead of directly into gc, as the latter
45 // approach is known to cause garbled graphics on macOS, Windows, and even
46 // sometimes Linux.
47
48 const QString text = getText();
49
50 // note that USUALLY the pixmap will have the right size. in very rare cases
51 // (e.g. on the very first call) the computed bounding rect will not be right
52 // and the pixmap will need a resize. it is faster to NOT usually calculate
53 // the necessary bounds with an extra call like QFontMetrics::boundingRect()
54 // here, as USUALLY the pixmap will be right and thus an extra call would be
55 // unnecessary overhead.
56
57 QSize size;
58
59 if (!draw(text, size)) {
60 // the pixmap is too small, we need to make it larger. make it 10% wider
61 // than the measured width to avoid resizing again as soon as the text
62 // gets a bit wider due to different content.
63
64 m_pixmap = QPixmap(size.width() * 1.1f, size.height());
65
66 KIS_ASSERT(draw(text, size));
67 }
68
69 QRectF r = m_pixmap.rect();
70 r |= m_shadow->boundingRectFor(r);
71
72 m_pixmapItem->setPixmap(m_pixmap);
73 m_scene->render(&gc, r.translated(20, 20), r);
74}
75
76bool KisFpsDecoration::draw(const QString &text, QSize &outSize)
77{
78 m_pixmap.fill(Qt::transparent);
79
80 const int flags = Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip;
81 QRect bounds;
82
83 QPainter painter(&m_pixmap);
84 painter.setFont(m_font);
85
86 painter.setPen(QPen(QColor(0xF0, 0xF0, 0xF0)));
87 painter.drawText(m_pixmap.rect().translated(1, 1), flags, text, &bounds);
88
89 outSize = bounds.size() + QSize(1, 1);
90
91 if (m_pixmap.width() < outSize.width() || m_pixmap.height() != outSize.height()) {
92 return false; // pixmap is too small and needs a resize. rarely happens.
93 }
94
95 return true;
96}
97
99{
100 QStringList lines;
101
102 if (KisOpenglCanvasDebugger::instance()->showFpsOnCanvas()) {
104 lines << QString("Canvas FPS: %1").arg(QString::number(value, 'f', 1));
105 }
106
108
109 if (monitor->haveStrokeSpeedMeasurement()) {
110 lines << QString("Last cursor/brush speed (px/ms): %1/%2%3")
111 .arg(monitor->lastCursorSpeed(), 0, 'f', 1)
112 .arg(monitor->lastRenderingSpeed(), 0, 'f', 1)
113 .arg(monitor->lastStrokeSaturated() ? " (!)" : "");
114 lines << QString("Last brush framerate: %1 fps")
115 .arg(monitor->lastFps(), 0, 'f', 1);
116
117 lines << QString("Average cursor/brush speed (px/ms): %1/%2")
118 .arg(monitor->avgCursorSpeed(), 0, 'f', 1)
119 .arg(monitor->avgRenderingSpeed(), 0, 'f', 1);
120 lines << QString("Average brush framerate: %1 fps")
121 .arg(monitor->avgFps(), 0, 'f', 1);
122 }
123
124 return lines.join('\n');
125}
float value(const T *src, size_t ch)
virtual void setVisible(bool v)
bool draw(const QString &text, QSize &outSize)
QString getText() const
QGraphicsDropShadowEffect * m_shadow
static const QString idTag
QGraphicsScene * m_scene
KisFpsDecoration(QPointer< KisView > view)
void drawDecoration(QPainter &gc, const QRectF &updateRect, const KisCoordinatesConverter *converter, KisCanvas2 *canvas) override
QGraphicsPixmapItem * m_pixmapItem
static KisOpenglCanvasDebugger * instance()
static KisStrokeSpeedMonitor * instance()
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
#define bounds(x, a, b)