From c3221c5b5f5fef9451cf3107c6e565966d4a3103aa8fae82727beaadcd38206e Mon Sep 17 00:00:00 2001 From: Fabian Vogt Date: Tue, 5 Mar 2024 12:44:06 +0000 Subject: [PATCH] Accepting request 1153973 from home:dziobian - Add backported intel-compositor-freeze.patch * fixes kde#481721 OBS-URL: https://build.opensuse.org/request/show/1153973 OBS-URL: https://build.opensuse.org/package/show/KDE:Frameworks/kwin6?expand=0&rev=5 --- intel-compositor-freeze.patch | 133 ++++++++++++++++++++++++++++++++++ kwin6.changes | 6 ++ kwin6.spec | 1 + 3 files changed, 140 insertions(+) create mode 100644 intel-compositor-freeze.patch diff --git a/intel-compositor-freeze.patch b/intel-compositor-freeze.patch new file mode 100644 index 0000000..3a2a327 --- /dev/null +++ b/intel-compositor-freeze.patch @@ -0,0 +1,133 @@ +From 0dc3f4906fd7cdaaeb740b2b29213acd5d2989fa Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii +Date: Thu, 29 Feb 2024 19:17:55 +0200 +Subject: [PATCH] opengl: Harden GLRenderTimeQuery against opengl providing bad + timestamps + +The end render timestamp can be slightly in the past before the start +render timestamp. This results in negative render times, which can make +kwin wait way more than just one vblank interval before starting the +next frame. + +It appears that there is no way to detect if the gpu has performed a +disjoint operation in OpenGL. It's available only in GLES. As a way +around, this change makes the GLRenderTimeQuery insert two probes: one +queries gl timestamps when starting rendering and ending rendering; +another one just queries std::steady_clock before and after painting. +This hardens the GLRenderTimeQuery against OpenGL providing nonsensical +results sometimes. + +BUG: 481721 +--- + src/opengl/glrendertimequery.cpp | 42 +++++++++++++++----------------- + src/opengl/glrendertimequery.h | 16 +++++++++--- + 2 files changed, 32 insertions(+), 26 deletions(-) + +diff --git a/src/opengl/glrendertimequery.cpp b/src/opengl/glrendertimequery.cpp +index e299c358e14..cf6fbb49a72 100644 +--- a/src/opengl/glrendertimequery.cpp ++++ b/src/opengl/glrendertimequery.cpp +@@ -15,36 +15,33 @@ namespace KWin + GLRenderTimeQuery::GLRenderTimeQuery() + { + if (GLPlatform::instance()->supports(GLFeature::TimerQuery)) { +- glGenQueries(1, &m_query); ++ glGenQueries(1, &m_gpuProbe.query); + } + } + + GLRenderTimeQuery::~GLRenderTimeQuery() + { +- if (m_query) { +- glDeleteQueries(1, &m_query); ++ if (m_gpuProbe.query) { ++ glDeleteQueries(1, &m_gpuProbe.query); + } + } + + void GLRenderTimeQuery::begin() + { +- if (m_query) { +- GLint64 nanos = 0; +- glGetInteger64v(GL_TIMESTAMP, &nanos); +- m_cpuStart = std::chrono::nanoseconds(nanos); +- } else { +- m_cpuStart = std::chrono::steady_clock::now().time_since_epoch(); ++ if (m_gpuProbe.query) { ++ glGetInteger64v(GL_TIMESTAMP, &m_gpuProbe.start); + } ++ m_cpuProbe.start = std::chrono::steady_clock::now().time_since_epoch(); + } + + void GLRenderTimeQuery::end() + { +- if (m_query) { +- glQueryCounter(m_query, GL_TIMESTAMP); +- } else { +- m_cpuEnd = std::chrono::steady_clock::now().time_since_epoch(); +- } + m_hasResult = true; ++ ++ if (m_gpuProbe.query) { ++ glQueryCounter(m_gpuProbe.query, GL_TIMESTAMP); ++ } ++ m_cpuProbe.end = std::chrono::steady_clock::now().time_since_epoch(); + } + + std::chrono::nanoseconds GLRenderTimeQuery::result() +@@ -53,16 +50,15 @@ std::chrono::nanoseconds GLRenderTimeQuery::result() + return std::chrono::nanoseconds::zero(); + } + m_hasResult = false; +- if (m_query) { +- uint64_t nanos = 0; +- glGetQueryObjectui64v(m_query, GL_QUERY_RESULT, &nanos); +- if (nanos == 0) { +- return std::chrono::nanoseconds::zero(); +- } +- return std::chrono::nanoseconds(nanos) - m_cpuStart; +- } else { +- return m_cpuEnd - m_cpuStart; ++ ++ if (m_gpuProbe.query) { ++ glGetQueryObjecti64v(m_gpuProbe.query, GL_QUERY_RESULT, &m_gpuProbe.end); + } ++ ++ const std::chrono::nanoseconds gpuTime(m_gpuProbe.end - m_gpuProbe.start); ++ const std::chrono::nanoseconds cpuTime = m_cpuProbe.end - m_cpuProbe.start; ++ ++ return std::max(gpuTime, cpuTime); + } + + } +diff --git a/src/opengl/glrendertimequery.h b/src/opengl/glrendertimequery.h +index 7850985d603..0778fd5c7bd 100644 +--- a/src/opengl/glrendertimequery.h ++++ b/src/opengl/glrendertimequery.h +@@ -31,10 +31,20 @@ public: + std::chrono::nanoseconds result(); + + private: +- GLuint m_query = 0; + bool m_hasResult = false; +- std::chrono::nanoseconds m_cpuStart = std::chrono::nanoseconds::zero(); +- std::chrono::nanoseconds m_cpuEnd = std::chrono::nanoseconds::zero(); ++ ++ struct ++ { ++ std::chrono::nanoseconds start = std::chrono::nanoseconds::zero(); ++ std::chrono::nanoseconds end = std::chrono::nanoseconds::zero(); ++ } m_cpuProbe; ++ ++ struct ++ { ++ GLuint query = 0; ++ GLint64 start = 0; ++ GLint64 end = 0; ++ } m_gpuProbe; + }; + + } +-- +GitLab + diff --git a/kwin6.changes b/kwin6.changes index f363aee..4e4dcc0 100644 --- a/kwin6.changes +++ b/kwin6.changes @@ -3,6 +3,12 @@ Mon Mar 4 20:05:29 UTC 2024 - Christophe Marin - Add Provides/Obsoletes to replace Plasma 5 +------------------------------------------------------------------- +Thu Feb 29 18:26:03 UTC 2024 - Bruno Pitrus + +- Add backported intel-compositor-freeze.patch + * fixes kde#481721 + ------------------------------------------------------------------- Wed Feb 21 18:36:15 UTC 2024 - Fabian Vogt diff --git a/kwin6.spec b/kwin6.spec index 8f359f2..e4219f0 100644 --- a/kwin6.spec +++ b/kwin6.spec @@ -39,6 +39,7 @@ Source: %{rname}-%{version}.tar.xz Source1: %{rname}-%{version}.tar.xz.sig Source2: plasma.keyring %endif +Patch0: intel-compositor-freeze.patch BuildRequires: fdupes BuildRequires: kf6-extra-cmake-modules >= %{kf6_version} BuildRequires: libcap-progs