From fc54bdfe8995a1298c0350f3b003b1ebc071a14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sun, 6 Feb 2011 09:27:30 +0100 Subject: [PATCH] Unbind shader before copying pixels to back buffer. This solves the regression with NVIDIA drivers resulting in a black screen. Apparently NVIDIA does not support glXCopySubBuffer and the copying of pixels fails with a shader bound. So unbinding the shader before copying the pixels and rebinding the shader afterwards resolves the issue. This allows to remove the temporary hack to make NVIDIA work, again. --- lib/kwinglutils.cpp | 5 ----- scene_opengl_glx.cpp | 11 +++++++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/kwinglutils.cpp b/lib/kwinglutils.cpp index 49b94167a6..a01d1788a6 100644 --- a/lib/kwinglutils.cpp +++ b/lib/kwinglutils.cpp @@ -1183,11 +1183,6 @@ GLShader *ShaderManager::loadShaderFromCode(const QByteArray &vertexSource, cons void ShaderManager::initShaders() { - // HACK: the generic shaders fail with NVIDIA's blob - // temporarily disable them to force kwin on GL 1.x profile - if (GLPlatform::instance()->driver() == Driver_NVidia) { - return; - } m_orthoShader = new GLShader(":/resources/scene-vertex.glsl", ":/resources/scene-fragment.glsl"); if (m_orthoShader->isValid()) { pushShader(SimpleShader, true); diff --git a/scene_opengl_glx.cpp b/scene_opengl_glx.cpp index 4e89664f56..edff792ab8 100644 --- a/scene_opengl_glx.cpp +++ b/scene_opengl_glx.cpp @@ -587,6 +587,13 @@ void SceneOpenGL::flushBuffer(int mask, QRegion damage) glXCopySubBuffer(display(), glxbuffer, r.x(), y, r.width(), r.height()); } } else { + // if a shader is bound, copy pixels results in a black screen + // therefore unbind the shader and restore after copying the pixels + GLint shader = 0; + if (ShaderManager::instance()->isShaderBound()) { + glGetIntegerv(GL_CURRENT_PROGRAM, &shader); + glUseProgram(0); + } // no idea why glScissor() is used, but Compiz has it and it doesn't seem to hurt glEnable(GL_SCISSOR_TEST); glDrawBuffer(GL_FRONT); @@ -608,6 +615,10 @@ void SceneOpenGL::flushBuffer(int mask, QRegion damage) glBitmap(0, 0, 0, 0, -xpos, -ypos, NULL); // move position back to 0,0 glDrawBuffer(GL_BACK); glDisable(GL_SCISSOR_TEST); + // rebind previously bound shader + if (ShaderManager::instance()->isShaderBound()) { + glUseProgram(shader); + } } } else { waitSync();