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.
This commit is contained in:
parent
ca0a2229cc
commit
4d2c9f5d88
11 changed files with 72 additions and 120 deletions
|
@ -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()) {
|
||||
|
|
131
src/options.cpp
131
src/options.cpp
|
@ -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…
Reference in a new issue