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:
parent
35abacabc4
commit
9f13e9b260
1 changed files with 30 additions and 1 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue