Refactor compositing config loading

Config loading is split in two groups: loading compositing config and
loading the rest. They are loaded separately at different times. Some
options are loaded in the Options constructor, some are loaded when compositing
starts, some are loaded when the Workspace is created. It's not easy to
keep track of what loads what and when.

This change simplifies option handling by loading all options in bulk
and decouples Options from OutputBackend and GLPlatform to ensure that
it can safely load options before kwin is fully operational.
master
Vlad Zahorodnii 1 year ago
parent ca0a2229cc
commit 4d2c9f5d88

@ -174,6 +174,18 @@ void EglBackend::init()
qCWarning(KWIN_CORE) << "eglPostSubBufferNV not supported, have to enable buffer preservation - which breaks v-sync and performance";
eglSurfaceAttrib(eglDisplayObject()->handle(), surface(), EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
}
m_swapStrategy = options->glPreferBufferSwap();
if (m_swapStrategy == Options::AutoSwapStrategy) {
// buffer copying is very fast with the nvidia blob
// but due to restrictions in DRI2 *incredibly* slow for all MESA drivers
// see https://www.x.org/releases/X11R7.7/doc/dri2proto/dri2proto.txt, item 2.5
if (GLPlatform::instance()->driver() == Driver_NVidia) {
m_swapStrategy = Options::CopyFrontBuffer;
} else if (GLPlatform::instance()->driver() != Driver_Unknown) { // undetected, finally resolved when context is initialized
m_swapStrategy = Options::ExtendDamage;
}
}
}
bool EglBackend::initRenderingContext()
@ -358,7 +370,7 @@ void EglBackend::present(Output *output)
QRegion effectiveRenderedRegion = m_lastRenderedRegion;
if (!GLPlatform::instance()->isGLES()) {
const QRect displayRect = workspace()->geometry();
if (!supportsBufferAge() && options->glPreferBufferSwap() == Options::CopyFrontBuffer && m_lastRenderedRegion != displayRect) {
if (!supportsBufferAge() && m_swapStrategy == Options::CopyFrontBuffer && m_lastRenderedRegion != displayRect) {
glReadBuffer(GL_FRONT);
copyPixels(QRegion(displayRect) - m_lastRenderedRegion, displayRect.size());
glReadBuffer(GL_BACK);

@ -7,6 +7,7 @@
#pragma once
#include "core/outputlayer.h"
#include "options.h"
#include "platformsupport/scenes/opengl/abstract_egl_backend.h"
#include "platformsupport/scenes/opengl/openglsurfacetexture_x11.h"
#include "utils/damagejournal.h"
@ -78,6 +79,7 @@ private:
std::unique_ptr<GLRenderTimeQuery> m_query;
int m_havePostSubBuffer = false;
bool m_havePlatformBase = false;
Options::GlSwapStrategy m_swapStrategy = Options::AutoSwapStrategy;
};
class EglPixmapTexture : public GLTexture

@ -225,10 +225,19 @@ void GlxBackend::init()
// Initialize OpenGL
GLPlatform *glPlatform = GLPlatform::instance();
glPlatform->detect(GlxPlatformInterface);
options->setGlPreferBufferSwap(options->glPreferBufferSwap()); // resolve autosetting
if (options->glPreferBufferSwap() == Options::AutoSwapStrategy) {
options->setGlPreferBufferSwap('e'); // for unknown drivers - should not happen
m_swapStrategy = options->glPreferBufferSwap();
if (m_swapStrategy == Options::AutoSwapStrategy) {
// buffer copying is very fast with the nvidia blob
// but due to restrictions in DRI2 *incredibly* slow for all MESA drivers
// see https://www.x.org/releases/X11R7.7/doc/dri2proto/dri2proto.txt, item 2.5
if (GLPlatform::instance()->driver() == Driver_NVidia) {
m_swapStrategy = Options::CopyFrontBuffer;
} else if (GLPlatform::instance()->driver() != Driver_Unknown) { // undetected, finally resolved when context is initialized
m_swapStrategy = Options::ExtendDamage;
}
}
glPlatform->printResults();
initGL(&getProcAddress);
@ -731,7 +740,7 @@ void GlxBackend::present(Output *output)
const QRect displayRect = workspace()->geometry();
QRegion effectiveRenderedRegion = m_lastRenderedRegion;
if (!supportsBufferAge() && options->glPreferBufferSwap() == Options::CopyFrontBuffer && m_lastRenderedRegion != displayRect) {
if (!supportsBufferAge() && m_swapStrategy == Options::CopyFrontBuffer && m_lastRenderedRegion != displayRect) {
glReadBuffer(GL_FRONT);
copyPixels(QRegion(displayRect) - m_lastRenderedRegion, displayRect.size());
glReadBuffer(GL_BACK);

@ -8,6 +8,7 @@
*/
#pragma once
#include "core/outputlayer.h"
#include "options.h"
#include "platformsupport/scenes/opengl/openglbackend.h"
#include "platformsupport/scenes/opengl/openglsurfacetexture_x11.h"
#include "utils/damagejournal.h"
@ -138,6 +139,7 @@ private:
std::unique_ptr<VsyncMonitor> m_vsyncMonitor;
std::unique_ptr<GlxLayer> m_layer;
std::unique_ptr<GLRenderTimeQuery> m_query;
Options::GlSwapStrategy m_swapStrategy = Options::AutoSwapStrategy;
friend class GlxPixmapTexture;
};

@ -204,8 +204,6 @@ bool Compositor::setupStart()
}
m_state = State::Starting;
options->reloadCompositingSettings(true);
initializeX11();
Q_EMIT aboutToToggleCompositing();

@ -134,7 +134,6 @@ void ApplicationWayland::performStartup()
setOperationMode(OperationModeXwayland);
setXwaylandScale(config()->group("Xwayland").readEntry("Scale", 1.0));
}
// first load options - done internally by a different thread
createOptions();
if (!outputBackend()->initialize()) {

@ -259,7 +259,6 @@ void ApplicationX11::performStartup()
connect(owner.get(), &KSelectionOwner::lostOwnership, this, &ApplicationX11::lostSelection);
connect(owner.get(), &KSelectionOwner::claimedOwnership, this, [this] {
installNativeX11EventFilter();
// first load options - done internally by a different thread
createOptions();
if (!outputBackend()->initialize()) {

@ -12,14 +12,12 @@
#include "config-kwin.h"
#include "core/outputbackend.h"
#include "utils/common.h"
#ifndef KCMRULES
#include <QProcess>
#include "libkwineffects/glplatform.h"
#include "settings.h"
#include "workspace.h"
#include <QOpenGLContext>
@ -92,7 +90,8 @@ Options::Options(QObject *parent)
, condensed_title(false)
{
m_settings->setDefaults();
syncFromKcfgc();
loadConfig();
m_configWatcher = KConfigWatcher::create(m_settings->sharedConfig());
connect(m_configWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) {
@ -612,16 +611,6 @@ void Options::setWindowsBlockCompositing(bool value)
void Options::setGlPreferBufferSwap(char glPreferBufferSwap)
{
if (glPreferBufferSwap == 'a') {
// buffer copying is very fast with the nvidia blob
// but due to restrictions in DRI2 *incredibly* slow for all MESA drivers
// see https://www.x.org/releases/X11R7.7/doc/dri2proto/dri2proto.txt, item 2.5
if (GLPlatform::instance()->driver() == Driver_NVidia) {
glPreferBufferSwap = CopyFrontBuffer;
} else if (GLPlatform::instance()->driver() != Driver_Unknown) { // undetected, finally resolved when context is initialized
glPreferBufferSwap = ExtendDamage;
}
}
if (m_glPreferBufferSwap == (GlSwapStrategy)glPreferBufferSwap) {
return;
}
@ -715,16 +704,6 @@ void Options::reparseConfiguration()
void Options::updateSettings()
{
loadConfig();
// Read button tooltip animation effect from kdeglobals
// Since we want to allow users to enable window decoration tooltips
// and not kstyle tooltips and vise-versa, we don't read the
// "EffectNoTooltip" setting from kdeglobals.
// QToolTip::setGloballyEnabled( d->show_tooltips );
// KDE4 this probably needs to be done manually in clients
// Driver-specific config detection
reloadCompositingSettings();
Q_EMIT configChanged();
}
@ -775,48 +754,9 @@ void Options::loadConfig()
m_modifierOnlyShortcuts.insert(Qt::AltModifier, config.readEntry("Alt", QStringList()));
}
m_modifierOnlyShortcuts.insert(Qt::MetaModifier, config.readEntry("Meta", QStringList{QStringLiteral("org.kde.plasmashell"), QStringLiteral("/PlasmaShell"), QStringLiteral("org.kde.PlasmaShell"), QStringLiteral("activateLauncherMenu")}));
}
void Options::syncFromKcfgc()
{
setCondensedTitle(m_settings->condensedTitle());
setFocusPolicy(m_settings->focusPolicy());
setNextFocusPrefersMouse(m_settings->nextFocusPrefersMouse());
setSeparateScreenFocus(m_settings->separateScreenFocus());
setActiveMouseScreen(m_settings->activeMouseScreen());
setRollOverDesktops(m_settings->rollOverDesktops());
setFocusStealingPreventionLevel(m_settings->focusStealingPreventionLevel());
setActivationDesktopPolicy(m_settings->activationDesktopPolicy());
setXwaylandCrashPolicy(m_settings->xwaylandCrashPolicy());
setXwaylandMaxCrashCount(m_settings->xwaylandMaxCrashCount());
setXwaylandEavesdrops(XwaylandEavesdropsMode(m_settings->xwaylandEavesdrops()));
setPlacement(m_settings->placement());
setAutoRaise(m_settings->autoRaise());
setAutoRaiseInterval(m_settings->autoRaiseInterval());
setDelayFocusInterval(m_settings->delayFocusInterval());
setShadeHover(m_settings->shadeHover());
setShadeHoverInterval(m_settings->shadeHoverInterval());
setClickRaise(m_settings->clickRaise());
setBorderSnapZone(m_settings->borderSnapZone());
setWindowSnapZone(m_settings->windowSnapZone());
setCenterSnapZone(m_settings->centerSnapZone());
setSnapOnlyWhenOverlapping(m_settings->snapOnlyWhenOverlapping());
setKillPingTimeout(m_settings->killPingTimeout());
setHideUtilityWindowsForInactive(m_settings->hideUtilityWindowsForInactive());
setBorderlessMaximizedWindows(m_settings->borderlessMaximizedWindows());
setElectricBorderMaximize(m_settings->electricBorderMaximize());
setElectricBorderTiling(m_settings->electricBorderTiling());
setElectricBorderCornerRatio(m_settings->electricBorderCornerRatio());
setWindowsBlockCompositing(m_settings->windowsBlockCompositing());
setLatencyPolicy(m_settings->latencyPolicy());
setRenderTimeEstimator(m_settings->renderTimeEstimator());
setAllowTearing(m_settings->allowTearing());
}
bool Options::loadCompositingConfig(bool force)
{
KConfigGroup config(m_settings->config(), "Compositing");
// Compositing
config = KConfigGroup(m_settings->config(), "Compositing");
bool useCompositing = false;
CompositingType compositingMode = NoCompositing;
QString compositingBackend = config.readEntry("Backend", "OpenGL");
@ -852,32 +792,7 @@ bool Options::loadCompositingConfig(bool force)
}
}
setCompositingMode(compositingMode);
const bool platformSupportsNoCompositing = kwinApp()->outputBackend()->supportedCompositors().contains(NoCompositing);
if (m_compositingMode == NoCompositing && platformSupportsNoCompositing) {
setUseCompositing(false);
return false; // do not even detect compositing preferences if explicitly disabled
}
// it's either enforced by env or by initial resume from "suspend" or we check the settings
setUseCompositing(useCompositing || force || config.readEntry("Enabled", Options::defaultUseCompositing() || !platformSupportsNoCompositing));
if (!m_useCompositing) {
return false; // not enforced or necessary and not "enabled" by settings
}
return true;
}
void Options::reloadCompositingSettings(bool force)
{
if (!loadCompositingConfig(force)) {
return;
}
m_settings->load();
syncFromKcfgc();
// Compositing settings
KConfigGroup config(m_settings->config(), "Compositing");
setUseCompositing(useCompositing || config.readEntry("Enabled", Options::defaultUseCompositing()));
setGlSmoothScale(std::clamp(config.readEntry("GLTextureFilter", Options::defaultGlSmoothScale()), -1, 2));
setGlStrictBindingFollowsDriver(!config.hasKey("GLStrictBinding"));
@ -928,6 +843,42 @@ void Options::reloadCompositingSettings(bool force)
setGlPlatformInterface(keyToInterface(config.readEntry("GLPlatformInterface", interfaceToKey(m_glPlatformInterface))));
}
void Options::syncFromKcfgc()
{
setCondensedTitle(m_settings->condensedTitle());
setFocusPolicy(m_settings->focusPolicy());
setNextFocusPrefersMouse(m_settings->nextFocusPrefersMouse());
setSeparateScreenFocus(m_settings->separateScreenFocus());
setActiveMouseScreen(m_settings->activeMouseScreen());
setRollOverDesktops(m_settings->rollOverDesktops());
setFocusStealingPreventionLevel(m_settings->focusStealingPreventionLevel());
setActivationDesktopPolicy(m_settings->activationDesktopPolicy());
setXwaylandCrashPolicy(m_settings->xwaylandCrashPolicy());
setXwaylandMaxCrashCount(m_settings->xwaylandMaxCrashCount());
setXwaylandEavesdrops(XwaylandEavesdropsMode(m_settings->xwaylandEavesdrops()));
setPlacement(m_settings->placement());
setAutoRaise(m_settings->autoRaise());
setAutoRaiseInterval(m_settings->autoRaiseInterval());
setDelayFocusInterval(m_settings->delayFocusInterval());
setShadeHover(m_settings->shadeHover());
setShadeHoverInterval(m_settings->shadeHoverInterval());
setClickRaise(m_settings->clickRaise());
setBorderSnapZone(m_settings->borderSnapZone());
setWindowSnapZone(m_settings->windowSnapZone());
setCenterSnapZone(m_settings->centerSnapZone());
setSnapOnlyWhenOverlapping(m_settings->snapOnlyWhenOverlapping());
setKillPingTimeout(m_settings->killPingTimeout());
setHideUtilityWindowsForInactive(m_settings->hideUtilityWindowsForInactive());
setBorderlessMaximizedWindows(m_settings->borderlessMaximizedWindows());
setElectricBorderMaximize(m_settings->electricBorderMaximize());
setElectricBorderTiling(m_settings->electricBorderTiling());
setElectricBorderCornerRatio(m_settings->electricBorderCornerRatio());
setWindowsBlockCompositing(m_settings->windowsBlockCompositing());
setLatencyPolicy(m_settings->latencyPolicy());
setRenderTimeEstimator(m_settings->renderTimeEstimator());
setAllowTearing(m_settings->allowTearing());
}
// restricted should be true for operations that the user may not be able to repeat
// if the window is moved out of the workspace (e.g. if the user moves a window
// by the titlebar, and moves it too high beneath Kicker at the top edge, they

@ -640,7 +640,6 @@ public:
//----------------------
// Compositing settings
void reloadCompositingSettings(bool force = false);
CompositingType compositingMode() const
{
return m_compositingMode;
@ -903,10 +902,6 @@ public:
* Performs loading all settings except compositing related.
*/
void loadConfig();
/**
* Performs loading of compositing settings which do not depend on OpenGL.
*/
bool loadCompositingConfig(bool force);
void reparseConfiguration();
//----------------------

@ -9,7 +9,7 @@
#include "platformsupport/scenes/opengl/abstract_egl_backend.h"
#include "compositor.h"
#include "core/outputbackend.h"
#include "options.h"
#include "main.h"
#include "utils/common.h"
#include "utils/egl_context_attribute_builder.h"
#include "wayland/drmclientbuffer.h"
@ -115,10 +115,6 @@ void AbstractEglBackend::initKWinGL()
{
GLPlatform *glPlatform = GLPlatform::instance();
glPlatform->detect(EglPlatformInterface);
options->setGlPreferBufferSwap(options->glPreferBufferSwap()); // resolve autosetting
if (options->glPreferBufferSwap() == Options::AutoSwapStrategy) {
options->setGlPreferBufferSwap('e'); // for unknown drivers - should not happen
}
glPlatform->printResults();
initGL(&getProcAddress);
}

@ -64,8 +64,6 @@
#include <KConfigGroup>
#include <KLocalizedString>
#include <KStartupInfo>
// Qt
#include <QtConcurrentRun>
// xcb
#include <xcb/xinerama.h>
@ -133,9 +131,6 @@ Workspace::Workspace()
, m_outputConfigStore(std::make_unique<OutputConfigurationStore>())
, m_lidSwitchTracker(std::make_unique<LidSwitchTracker>())
{
// If KWin was already running it saved its configuration after loosing the selection -> Reread
QFuture<void> reparseConfigFuture = QtConcurrent::run(&Options::reparseConfiguration, options);
_self = this;
#if KWIN_BUILD_ACTIVITIES
@ -147,12 +142,6 @@ Workspace::Workspace()
}
#endif
// PluginMgr needs access to the config file, so we need to wait for it for finishing
reparseConfigFuture.waitForFinished();
options->loadConfig();
options->loadCompositingConfig(false);
delayFocusTimer = nullptr;
m_quickTileCombineTimer = new QTimer(this);

Loading…
Cancel
Save