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 &region, 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"