[effects] Make current OpenGL context per each unloaded effect

Summary:
Some effects may release the current context when they tear down, so we
have to make the current context per each unloaded effect.

BUG: 396830
FIXED-IN: 5.15.0

Test Plan: No longer able to reproduce bug 396830.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: davidedmundson, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D17716
This commit is contained in:
Vlad Zagorodniy 2018-12-19 16:44:06 +02:00
parent f3060723e1
commit 9ac2e5d5bb
2 changed files with 39 additions and 33 deletions

View file

@ -273,19 +273,8 @@ EffectsHandlerImpl::~EffectsHandlerImpl()
void EffectsHandlerImpl::unloadAllEffects()
{
makeOpenGLContextCurrent();
if (keyboard_grab_effect != NULL)
ungrabKeyboard();
setActiveFullScreenEffect(nullptr);
for (auto it = loaded_effects.begin(); it != loaded_effects.end(); ++it) {
Effect *effect = (*it).second;
stopMouseInterception(effect);
// remove support properties for the effect
const QList<QByteArray> properties = m_propertiesForEffects.keys();
for (const QByteArray &property : properties) {
removeSupportProperty(property, effect);
}
delete effect;
for (const EffectPair &pair : loaded_effects) {
destroyEffect(pair.second);
}
effect_order.clear();
@ -1394,29 +1383,44 @@ bool EffectsHandlerImpl::loadEffect(const QString& name)
void EffectsHandlerImpl::unloadEffect(const QString& name)
{
makeOpenGLContextCurrent();
m_compositor->addRepaintFull();
for (QMap< int, EffectPair >::iterator it = effect_order.begin(); it != effect_order.end(); ++it) {
if (it.value().first == name) {
qCDebug(KWIN_CORE) << "EffectsHandler::unloadEffect : Unloading Effect : " << name;
if (activeFullScreenEffect() == it.value().second) {
setActiveFullScreenEffect(0);
}
stopMouseInterception(it.value().second);
// remove support properties for the effect
const QList<QByteArray> properties = m_propertiesForEffects.keys();
for (const QByteArray &property : properties) {
removeSupportProperty(property, it.value().second);
}
delete it.value().second;
effect_order.erase(it);
effectsChanged();
return;
auto it = std::find_if(effect_order.begin(), effect_order.end(),
[name](EffectPair &pair) {
return pair.first == name;
}
);
if (it == effect_order.end()) {
qCDebug(KWIN_CORE) << "EffectsHandler::unloadEffect : Effect not loaded :" << name;
return;
}
qCDebug(KWIN_CORE) << "EffectsHandler::unloadEffect : Effect not loaded : " << name;
qCDebug(KWIN_CORE) << "EffectsHandler::unloadEffect : Unloading Effect :" << name;
destroyEffect((*it).second);
effect_order.erase(it);
effectsChanged();
m_compositor->addRepaintFull();
}
void EffectsHandlerImpl::destroyEffect(Effect *effect)
{
makeOpenGLContextCurrent();
if (fullscreen_effect == effect) {
setActiveFullScreenEffect(nullptr);
}
if (keyboard_grab_effect == effect) {
ungrabKeyboard();
}
stopMouseInterception(effect);
const QList<QByteArray> properties = m_propertiesForEffects.keys();
for (const QByteArray &property : properties) {
removeSupportProperty(property, effect);
}
delete effect;
}
void EffectsHandlerImpl::reconfigureEffect(const QString& name)

View file

@ -340,6 +340,8 @@ protected:
private:
void registerPropertyType(long atom, bool reg);
void destroyEffect(Effect *effect);
typedef QVector< Effect*> EffectsList;
typedef EffectsList::const_iterator EffectsIterator;
EffectsList m_activeEffects;