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