WORKAROUND for nvidia VBO failures

When switching virtual terminals,
suspending to ram and resizing the
screen (GL viewport) at least the
nvidia driver moves VBO data between
the video RAM and the system heap -
and something about this isn't reliable:

An often perceived resulted are scattered
windows but it may also be the cause for
entirely black screens reported for same
occasions.

As a workaround, we hook into the GL debug
messages and filter them for the suspicious
message, then re-init VBOs

TODO:
figure whether that's our fault or nvidias

REVIEW: 123936
CCBUG: 344326

Patch applies to KWin 5.4
This commit is contained in:
Thomas Lübking 2015-05-26 22:52:16 +02:00
parent 35abacabc4
commit 9f13e9b260

View file

@ -436,9 +436,11 @@ SceneOpenGL::SceneOpenGL(OpenGLBackend *backend, QObject *parent)
}
}
static SceneOpenGL *gs_debuggedScene = nullptr;
SceneOpenGL::~SceneOpenGL()
{
// do cleanup after initBuffer()
gs_debuggedScene = nullptr;
SceneOpenGL::EffectFrame::cleanup();
if (init_ok) {
delete m_syncManager;
@ -448,12 +450,32 @@ SceneOpenGL::~SceneOpenGL()
}
}
static void scheduleVboReInit()
{
if (!gs_debuggedScene)
return;
static QPointer<QTimer> timer;
if (!timer) {
delete timer;
timer = new QTimer(gs_debuggedScene);
timer->setSingleShot(true);
QObject::connect(timer, &QTimer::timeout, gs_debuggedScene, []() {
GLVertexBuffer::cleanup();
GLVertexBuffer::initStatic();
});
}
timer->start(250);
}
void SceneOpenGL::initDebugOutput()
{
const bool have_KHR_debug = hasGLExtension(QByteArrayLiteral("GL_KHR_debug"));
if (!have_KHR_debug && !hasGLExtension(QByteArrayLiteral("GL_ARB_debug_output")))
return;
gs_debuggedScene = this;
// Set the callback function
auto callback = [](GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei length,
@ -469,10 +491,17 @@ void SceneOpenGL::initDebugOutput()
qCWarning(KWIN_CORE, "%#x: %.*s", id, length, message);
break;
case GL_DEBUG_TYPE_OTHER:
// at least the nvidia driver seems prone to end up with invalid VBOs after
// transferring them between system heap and VRAM
// so we re-init them whenever this happens (typically when switching VT, resuming
// from STR and XRandR events - #344326
if (strstr(message, "Buffer detailed info:") && strstr(message, "has been updated"))
scheduleVboReInit();
// fall through! for general message printing
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
case GL_DEBUG_TYPE_PORTABILITY:
case GL_DEBUG_TYPE_PERFORMANCE:
case GL_DEBUG_TYPE_OTHER:
default:
qCDebug(KWIN_CORE, "%#x: %.*s", id, length, message);
break;