diff --git a/libkwineffects/kwinglplatform.cpp b/libkwineffects/kwinglplatform.cpp index 823bade955..35d7ff53ee 100644 --- a/libkwineffects/kwinglplatform.cpp +++ b/libkwineffects/kwinglplatform.cpp @@ -502,6 +502,7 @@ QString GLPlatform::chipClassToString(ChipClass chipClass) GLPlatform::GLPlatform() : m_driver(Driver_Unknown), m_chipClass(UnknownChipClass), + m_recommendedCompositor(XRenderCompositing), m_mesaVersion(0), m_galliumVersion(0), m_looseBinding(false), @@ -753,6 +754,16 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) m_limitedGLSL = m_supportsGLSL; } + if (m_chipClass < R300) { + // fallback to XRender for R100 and R200 + m_recommendedCompositor = XRenderCompositing; + } else if (m_chipClass < R600) { + // OpenGL 1 due to NPOT limitations not supported by KWin's shaders + m_recommendedCompositor = OpenGL1Compositing; + } else { + m_recommendedCompositor = OpenGL2Compositing; + } + if (driver() == Driver_R600G || (driver() == Driver_R600C && m_renderer.contains("DRI2"))) { m_looseBinding = true; @@ -766,6 +777,14 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) if (m_driver == Driver_NVidia) m_looseBinding = true; + if (m_chipClass < NV20) { + m_recommendedCompositor = XRenderCompositing; + } else if (m_chipClass < NV40) { + m_recommendedCompositor = OpenGL1Compositing; + } else { + m_recommendedCompositor = OpenGL2Compositing; + } + m_limitedNPOT = m_textureNPOT && m_chipClass < NV40; m_limitedGLSL = m_supportsGLSL && m_chipClass < G80; } @@ -775,6 +794,12 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) m_supportsGLSL = false; m_limitedGLSL = m_supportsGLSL && m_chipClass < I965; + + if (m_chipClass < I965) { + m_recommendedCompositor = OpenGL1Compositing; + } else { + m_recommendedCompositor = OpenGL2Compositing; + } } if (isMesaDriver() && platformInterface == EglPlatformInterface) { @@ -789,8 +814,22 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) m_looseBinding = false; if (isSoftwareEmulation()) { - // Software emulation does not provide GLSL - m_limitedGLSL = m_supportsGLSL = false; + // we recommend XRender + m_recommendedCompositor = XRenderCompositing; + if (m_driver < Driver_Llvmpipe) { + // Software emulation does not provide GLSL + m_limitedGLSL = m_supportsGLSL = false; + } else { + // llvmpipe does support GLSL + m_limitedGLSL = false; + m_supportsGLSL = true; + } + } + + if (m_chipClass == UnknownChipClass && m_driver == Driver_Unknown) { + // we don't know the hardware. Let's be optimistic and assume OpenGL compatible hardware + m_recommendedCompositor = OpenGL2Compositing; + m_supportsGLSL = true; } if (isVirtualBox()) { @@ -990,5 +1029,10 @@ bool GLPlatform::isVirtualMachine() const return m_virtualMachine; } +CompositingType GLPlatform::recommendedCompositor() const +{ + return m_recommendedCompositor; +} + } // namespace KWin diff --git a/libkwineffects/kwinglplatform.h b/libkwineffects/kwinglplatform.h index 79bf46d19f..249ecdb55e 100644 --- a/libkwineffects/kwinglplatform.h +++ b/libkwineffects/kwinglplatform.h @@ -296,6 +296,12 @@ public: **/ bool isLooseBinding() const; + /** + * @returns The CompositingType recommended by the driver. + * @since 4.10 + **/ + CompositingType recommendedCompositor() const; + /** * @returns a human readable form of the @p version. * @since 4.9 @@ -333,6 +339,7 @@ private: QSet m_extensions; Driver m_driver; ChipClass m_chipClass; + CompositingType m_recommendedCompositor; qint64 m_glVersion; qint64 m_glslVersion; qint64 m_mesaVersion; diff --git a/scene_opengl.cpp b/scene_opengl.cpp index de7abd8160..f2cf03fe13 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -80,6 +80,7 @@ Sources and other compositing managers: #include "utils.h" #include "client.h" +#include "composite.h" #include "deleted.h" #include "effects.h" #include "overlaywindow.h" @@ -150,11 +151,6 @@ SceneOpenGL::SceneOpenGL(Workspace* ws, OpenGLBackend *backend) // perform Scene specific checks GLPlatform *glPlatform = GLPlatform::instance(); - if (glPlatform->isSoftwareEmulation()) { - kError(1212) << "OpenGL Software Rasterizer detected. Falling back to XRender."; - QTimer::singleShot(0, Workspace::self(), SLOT(fallbackToXRenderCompositing())); - return; - } #ifndef KWIN_HAVE_OPENGLES if (!hasGLExtension("GL_ARB_texture_non_power_of_two") && !hasGLExtension("GL_ARB_texture_rectangle")) { @@ -256,6 +252,12 @@ SceneOpenGL *SceneOpenGL::createScene() } #endif if (!scene) { + if (GLPlatform::instance()->recommendedCompositor() == XRenderCompositing) { + kError(1212) << "OpenGL driver recommends XRender based compositing. Falling back to XRender."; + kError(1212) << "To overwrite the detection use the environment variable KWIN_COMPOSE"; + kError(1212) << "For more information see http://community.kde.org/KWin/Environment_Variables#KWIN_COMPOSE"; + QTimer::singleShot(0, Compositor::self(), SLOT(fallbackToXRenderCompositing())); + } delete backend; } @@ -439,14 +441,23 @@ void SceneOpenGL::screenGeometryChanged(const QSize &size) //**************************************** bool SceneOpenGL2::supported(OpenGLBackend *backend) { + const QByteArray forceEnv = qgetenv("KWIN_COMPOSE"); + if (!forceEnv.isEmpty()) { + if (qstrcmp(forceEnv, "O2") == 0) { + kDebug(1212) << "OpenGL 2 compositing enforced by environment variable"; + return true; + } else { + // OpenGL 2 disabled by environment variable + return false; + } + } if (!backend->isDirectRendering()) { return false; } -#ifdef KWIN_HAVE_OPENGL_1 - if (!GLPlatform::instance()->supports(GLSL) || GLPlatform::instance()->supports(LimitedNPOT)) { + if (GLPlatform::instance()->recommendedCompositor() < OpenGL2Compositing) { + kDebug(1212) << "Driver does not recommend OpenGL 2 compositing"; return false; } -#endif if (options->isGlLegacy()) { kDebug(1212) << "OpenGL 2 disabled by config option"; return false; @@ -510,8 +521,21 @@ SceneOpenGL::Window *SceneOpenGL2::createWindow(Toplevel *t) #ifdef KWIN_HAVE_OPENGL_1 bool SceneOpenGL1::supported(OpenGLBackend *backend) { - // any OpenGL context will do - return !backend->isFailed(); + const QByteArray forceEnv = qgetenv("KWIN_COMPOSE"); + if (!forceEnv.isEmpty()) { + if (qstrcmp(forceEnv, "O1") == 0) { + kDebug(1212) << "OpenGL 1 compositing enforced by environment variable"; + return true; + } else { + // OpenGL 1 disabled by environment variable + return false; + } + } + if (GLPlatform::instance()->recommendedCompositor() < OpenGL1Compositing) { + kDebug(1212) << "Driver does not recommend OpenGL 1 compositing"; + return false; + } + return true; } SceneOpenGL1::SceneOpenGL1(OpenGLBackend *backend)