Keep KWin responsive while loading all effects
Loading all effects during startup can take some time[1] and during that time the screen is frozen as the loading blocks the compositor. This change doesn't load effects directly but puts them into a queue. The loading is controlled by invoking the dequeue through a queued connection. Thus we get a firing compositing timer in between and can ensure that a frame is rendered when needed and also react to X events during the loading. [1] On my high-end system the set of effects I use take about 200 msec to load. REVIEW: 115297icc-effect-5.14.5
parent
1576c55cd2
commit
29af52fbf1
42
effects.cpp
42
effects.cpp
|
@ -167,6 +167,41 @@ void ScreenLockerWatcher::setLocked(bool activated)
|
|||
emit locked(m_locked);
|
||||
}
|
||||
|
||||
EffectLoader::EffectLoader(EffectsHandlerImpl *parent)
|
||||
: QObject(parent)
|
||||
, m_effects(parent)
|
||||
, m_dequeueScheduled(false)
|
||||
{
|
||||
}
|
||||
|
||||
EffectLoader::~EffectLoader()
|
||||
{
|
||||
}
|
||||
|
||||
void EffectLoader::queue(const QString &effect, bool checkDefault)
|
||||
{
|
||||
m_queue.enqueue(qMakePair(effect, checkDefault));
|
||||
scheduleDequeue();
|
||||
}
|
||||
|
||||
void EffectLoader::dequeue()
|
||||
{
|
||||
Q_ASSERT(!m_queue.isEmpty());
|
||||
m_dequeueScheduled = false;
|
||||
const auto pair = m_queue.dequeue();
|
||||
m_effects->loadEffect(pair.first, pair.second);
|
||||
scheduleDequeue();
|
||||
}
|
||||
|
||||
void EffectLoader::scheduleDequeue()
|
||||
{
|
||||
if (m_queue.isEmpty() || m_dequeueScheduled) {
|
||||
return;
|
||||
}
|
||||
m_dequeueScheduled = true;
|
||||
QMetaObject::invokeMethod(this, "dequeue", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
//---------------------
|
||||
// Static
|
||||
|
||||
|
@ -211,6 +246,7 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
|
|||
, m_screenLockerWatcher(new ScreenLockerWatcher(this))
|
||||
, m_desktopRendering(false)
|
||||
, m_currentRenderedDesktop(0)
|
||||
, m_effectLoader(new EffectLoader(this))
|
||||
{
|
||||
new EffectsAdaptor(this);
|
||||
QDBusConnection dbus = QDBusConnection::sessionBus();
|
||||
|
@ -354,8 +390,8 @@ void EffectsHandlerImpl::slotEffectsQueried()
|
|||
// Then load those that should be loaded
|
||||
for (const QString & effectName : effectsToBeLoaded) {
|
||||
if (!isEffectLoaded(effectName)) {
|
||||
if (loadEffect(effectName, checkDefault.contains(effectName)))
|
||||
newLoaded.append(effectName);
|
||||
m_effectLoader->queue(effectName, checkDefault.contains(effectName));
|
||||
newLoaded.append(effectName);
|
||||
}
|
||||
}
|
||||
for (const EffectPair & ep : loaded_effects) {
|
||||
|
@ -1587,7 +1623,7 @@ void EffectsHandlerImpl::reloadEffect(Effect *effect)
|
|||
}
|
||||
if (!effectName.isNull()) {
|
||||
unloadEffect(effectName);
|
||||
loadEffect(effectName);
|
||||
m_effectLoader->queue(effectName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
20
effects.h
20
effects.h
|
@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <QStack>
|
||||
#include <QHash>
|
||||
#include <QQueue>
|
||||
#include <Plasma/FrameSvg>
|
||||
|
||||
namespace Plasma {
|
||||
|
@ -51,6 +52,7 @@ class WindowThumbnailItem;
|
|||
class Client;
|
||||
class Compositor;
|
||||
class Deleted;
|
||||
class EffectLoader;
|
||||
class Unmanaged;
|
||||
class ScreenLockerWatcher;
|
||||
|
||||
|
@ -282,6 +284,7 @@ private:
|
|||
int m_currentRenderedDesktop;
|
||||
Xcb::Window m_mouseInterceptionWindow;
|
||||
QList<Effect*> m_grabbedMouseEffects;
|
||||
EffectLoader *m_effectLoader;
|
||||
};
|
||||
|
||||
class EffectWindowImpl : public EffectWindow
|
||||
|
@ -462,6 +465,23 @@ private:
|
|||
bool m_locked;
|
||||
};
|
||||
|
||||
class EffectLoader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EffectLoader(EffectsHandlerImpl *parent);
|
||||
virtual ~EffectLoader();
|
||||
|
||||
void queue(const QString &effect, bool checkDefault = false);
|
||||
private Q_SLOTS:
|
||||
void dequeue();
|
||||
private:
|
||||
void scheduleDequeue();
|
||||
EffectsHandlerImpl *m_effects;
|
||||
QQueue<QPair<QString, bool>> m_queue;
|
||||
bool m_dequeueScheduled;
|
||||
};
|
||||
|
||||
inline
|
||||
QList<EffectWindow*> EffectsHandlerImpl::elevatedWindows() const
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue