From f82fffdd716a9d4df12ea317f70ce1b3d3ec36ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Thu, 23 Aug 2012 16:51:40 +0200 Subject: [PATCH] fix flicker with fullscreen effects BUG: 304375 FIXED-IN: 4.9.1 REVIEW: 106142 --- composite.cpp | 15 ++++++++++++--- scene.h | 3 +++ scene_opengl.h | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/composite.cpp b/composite.cpp index ddca3d339f..6ed8289bd8 100644 --- a/composite.cpp +++ b/composite.cpp @@ -393,14 +393,22 @@ void Workspace::timerEvent(QTimerEvent *te) QObject::timerEvent(te); } -static bool s_pending = false; +static int s_pendingFlushes = 0; + void Workspace::performCompositing() { if (!scene->overlayWindow()->isVisible()) return; // nothing is visible anyway bool pending = !repaints_region.isEmpty() || windowRepaintsPending(); - if (!(pending || s_pending)) { + if (pending) + s_pendingFlushes = 3; + else if (scene->hasPendingFlush()) + --s_pendingFlushes; + else + s_pendingFlushes = 0; + if (s_pendingFlushes < 1) { + s_pendingFlushes = 0; scene->idle(); // Note: It would seem here we should undo suspended unredirect, but when scenes need // it for some reason, e.g. transformations or translucency, the next pass that does not @@ -408,7 +416,7 @@ void Workspace::performCompositing() // Otherwise the window would not be painted normally anyway. return; } - s_pending = pending; + // create a list of all windows in the stacking order ToplevelList windows = xStackingOrder(); foreach (EffectWindow *c, static_cast< EffectsHandlerImpl* >(effects)->elevatedWindows()) { @@ -430,6 +438,7 @@ void Workspace::performCompositing() repaints_region = QRegion(); m_timeSinceLastVBlank = scene->paint(repaints, windows); + // Trigger at least one more pass even if there would be nothing to paint, so that scene->idle() // is called the next time. If there would be nothing pending, it will not restart the timer and // checkCompositeTime() would restart it again somewhen later, called from functions that diff --git a/scene.h b/scene.h index 38911986f8..d6db74a575 100644 --- a/scene.h +++ b/scene.h @@ -49,6 +49,9 @@ public: // Returns true if the ctor failed to properly initialize. virtual bool initFailed() const = 0; virtual CompositingType compositingType() const = 0; + + virtual bool hasPendingFlush() const { return false; } + // Repaints the given screen areas, windows provides the stacking order. // The entry point for the main part of the painting pass. // returns the time since the last vblank signal - if there's one diff --git a/scene_opengl.h b/scene_opengl.h index de33ce4d00..8501a4e947 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -46,6 +46,7 @@ public: virtual CompositingType compositingType() const { return OpenGLCompositing; } + virtual bool hasPendingFlush() const { return !m_lastDamage.isEmpty(); } virtual int paint(QRegion damage, ToplevelList windows); virtual void windowAdded(Toplevel*); virtual void windowDeleted(Deleted*);