Introduce a config option whether applications are allowed to block compositing

Summary:
From feedback we got it seems that not all users agree to games and
other applications blocking compositing. Some users prefer to have
compositing always on even if this gives a small performance penelity.

This change introduces a dedicated config option to specify whether games
are allowed to block compositing. By default this option is enabled.

The setting can be overwritten with a window specific rule. So usecases
like all windows except this very specific one are supported.

In the user interface the config option is shown where previously the
unredirect fullscreen option was shown.

Test Plan:
Run a game which should block compositing, verified it blocks.
Changed the setting, run the game again, verified it doesn't block. And
once more for with allowing to block.

Reviewers: #kwin, #plasma_on_wayland, #vdg

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D2584
icc-effect-5.14.5
Martin Gräßlin 2016-08-26 08:56:42 +02:00
parent c6a840413a
commit 853020336f
8 changed files with 77 additions and 22 deletions

View File

@ -1822,7 +1822,7 @@ bool Client::acceptsFocus() const
void Client::setBlockingCompositing(bool block) void Client::setBlockingCompositing(bool block)
{ {
const bool usedToBlock = blocks_compositing; const bool usedToBlock = blocks_compositing;
blocks_compositing = rules()->checkBlockCompositing(block); blocks_compositing = rules()->checkBlockCompositing(block && options->windowsBlockCompositing());
if (usedToBlock != blocks_compositing) { if (usedToBlock != blocks_compositing) {
emit blockingCompositingChanged(blocks_compositing ? this : 0); emit blockingCompositingChanged(blocks_compositing ? this : 0);
} }

View File

@ -48,6 +48,7 @@ Compositing::Compositing(QObject *parent)
, m_changed(false) , m_changed(false)
, m_openGLPlatformInterfaceModel(new OpenGLPlatformInterfaceModel(this)) , m_openGLPlatformInterfaceModel(new OpenGLPlatformInterfaceModel(this))
, m_openGLPlatformInterface(0) , m_openGLPlatformInterface(0)
, m_windowsBlockCompositing(true)
{ {
reset(); reset();
connect(this, &Compositing::animationSpeedChanged, this, &Compositing::changed); connect(this, &Compositing::animationSpeedChanged, this, &Compositing::changed);
@ -59,6 +60,7 @@ Compositing::Compositing(QObject *parent)
connect(this, &Compositing::compositingTypeChanged, this, &Compositing::changed); connect(this, &Compositing::compositingTypeChanged, this, &Compositing::changed);
connect(this, &Compositing::compositingEnabledChanged, this, &Compositing::changed); connect(this, &Compositing::compositingEnabledChanged, this, &Compositing::changed);
connect(this, &Compositing::openGLPlatformInterfaceChanged, this, &Compositing::changed); connect(this, &Compositing::openGLPlatformInterfaceChanged, this, &Compositing::changed);
connect(this, &Compositing::windowsBlockCompositingChanged, this, &Compositing::changed);
connect(this, &Compositing::changed, [this]{ connect(this, &Compositing::changed, [this]{
m_changed = true; m_changed = true;
@ -112,6 +114,8 @@ void Compositing::reset()
const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(kwinConfig.readEntry("GLPlatformInterface", "glx")); const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(kwinConfig.readEntry("GLPlatformInterface", "glx"));
setOpenGLPlatformInterface(index.isValid() ? index.row() : 0); setOpenGLPlatformInterface(index.isValid() ? index.row() : 0);
setWindowsBlockCompositing(kwinConfig.readEntry("WindowsBlockCompositing", true));
m_changed = false; m_changed = false;
} }
@ -126,6 +130,7 @@ void Compositing::defaults()
setCompositingType(CompositingType::OPENGL20_INDEX); setCompositingType(CompositingType::OPENGL20_INDEX);
const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(QStringLiteral("glx")); const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(QStringLiteral("glx"));
setOpenGLPlatformInterface(index.isValid() ? index.row() : 0); setOpenGLPlatformInterface(index.isValid() ? index.row() : 0);
setWindowsBlockCompositing(true);
m_changed = true; m_changed = true;
} }
@ -324,6 +329,7 @@ void Compositing::save()
if (glIndex.isValid()) { if (glIndex.isValid()) {
kwinConfig.writeEntry("GLPlatformInterface", glIndex.data(Qt::UserRole).toString()); kwinConfig.writeEntry("GLPlatformInterface", glIndex.data(Qt::UserRole).toString());
} }
kwinConfig.writeEntry("WindowsBlockCompositing", windowsBlockCompositing());
kwinConfig.sync(); kwinConfig.sync();
if (m_changed) { if (m_changed) {
@ -355,6 +361,20 @@ void Compositing::setOpenGLPlatformInterface(int interface)
emit openGLPlatformInterfaceChanged(interface); emit openGLPlatformInterfaceChanged(interface);
} }
bool Compositing::windowsBlockCompositing() const
{
return m_windowsBlockCompositing;
}
void Compositing::setWindowsBlockCompositing(bool set)
{
if (m_windowsBlockCompositing == set) {
return;
}
m_windowsBlockCompositing = set;
emit windowsBlockCompositingChanged(set);
}
CompositingType::CompositingType(QObject *parent) CompositingType::CompositingType(QObject *parent)
: QAbstractItemModel(parent) { : QAbstractItemModel(parent) {

View File

@ -44,6 +44,7 @@ class Compositing : public QObject
Q_PROPERTY(bool compositingEnabled READ compositingEnabled WRITE setCompositingEnabled NOTIFY compositingEnabledChanged) Q_PROPERTY(bool compositingEnabled READ compositingEnabled WRITE setCompositingEnabled NOTIFY compositingEnabledChanged)
Q_PROPERTY(KWin::Compositing::OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel READ openGLPlatformInterfaceModel CONSTANT) Q_PROPERTY(KWin::Compositing::OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel READ openGLPlatformInterfaceModel CONSTANT)
Q_PROPERTY(int openGLPlatformInterface READ openGLPlatformInterface WRITE setOpenGLPlatformInterface NOTIFY openGLPlatformInterfaceChanged) Q_PROPERTY(int openGLPlatformInterface READ openGLPlatformInterface WRITE setOpenGLPlatformInterface NOTIFY openGLPlatformInterfaceChanged)
Q_PROPERTY(bool windowsBlockCompositing READ windowsBlockCompositing WRITE setWindowsBlockCompositing NOTIFY windowsBlockCompositingChanged)
public: public:
explicit Compositing(QObject *parent = 0); explicit Compositing(QObject *parent = 0);
@ -59,6 +60,7 @@ public:
int compositingType() const; int compositingType() const;
bool compositingEnabled() const; bool compositingEnabled() const;
int openGLPlatformInterface() const; int openGLPlatformInterface() const;
bool windowsBlockCompositing() const;
OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel() const; OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel() const;
@ -71,6 +73,7 @@ public:
void setCompositingType(int index); void setCompositingType(int index);
void setCompositingEnabled(bool enalbed); void setCompositingEnabled(bool enalbed);
void setOpenGLPlatformInterface(int interface); void setOpenGLPlatformInterface(int interface);
void setWindowsBlockCompositing(bool set);
void save(); void save();
@ -89,6 +92,7 @@ Q_SIGNALS:
void compositingTypeChanged(int); void compositingTypeChanged(int);
void compositingEnabledChanged(bool); void compositingEnabledChanged(bool);
void openGLPlatformInterfaceChanged(int); void openGLPlatformInterfaceChanged(int);
void windowsBlockCompositingChanged(bool);
private: private:
int m_animationSpeed; int m_animationSpeed;
@ -102,6 +106,7 @@ private:
bool m_changed; bool m_changed;
OpenGLPlatformInterfaceModel *m_openGLPlatformInterfaceModel; OpenGLPlatformInterfaceModel *m_openGLPlatformInterfaceModel;
int m_openGLPlatformInterface; int m_openGLPlatformInterface;
bool m_windowsBlockCompositing;
}; };

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>481</width> <width>462</width>
<height>349</height> <height>377</height>
</rect> </rect>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
@ -21,19 +21,16 @@
<property name="visible"> <property name="visible">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text" stdset="0">
<string>OpenGL compositing (the default) has crashed KWin in the past. <string>OpenGL compositing (the default) has crashed KWin in the past.
This was most likely due to a driver bug. This was most likely due to a driver bug.
If you think that you have meanwhile upgraded to a stable driver, If you think that you have meanwhile upgraded to a stable driver,
you can reset this protection but be aware that this might result in an immediate crash! you can reset this protection but be aware that this might result in an immediate crash!
Alternatively, you might want to use the XRender backend instead.</string> Alternatively, you might want to use the XRender backend instead.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap" stdset="0">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="messageType">
<enum>KMessageWidget::Warning</enum>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -41,15 +38,12 @@ Alternatively, you might want to use the XRender backend instead.</string>
<property name="visible"> <property name="visible">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text" stdset="0">
<string>Scale method &quot;Accurate&quot; is not supported by all hardware and can cause performance regressions and rendering artifacts.</string> <string>Scale method &quot;Accurate&quot; is not supported by all hardware and can cause performance regressions and rendering artifacts.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap" stdset="0">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="messageType">
<enum>KMessageWidget::Warning</enum>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -57,12 +51,9 @@ Alternatively, you might want to use the XRender backend instead.</string>
<property name="visible"> <property name="visible">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="wordWrap"> <property name="wordWrap" stdset="0">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="messageType">
<enum>KMessageWidget::Warning</enum>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -70,15 +61,12 @@ Alternatively, you might want to use the XRender backend instead.</string>
<property name="visible"> <property name="visible">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text" stdset="0">
<string>Keeping the window thumbnail always interferes with the minimized state of windows. This can result in windows not suspending their work when minimized.</string> <string>Keeping the window thumbnail always interferes with the minimized state of windows. This can result in windows not suspending their work when minimized.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap" stdset="0">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="messageType">
<enum>KMessageWidget::Warning</enum>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -295,6 +283,18 @@ Alternatively, you might want to use the XRender backend instead.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="1">
<widget class="QCheckBox" name="windowsBlockCompositing">
<property name="toolTip">
<string>Applications can set a hint to block compositing when the window is open.
This brings performance improvements for e.g. games.
The setting can be overruled by window-specific rules.</string>
</property>
<property name="text">
<string>Allow applications to block compositing</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

View File

@ -169,6 +169,11 @@ void KWinCompositingSettings::init()
connect(m_compositing, &Compositing::glColorCorrectionChanged, m_form.colorCorrection, &QCheckBox::setChecked); connect(m_compositing, &Compositing::glColorCorrectionChanged, m_form.colorCorrection, &QCheckBox::setChecked);
connect(m_form.colorCorrection, &QCheckBox::toggled, m_compositing, &Compositing::setGlColorCorrection); connect(m_form.colorCorrection, &QCheckBox::toggled, m_compositing, &Compositing::setGlColorCorrection);
// windows blocking compositing
m_form.windowsBlockCompositing->setChecked(m_compositing->windowsBlockCompositing());
connect(m_compositing, &Compositing::windowsBlockCompositingChanged, m_form.windowsBlockCompositing, &QCheckBox::setChecked);
connect(m_form.windowsBlockCompositing, &QCheckBox::toggled, m_compositing, &Compositing::setWindowsBlockCompositing);
// compositing type // compositing type
CompositingType *type = new CompositingType(this); CompositingType *type = new CompositingType(this);
m_form.type->setModel(type); m_form.type->setModel(type);

View File

@ -262,6 +262,9 @@
<entry name="GLPlatformInterface" type="String"> <entry name="GLPlatformInterface" type="String">
<default>glx</default> <default>glx</default>
</entry> </entry>
<entry name="WindowsBlockCompositing" type="Bool">
<default>true</default>
</entry>
</group> </group>
<group name="TabBox"> <group name="TabBox">
<entry name="ShowDelay" type="Bool"> <entry name="ShowDelay" type="Bool">

View File

@ -125,6 +125,7 @@ Options::Options(QObject *parent)
, m_glCoreProfile(Options::defaultGLCoreProfile()) , m_glCoreProfile(Options::defaultGLCoreProfile())
, m_glPreferBufferSwap(Options::defaultGlPreferBufferSwap()) , m_glPreferBufferSwap(Options::defaultGlPreferBufferSwap())
, m_glPlatformInterface(Options::defaultGlPlatformInterface()) , m_glPlatformInterface(Options::defaultGlPlatformInterface())
, m_windowsBlockCompositing(true)
, OpTitlebarDblClick(Options::defaultOperationTitlebarDblClick()) , OpTitlebarDblClick(Options::defaultOperationTitlebarDblClick())
, CmdActiveTitlebar1(Options::defaultCommandActiveTitlebar1()) , CmdActiveTitlebar1(Options::defaultCommandActiveTitlebar1())
, CmdActiveTitlebar2(Options::defaultCommandActiveTitlebar2()) , CmdActiveTitlebar2(Options::defaultCommandActiveTitlebar2())
@ -714,6 +715,15 @@ void Options::setGLCoreProfile(bool value)
emit glCoreProfileChanged(); emit glCoreProfileChanged();
} }
void Options::setWindowsBlockCompositing(bool value)
{
if (m_windowsBlockCompositing == value) {
return;
}
m_windowsBlockCompositing = value;
emit windowsBlockCompositingChanged();
}
void Options::setGlPreferBufferSwap(char glPreferBufferSwap) void Options::setGlPreferBufferSwap(char glPreferBufferSwap)
{ {
if (glPreferBufferSwap == 'a') { if (glPreferBufferSwap == 'a') {
@ -886,6 +896,7 @@ void Options::syncFromKcfgc()
setElectricBorderMaximize(m_settings->electricBorderMaximize()); setElectricBorderMaximize(m_settings->electricBorderMaximize());
setElectricBorderTiling(m_settings->electricBorderTiling()); setElectricBorderTiling(m_settings->electricBorderTiling());
setElectricBorderCornerRatio(m_settings->electricBorderCornerRatio()); setElectricBorderCornerRatio(m_settings->electricBorderCornerRatio());
setWindowsBlockCompositing(m_settings->windowsBlockCompositing());
} }
@ -956,6 +967,8 @@ void Options::reloadCompositingSettings(bool force)
if (!loadCompositingConfig(force)) { if (!loadCompositingConfig(force)) {
return; return;
} }
m_settings->load();
syncFromKcfgc();
// from now on we've an initial setup and don't have to reload settings on compositing activation // from now on we've an initial setup and don't have to reload settings on compositing activation
// see Workspace::setupCompositing(), composite.cpp // see Workspace::setupCompositing(), composite.cpp
setCompositingInitialized(true); setCompositingInitialized(true);

View File

@ -190,6 +190,7 @@ class KWIN_EXPORT Options : public QObject
Q_PROPERTY(bool glCoreProfile READ glCoreProfile WRITE setGLCoreProfile NOTIFY glCoreProfileChanged) Q_PROPERTY(bool glCoreProfile READ glCoreProfile WRITE setGLCoreProfile NOTIFY glCoreProfileChanged)
Q_PROPERTY(GlSwapStrategy glPreferBufferSwap READ glPreferBufferSwap WRITE setGlPreferBufferSwap NOTIFY glPreferBufferSwapChanged) Q_PROPERTY(GlSwapStrategy glPreferBufferSwap READ glPreferBufferSwap WRITE setGlPreferBufferSwap NOTIFY glPreferBufferSwapChanged)
Q_PROPERTY(KWin::OpenGLPlatformInterface glPlatformInterface READ glPlatformInterface WRITE setGlPlatformInterface NOTIFY glPlatformInterfaceChanged) Q_PROPERTY(KWin::OpenGLPlatformInterface glPlatformInterface READ glPlatformInterface WRITE setGlPlatformInterface NOTIFY glPlatformInterfaceChanged)
Q_PROPERTY(bool windowsBlockCompositing READ windowsBlockCompositing WRITE setWindowsBlockCompositing NOTIFY windowsBlockCompositingChanged)
public: public:
explicit Options(QObject *parent = NULL); explicit Options(QObject *parent = NULL);
@ -593,6 +594,11 @@ public:
return m_glPreferBufferSwap; return m_glPreferBufferSwap;
} }
bool windowsBlockCompositing() const
{
return m_windowsBlockCompositing;
}
QStringList modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const; QStringList modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const;
// setters // setters
@ -656,6 +662,7 @@ public:
void setGLCoreProfile(bool glCoreProfile); void setGLCoreProfile(bool glCoreProfile);
void setGlPreferBufferSwap(char glPreferBufferSwap); void setGlPreferBufferSwap(char glPreferBufferSwap);
void setGlPlatformInterface(OpenGLPlatformInterface interface); void setGlPlatformInterface(OpenGLPlatformInterface interface);
void setWindowsBlockCompositing(bool set);
// default values // default values
static WindowOperation defaultOperationTitlebarDblClick() { static WindowOperation defaultOperationTitlebarDblClick() {
@ -848,6 +855,7 @@ Q_SIGNALS:
void glCoreProfileChanged(); void glCoreProfileChanged();
void glPreferBufferSwapChanged(); void glPreferBufferSwapChanged();
void glPlatformInterfaceChanged(); void glPlatformInterfaceChanged();
void windowsBlockCompositingChanged();
void configChanged(); void configChanged();
@ -897,6 +905,7 @@ private:
bool m_glCoreProfile; bool m_glCoreProfile;
GlSwapStrategy m_glPreferBufferSwap; GlSwapStrategy m_glPreferBufferSwap;
OpenGLPlatformInterface m_glPlatformInterface; OpenGLPlatformInterface m_glPlatformInterface;
bool m_windowsBlockCompositing;
WindowOperation OpTitlebarDblClick; WindowOperation OpTitlebarDblClick;
WindowOperation opMaxButtonRightClick = defaultOperationMaxButtonRightClick(); WindowOperation opMaxButtonRightClick = defaultOperationMaxButtonRightClick();