platforms/x11: Disable swap events by default on Intel

Some users reported performances issues after recent compositing
scheduling changes, in particular animations being laggy.

The issue is that sometimes it may take more than a vblank interval for
a buffer swap to complete. Previously, compositing was driven by a
timer and it wasn't synchronized to vblanks. If some frame is running
late, the compositor will just start painting a new frame, i.e. the
screen will be rendered triple buffered.

This change disables the swap events code path on Intel to restore the
previous behavior. Unfortunately, that may add an extra frame of latency.

The swap events code path can be enabled explicitly on Intel by setting
the KWIN_USE_INTEL_SWAP_EVENT environment variable to 1.
This commit is contained in:
Vlad Zahorodnii 2021-01-26 16:14:35 +02:00
parent 6aea213c84
commit 76effae5ca

View file

@ -200,13 +200,14 @@ void GlxBackend::init()
glPlatform->printResults();
initGL(&getProcAddress);
const bool swapEventSwitch = qEnvironmentVariableIntValue("KWIN_USE_INTEL_SWAP_EVENT");
// Check whether certain features are supported
m_haveMESACopySubBuffer = hasExtension(QByteArrayLiteral("GLX_MESA_copy_sub_buffer"));
m_haveMESASwapControl = hasExtension(QByteArrayLiteral("GLX_MESA_swap_control"));
m_haveEXTSwapControl = hasExtension(QByteArrayLiteral("GLX_EXT_swap_control"));
m_haveSGISwapControl = hasExtension(QByteArrayLiteral("GLX_SGI_swap_control"));
m_haveINTELSwapEvent = hasExtension(QByteArrayLiteral("GLX_INTEL_swap_event"))
&& qgetenv("KWIN_USE_INTEL_SWAP_EVENT") != QByteArrayLiteral("0");
m_haveINTELSwapEvent = hasExtension(QByteArrayLiteral("GLX_INTEL_swap_event")) && swapEventSwitch;
bool haveSwapInterval = m_haveMESASwapControl || m_haveEXTSwapControl || m_haveSGISwapControl;
@ -225,6 +226,16 @@ void GlxBackend::init()
m_haveINTELSwapEvent = false;
}
// Don't use swap events on Intel. The issue with Intel GPUs is that they are not as
// powerful as discrete GPUs. Therefore, it's better to push frames as often as vblank
// notifications are received. This, however, may increase latency. If the swap events
// are enabled explicitly by setting the environment variable, honor that choice.
if (glPlatform->isIntel()) {
if (!swapEventSwitch) {
m_haveINTELSwapEvent = false;
}
}
if (haveSwapInterval) {
setSwapInterval(1);
} else {