File 0003-Remove-most-overhead-caused-by-the-freeze-detection-.patch of Package kwin5

From 14d993610e36418baa42436dc9606d9217cba590 Mon Sep 17 00:00:00 2001
From: Antonio Larrosa <larrosa@kde.org>
Date: Sun, 23 Oct 2016 12:19:38 +0200
Subject: [PATCH 3/4] Remove most overhead caused by the freeze-detection
 thread

I separated (Pre/Post)Init and (Pre/Post)Frame code in x11_platform
so now *Init "detects" crashes and *Frame detects freezes.

Also, now Pre/PostFrame can be called many times in a row since
PostFrame doesn't remove the thread but just deletes the timer
and PreFrame reuses the thread if it was already created.

I added OpenGLSafePoint::PostLastFrame which is called after the last
PostFrame safe point, and really removes the thread (also will delete
the timer if it wasn't deleted earlier)

Also, for freeze detection there's no need to write
OpenGLIsUnsafe=true in PreFrame and correct it in PostFrame since
kwin doesn't crash and I guess it's not nice to write twice to the
config file in every frame, even if it's just the first n frames and
the operating system will probably cache those writes. So I moved the
code to only set OpenGLIsUnsafe=true when a freeze is detected.
---
 composite.cpp                                     |  5 ++++
 platform.h                                        |  3 ++-
 plugins/platforms/x11/standalone/x11_platform.cpp | 30 +++++++++++++++++------
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/composite.cpp b/composite.cpp
index a425a5f..37cd54d 100644
--- a/composite.cpp
+++ b/composite.cpp
@@ -207,9 +207,11 @@ void Compositor::slotCompositingOptionsInitialized()
             qCWarning(KWIN_CORE) << "KWin has detected that your OpenGL library is unsafe to use";
         else {
             kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PreInit);
+            kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PreFrame);
 
             m_scene = SceneOpenGL::createScene(this);
 
+            kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PostLastFrame);
             kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PostInit);
 
             if (m_scene && !m_scene->initFailed()) {
@@ -745,6 +747,9 @@ void Compositor::performCompositing()
             kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PostFrame);
         }
         m_frameCount++;
+	if (m_frameCount >= m_maxFramesTestedForSafety) {
+            kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PostLastFrame);
+	 }
     }
     m_timeSinceStart += m_timeSinceLastVBlank;
 
diff --git a/platform.h b/platform.h
index 727ef70..83e41bb 100644
--- a/platform.h
+++ b/platform.h
@@ -144,7 +144,8 @@ public:
         PreInit,
         PostInit,
         PreFrame,
-        PostFrame
+        PostFrame,
+        PostLastFrame
     };
     /**
      * This method is invoked before and after creating the OpenGL rendering Scene.
diff --git a/plugins/platforms/x11/standalone/x11_platform.cpp b/plugins/platforms/x11/standalone/x11_platform.cpp
index 12c0395..39652c2 100644
--- a/plugins/platforms/x11/standalone/x11_platform.cpp
+++ b/plugins/platforms/x11/standalone/x11_platform.cpp
@@ -200,10 +200,18 @@ void X11StandalonePlatform::createOpenGLSafePoint(OpenGLSafePoint safePoint)
     auto group = KConfigGroup(kwinApp()->config(), "Compositing");
     switch (safePoint) {
     case OpenGLSafePoint::PreInit:
+        group.writeEntry(unsafeKey, true);
+        break;
+    case OpenGLSafePoint::PostInit:
+        group.writeEntry(unsafeKey, false);
+        break;
     case OpenGLSafePoint::PreFrame:
-        Q_ASSERT(m_openGLFreezeProtectionThread == nullptr);
-        m_openGLFreezeProtectionThread = new QThread(this);
-        m_openGLFreezeProtectionThread->start();
+        if (m_openGLFreezeProtectionThread == nullptr) {
+            m_openGLFreezeProtectionThread = new QThread(this);
+            m_openGLFreezeProtectionThread->setObjectName("FreezeDetector");
+            m_openGLFreezeProtectionThread->start();
+	}
+        Q_ASSERT(m_openGLFreezeProtection == nullptr);
         m_openGLFreezeProtection = new QTimer;
         m_openGLFreezeProtection->setInterval(15000);
         m_openGLFreezeProtection->setSingleShot(true);
@@ -211,20 +219,26 @@ void X11StandalonePlatform::createOpenGLSafePoint(OpenGLSafePoint safePoint)
         m_openGLFreezeProtection->moveToThread(m_openGLFreezeProtectionThread);
         connect(m_openGLFreezeProtection, &QTimer::timeout, m_openGLFreezeProtection,
             [] {
+                const QString unsafeKey(QLatin1String("OpenGLIsUnsafe") + (kwinApp()->isX11MultiHead() ? QString::number(kwinApp()->x11ScreenNumber()) : QString()));
+                auto group = KConfigGroup(kwinApp()->config(), "Compositing");
+                group.writeEntry(unsafeKey, true);
+                group.sync();
                 qFatal("Freeze in OpenGL initialization detected");
             }, Qt::DirectConnection);
-
-        group.writeEntry(unsafeKey, true);
         break;
-    case OpenGLSafePoint::PostInit:
     case OpenGLSafePoint::PostFrame:
         m_openGLFreezeProtection->deleteLater();
+        m_openGLFreezeProtection = nullptr;
+        break;
+    case OpenGLSafePoint::PostLastFrame:
+        if (m_openGLFreezeProtection) {
+            m_openGLFreezeProtection->deleteLater();
+            m_openGLFreezeProtection = nullptr;
+        };
         m_openGLFreezeProtectionThread->quit();
         m_openGLFreezeProtectionThread->wait();
         delete m_openGLFreezeProtectionThread;
         m_openGLFreezeProtectionThread = nullptr;
-        m_openGLFreezeProtection = nullptr;
-        group.writeEntry(unsafeKey, false);
         break;
     }
     group.sync();
-- 
2.10.1

openSUSE Build Service is sponsored by