diff --git a/src/core/renderjournal.cpp b/src/core/renderjournal.cpp index 492602e66f..756eafe8ac 100644 --- a/src/core/renderjournal.cpp +++ b/src/core/renderjournal.cpp @@ -15,36 +15,20 @@ RenderJournal::RenderJournal() void RenderJournal::add(std::chrono::nanoseconds renderTime) { - if (m_log.count() >= m_size) { - m_log.dequeue(); + if (renderTime > m_result || !m_lastAdd) { + m_result = renderTime; + } else { + static constexpr std::chrono::nanoseconds timeConstant = std::chrono::milliseconds(500); + const auto timeDifference = std::chrono::steady_clock::now() - *m_lastAdd; + const double ratio = std::min(0.1, double(timeDifference.count()) / double(timeConstant.count())); + m_result = std::chrono::nanoseconds(int64_t(renderTime.count() * ratio + m_result.count() * (1 - ratio))); } - m_log.enqueue(renderTime); + m_lastAdd = std::chrono::steady_clock::now(); } -std::chrono::nanoseconds RenderJournal::minimum() const +std::chrono::nanoseconds RenderJournal::result() const { - auto it = std::min_element(m_log.constBegin(), m_log.constEnd()); - return it != m_log.constEnd() ? (*it) : std::chrono::nanoseconds::zero(); -} - -std::chrono::nanoseconds RenderJournal::maximum() const -{ - auto it = std::max_element(m_log.constBegin(), m_log.constEnd()); - return it != m_log.constEnd() ? (*it) : std::chrono::nanoseconds::zero(); -} - -std::chrono::nanoseconds RenderJournal::average() const -{ - if (m_log.isEmpty()) { - return std::chrono::nanoseconds::zero(); - } - - std::chrono::nanoseconds result = std::chrono::nanoseconds::zero(); - for (const std::chrono::nanoseconds &entry : m_log) { - result += entry; - } - - return result / m_log.count(); + return m_result; } } // namespace KWin diff --git a/src/core/renderjournal.h b/src/core/renderjournal.h index dfbb059126..244cf7d5c2 100644 --- a/src/core/renderjournal.h +++ b/src/core/renderjournal.h @@ -25,24 +25,11 @@ public: void add(std::chrono::nanoseconds renderTime); - /** - * Returns the maximum estimated amount of time that it takes to render a single frame. - */ - std::chrono::nanoseconds maximum() const; - - /** - * Returns the minimum estimated amount of time that it takes to render a single frame. - */ - std::chrono::nanoseconds minimum() const; - - /** - * Returns the average estimated amount of time that it takes to render a single frame. - */ - std::chrono::nanoseconds average() const; + std::chrono::nanoseconds result() const; private: - QQueue m_log; - int m_size = 15; + std::chrono::nanoseconds m_result{0}; + std::optional m_lastAdd; }; } // namespace KWin diff --git a/src/core/renderloop.cpp b/src/core/renderloop.cpp index 77484f2946..90d50c77bc 100644 --- a/src/core/renderloop.cpp +++ b/src/core/renderloop.cpp @@ -56,40 +56,11 @@ void RenderLoopPrivate::scheduleRepaint() } // Estimate when it's a good time to perform the next compositing cycle. + // this safety margin is required for + // - the buffer readiness deadline in the drm backend, which is 1.8ms before vblank + // - scheduling and timer inaccuracies (estimated to be up to 1.2ms here) const std::chrono::nanoseconds safetyMargin = std::chrono::milliseconds(3); - - std::chrono::nanoseconds renderTime; - switch (q->latencyPolicy()) { - case KWin::RenderLoop::LatencyExtremelyLow: - renderTime = std::chrono::nanoseconds(long(vblankInterval.count() * 0.1)); - break; - case KWin::RenderLoop::LatencyLow: - renderTime = std::chrono::nanoseconds(long(vblankInterval.count() * 0.25)); - break; - case KWin::RenderLoop::LatencyMedium: - renderTime = std::chrono::nanoseconds(long(vblankInterval.count() * 0.5)); - break; - case KWin::RenderLoop::LatencyHigh: - renderTime = std::chrono::nanoseconds(long(vblankInterval.count() * 0.75)); - break; - case KWin::RenderLoop::LatencyExtremelyHigh: - renderTime = std::chrono::nanoseconds(long(vblankInterval.count() * 0.9)); - break; - } - - switch (options->renderTimeEstimator()) { - case RenderTimeEstimatorMinimum: - renderTime = std::max(renderTime, renderJournal.minimum()); - break; - case RenderTimeEstimatorMaximum: - renderTime = std::max(renderTime, renderJournal.maximum()); - break; - case RenderTimeEstimatorAverage: - renderTime = std::max(renderTime, renderJournal.average()); - break; - } - - std::chrono::nanoseconds nextRenderTimestamp = nextPresentationTimestamp - renderTime - safetyMargin; + std::chrono::nanoseconds nextRenderTimestamp = nextPresentationTimestamp - renderJournal.result() - safetyMargin; // If we can't render the frame before the deadline, start compositing immediately. if (nextRenderTimestamp < currentTime) { @@ -239,21 +210,6 @@ void RenderLoop::scheduleRepaint(Item *item) } } -KWin::RenderLoop::LatencyPolicy RenderLoop::latencyPolicy() const -{ - return d->latencyPolicy.value_or(options->latencyPolicy()); -} - -void RenderLoop::setLatencyPolicy(LatencyPolicy policy) -{ - d->latencyPolicy = policy; -} - -void RenderLoop::resetLatencyPolicy() -{ - d->latencyPolicy.reset(); -} - std::chrono::nanoseconds RenderLoop::lastPresentationTimestamp() const { return d->lastPresentationTimestamp; diff --git a/src/core/renderloop.h b/src/core/renderloop.h index 19fd02a908..4f726b6644 100644 --- a/src/core/renderloop.h +++ b/src/core/renderloop.h @@ -109,33 +109,6 @@ public: */ void setVrrPolicy(VrrPolicy vrrPolicy); - /** - * This enum type specifies the latency level configured by the user. - */ - enum LatencyPolicy { - LatencyExtremelyLow, - LatencyLow, - LatencyMedium, - LatencyHigh, - LatencyExtremelyHigh, - }; - Q_ENUM(LatencyPolicy) - /** - * Returns the latency policy for this render loop. - */ - LatencyPolicy latencyPolicy() const; - - /** - * Sets the latecy policy of this render loop to @a policy. By default, - * the latency policy of this render loop matches options->latencyPolicy(). - */ - void setLatencyPolicy(LatencyPolicy policy); - - /** - * Resets the latency policy to the default value. - */ - void resetLatencyPolicy(); - Q_SIGNALS: /** * This signal is emitted when the refresh rate of this RenderLoop has changed. diff --git a/src/core/renderloop_p.h b/src/core/renderloop_p.h index 763be9d289..ca1b3be979 100644 --- a/src/core/renderloop_p.h +++ b/src/core/renderloop_p.h @@ -44,7 +44,6 @@ public: bool pendingReschedule = false; bool pendingRepaint = false; RenderLoop::VrrPolicy vrrPolicy = RenderLoop::VrrPolicy::Never; - std::optional latencyPolicy; Item *fullscreenItem = nullptr; bool allowTearing = false; diff --git a/src/effects.cpp b/src/effects.cpp index 5189f83ea5..f6dbbcbb90 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -386,15 +386,6 @@ void EffectsHandlerImpl::setActiveFullScreenEffect(Effect *e) fullscreen_effect = e; Q_EMIT activeFullScreenEffectChanged(); if (activeChanged) { - const auto delegates = m_scene->delegates(); - for (SceneDelegate *delegate : delegates) { - RenderLoop *loop = delegate->layer()->loop(); - if (fullscreen_effect) { - loop->setLatencyPolicy(KWin::RenderLoop::LatencyPolicy::LatencyExtremelyHigh); - } else { - loop->resetLatencyPolicy(); - } - } Q_EMIT hasActiveFullScreenEffectChanged(); workspace()->screenEdges()->checkBlocking(); } diff --git a/src/kcms/compositing/compositing.ui b/src/kcms/compositing/compositing.ui index 2810f6676d..d8bf341f24 100644 --- a/src/kcms/compositing/compositing.ui +++ b/src/kcms/compositing/compositing.ui @@ -171,42 +171,6 @@ you can reset this protection but be aware that this might result in an immediat - - - - Latency: - - - - - - - - Force lowest latency (may cause dropped frames) - - - - - Prefer lower latency - - - - - Balance of latency and smoothness - - - - - Prefer smoother animations - - - - - Force smoothest animations - - - - diff --git a/src/kcms/compositing/kwincompositing.json b/src/kcms/compositing/kwincompositing.json index c18d552b55..4224d7c5f9 100644 --- a/src/kcms/compositing/kwincompositing.json +++ b/src/kcms/compositing/kwincompositing.json @@ -114,5 +114,8 @@ "X-KDE-Keywords[x-test]": "xxkwinxx,xxwindowxx,xxmanagerxx,xxcompositingxx,xxcompositorxx,xxeffectxx,xx3D effectsxx,xx2D effectsxx,xxOpenGLxx,xxXRenderxx,xxvideo settingsxx,xxgraphical effectsxx,xxdesktop effectsxx,xxgraphicsxx,xxlatencyxx,xxvsyncxx,xxtearingxx,xxwindow thumbnailsxx,xxscale methodxx,xxscaling methodxx,xxbackendxx", "X-KDE-Keywords[zh_CN]": "kwin,window,manager,compositing,compositor,effect,3D effects,2D effects,OpenGL,XRender,video settings,graphical effects,desktop effects,graphics,latency,vsync,tearing,window thumbnails,scale method,scaling method,backend,窗口,管理器,显示特效混合器,混合器,构图,混成,效果,特效,视效,动效,3D 特效,2D 特效,视频设置,图形效果,图形特效,图形延迟,延迟,垂直同步,撕裂,窗口缩略图,缩放方式,后端,后端程序", "X-KDE-System-Settings-Parent-Category": "display", - "X-KDE-Weight": 60 + "X-KDE-Weight": 60, + "X-KDE-OnlyShowOnQtPlatforms": [ + "xcb" + ] } diff --git a/src/kcms/compositing/kwincompositing_setting.kcfg b/src/kcms/compositing/kwincompositing_setting.kcfg index c8dac2af22..01ac32431a 100644 --- a/src/kcms/compositing/kwincompositing_setting.kcfg +++ b/src/kcms/compositing/kwincompositing_setting.kcfg @@ -33,16 +33,5 @@ true - - - - - - - - - - LatencyExtremelyHigh - diff --git a/src/kwin.kcfg b/src/kwin.kcfg index 9d1a782a6c..8ee4cf67f5 100644 --- a/src/kwin.kcfg +++ b/src/kwin.kcfg @@ -261,24 +261,6 @@ true - - - - - - - - - KWin::RenderLoop::LatencyExtremelyHigh - - - - - - - - RenderTimeEstimatorMaximum - true diff --git a/src/options.cpp b/src/options.cpp index 0589ac809c..0ba03ca9e3 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -55,8 +55,6 @@ Options::Options(QObject *parent) , m_xwaylandCrashPolicy(Options::defaultXwaylandCrashPolicy()) , m_xwaylandMaxCrashCount(Options::defaultXwaylandMaxCrashCount()) , m_xwaylandEavesdrops(Options::defaultXwaylandEavesdrops()) - , m_latencyPolicy(Options::defaultLatencyPolicy()) - , m_renderTimeEstimator(Options::defaultRenderTimeEstimator()) , m_compositingMode(Options::defaultCompositingMode()) , m_useCompositing(Options::defaultUseCompositing()) , m_hiddenPreviews(Options::defaultHiddenPreviews()) @@ -619,34 +617,6 @@ void Options::setGlPreferBufferSwap(char glPreferBufferSwap) Q_EMIT glPreferBufferSwapChanged(); } -KWin::RenderLoop::LatencyPolicy Options::latencyPolicy() const -{ - return m_latencyPolicy; -} - -void Options::setLatencyPolicy(KWin::RenderLoop::LatencyPolicy policy) -{ - if (m_latencyPolicy == policy) { - return; - } - m_latencyPolicy = policy; - Q_EMIT latencyPolicyChanged(); -} - -RenderTimeEstimator Options::renderTimeEstimator() const -{ - return m_renderTimeEstimator; -} - -void Options::setRenderTimeEstimator(RenderTimeEstimator estimator) -{ - if (m_renderTimeEstimator == estimator) { - return; - } - m_renderTimeEstimator = estimator; - Q_EMIT renderTimeEstimatorChanged(); -} - bool Options::allowTearing() const { return m_allowTearing; @@ -875,8 +845,6 @@ void Options::syncFromKcfgc() setElectricBorderTiling(m_settings->electricBorderTiling()); setElectricBorderCornerRatio(m_settings->electricBorderCornerRatio()); setWindowsBlockCompositing(m_settings->windowsBlockCompositing()); - setLatencyPolicy(m_settings->latencyPolicy()); - setRenderTimeEstimator(m_settings->renderTimeEstimator()); setAllowTearing(m_settings->allowTearing()); } diff --git a/src/options.h b/src/options.h index 9dfe1813a7..63e39b947d 100644 --- a/src/options.h +++ b/src/options.h @@ -48,15 +48,6 @@ enum XwaylandCrashPolicy { Restart, }; -/** - * This enum type specifies the method for estimating the expected render time. - */ -enum RenderTimeEstimator { - RenderTimeEstimatorMinimum, - RenderTimeEstimatorMaximum, - RenderTimeEstimatorAverage, -}; - /** * Placement policies. How workspace decides the way windows get positioned * on the screen. The better the policy, the heavier the resource use. @@ -82,7 +73,6 @@ class KWIN_EXPORT Options : public QObject { Q_OBJECT Q_ENUM(XwaylandCrashPolicy) - Q_ENUM(RenderTimeEstimator) Q_ENUM(PlacementPolicy) Q_PROPERTY(FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy NOTIFY focusPolicyChanged) Q_PROPERTY(XwaylandCrashPolicy xwaylandCrashPolicy READ xwaylandCrashPolicy WRITE setXwaylandCrashPolicy NOTIFY xwaylandCrashPolicyChanged) @@ -207,8 +197,6 @@ class KWIN_EXPORT Options : public QObject Q_PROPERTY(GlSwapStrategy glPreferBufferSwap READ glPreferBufferSwap WRITE setGlPreferBufferSwap NOTIFY glPreferBufferSwapChanged) Q_PROPERTY(KWin::OpenGLPlatformInterface glPlatformInterface READ glPlatformInterface WRITE setGlPlatformInterface NOTIFY glPlatformInterfaceChanged) Q_PROPERTY(bool windowsBlockCompositing READ windowsBlockCompositing WRITE setWindowsBlockCompositing NOTIFY windowsBlockCompositingChanged) - Q_PROPERTY(KWin::RenderLoop::LatencyPolicy latencyPolicy READ latencyPolicy WRITE setLatencyPolicy NOTIFY latencyPolicyChanged) - Q_PROPERTY(RenderTimeEstimator renderTimeEstimator READ renderTimeEstimator WRITE setRenderTimeEstimator NOTIFY renderTimeEstimatorChanged) Q_PROPERTY(bool allowTearing READ allowTearing WRITE setAllowTearing NOTIFY allowTearingChanged) public: explicit Options(QObject *parent = nullptr); @@ -697,8 +685,6 @@ public: } QStringList modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const; - KWin::RenderLoop::LatencyPolicy latencyPolicy() const; - RenderTimeEstimator renderTimeEstimator() const; bool allowTearing() const; // setters @@ -757,8 +743,6 @@ public: void setGlPreferBufferSwap(char glPreferBufferSwap); void setGlPlatformInterface(OpenGLPlatformInterface interface); void setWindowsBlockCompositing(bool set); - void setLatencyPolicy(KWin::RenderLoop::LatencyPolicy policy); - void setRenderTimeEstimator(RenderTimeEstimator estimator); void setAllowTearing(bool allow); // default values @@ -886,14 +870,6 @@ public: { return None; } - static KWin::RenderLoop::LatencyPolicy defaultLatencyPolicy() - { - return KWin::RenderLoop::LatencyExtremelyHigh; - } - static RenderTimeEstimator defaultRenderTimeEstimator() - { - return RenderTimeEstimatorMaximum; - } static ActivationDesktopPolicy defaultActivationDesktopPolicy() { return ActivationDesktopPolicy::SwitchToOtherDesktop; @@ -964,9 +940,7 @@ Q_SIGNALS: void glPlatformInterfaceChanged(); void windowsBlockCompositingChanged(); void animationSpeedChanged(); - void latencyPolicyChanged(); void configChanged(); - void renderTimeEstimatorChanged(); void allowTearingChanged(); private: @@ -998,8 +972,6 @@ private: XwaylandCrashPolicy m_xwaylandCrashPolicy; int m_xwaylandMaxCrashCount; XwaylandEavesdropsMode m_xwaylandEavesdrops; - KWin::RenderLoop::LatencyPolicy m_latencyPolicy; - RenderTimeEstimator m_renderTimeEstimator; CompositingType m_compositingMode; bool m_useCompositing;