File indexing completed on 2024-11-10 04:57:08
0001 /* 0002 SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org> 0003 SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0004 SPDX-FileCopyrightText: 2022 Arjen Hiemstra <ahiemstra@heimr.nl> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "showfpseffect.h" 0010 #include "core/output.h" 0011 #include "core/renderviewport.h" 0012 #include "effect/effecthandler.h" 0013 0014 #include <QQmlContext> 0015 0016 namespace KWin 0017 { 0018 0019 ShowFpsEffect::ShowFpsEffect() 0020 { 0021 } 0022 0023 ShowFpsEffect::~ShowFpsEffect() = default; 0024 0025 int ShowFpsEffect::fps() const 0026 { 0027 return m_fps; 0028 } 0029 0030 int ShowFpsEffect::maximumFps() const 0031 { 0032 return m_maximumFps; 0033 } 0034 0035 int ShowFpsEffect::paintDuration() const 0036 { 0037 return m_paintDuration; 0038 } 0039 0040 int ShowFpsEffect::paintAmount() const 0041 { 0042 return m_paintAmount; 0043 } 0044 0045 QColor ShowFpsEffect::paintColor() const 0046 { 0047 auto normalizedDuration = std::min(1.0, m_paintDuration / 100.0); 0048 return QColor::fromHsvF(0.3 - (0.3 * normalizedDuration), 1.0, 1.0); 0049 } 0050 0051 void ShowFpsEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) 0052 { 0053 effects->prePaintScreen(data, presentTime); 0054 0055 m_newFps += 1; 0056 0057 m_paintDurationTimer.restart(); 0058 m_paintAmount = 0; 0059 0060 // detect highest monitor refresh rate 0061 uint32_t maximumFps = 0; 0062 const auto screens = effects->screens(); 0063 for (auto screen : screens) { 0064 maximumFps = std::max(screen->refreshRate(), maximumFps); 0065 } 0066 maximumFps /= 1000; // Convert from mHz to Hz. 0067 0068 if (maximumFps != m_maximumFps) { 0069 m_maximumFps = maximumFps; 0070 Q_EMIT maximumFpsChanged(); 0071 } 0072 0073 if (!m_scene) { 0074 m_scene = std::make_unique<OffscreenQuickScene>(); 0075 const auto url = QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/showfps/qml/main.qml"))); 0076 m_scene->setSource(url, {{QStringLiteral("effect"), QVariant::fromValue(this)}}); 0077 } 0078 } 0079 0080 void ShowFpsEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion, Output *screen) 0081 { 0082 effects->paintScreen(renderTarget, viewport, mask, region, screen); 0083 0084 auto now = std::chrono::steady_clock::now(); 0085 if ((now - m_lastFpsTime) >= std::chrono::milliseconds(1000)) { 0086 m_fps = m_newFps; 0087 m_newFps = 0; 0088 m_lastFpsTime = now; 0089 Q_EMIT fpsChanged(); 0090 } 0091 0092 const auto rect = viewport.renderRect(); 0093 m_scene->setGeometry(QRect(rect.x() + rect.width() - 300, 0, 300, 150)); 0094 effects->renderOffscreenQuickView(renderTarget, viewport, m_scene.get()); 0095 } 0096 0097 void ShowFpsEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data) 0098 { 0099 effects->paintWindow(renderTarget, viewport, w, mask, region, data); 0100 0101 // Take intersection of region and actual window's rect, minus the fps area 0102 // (since we keep repainting it) and count the pixels. 0103 QRegion repaintRegion = region & w->frameGeometry().toRect(); 0104 repaintRegion -= m_scene->geometry(); 0105 for (const QRect &rect : repaintRegion) { 0106 m_paintAmount += rect.width() * rect.height(); 0107 } 0108 } 0109 0110 void ShowFpsEffect::postPaintScreen() 0111 { 0112 effects->postPaintScreen(); 0113 0114 m_paintDuration = m_paintDurationTimer.elapsed(); 0115 Q_EMIT paintChanged(); 0116 0117 effects->addRepaint(m_scene->geometry()); 0118 } 0119 0120 bool ShowFpsEffect::supported() 0121 { 0122 return effects->isOpenGLCompositing(); 0123 } 0124 0125 } // namespace KWin 0126 0127 #include "moc_showfpseffect.cpp"