diff --git a/autotests/libkwineffects/CMakeLists.txt b/autotests/libkwineffects/CMakeLists.txt index 8973545cc2..0c87dfb5c1 100644 --- a/autotests/libkwineffects/CMakeLists.txt +++ b/autotests/libkwineffects/CMakeLists.txt @@ -12,3 +12,8 @@ endmacro() kwineffects_unit_tests( windowquadlisttest ) + +add_executable(kwinglplatformtest kwinglplatformtest.cpp mock_gl.cpp ../../libkwineffects/kwinglplatform.cpp) +add_test(kwineffects-kwinglplatformtest kwinglplatformtest) +target_link_libraries(kwinglplatformtest Qt5::Test Qt5::Gui Qt5::X11Extras KF5::ConfigCore) +ecm_mark_as_test(kwinglplatformtest) diff --git a/autotests/libkwineffects/data/glplatform/intel-ivybridge-desktop-3.3 b/autotests/libkwineffects/data/glplatform/intel-ivybridge-desktop-3.3 new file mode 100644 index 0000000000..47039a4365 --- /dev/null +++ b/autotests/libkwineffects/data/glplatform/intel-ivybridge-desktop-3.3 @@ -0,0 +1,19 @@ +[Driver] +Vendor=Intel Open Source Technology Center +Renderer=Mesa DRI Intel(R) Ivybridge Desktop +Version=3.3 (Core Profile) Mesa 11.2.2 +ShadingLanguageVersion=3.30 + +[Settings] +LooseBinding=true +GLSL=true +TextureNPOT=true +Mesa=true +Intel=true +GLVersion=3,3 +GLSLVersion=3,30 +MesaVersion=11,2,2 +DriverVersion=11,2,2 +Driver=7 +ChipClass=2004 +Compositor=9 diff --git a/autotests/libkwineffects/kwinglplatformtest.cpp b/autotests/libkwineffects/kwinglplatformtest.cpp new file mode 100644 index 0000000000..1cd0f03007 --- /dev/null +++ b/autotests/libkwineffects/kwinglplatformtest.cpp @@ -0,0 +1,192 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2016 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "mock_gl.h" +#include +#include + +#include +#include + +using namespace KWin; + +void KWin::cleanupGL() +{ + GLPlatform::cleanup(); +} + +class GLPlatformTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void cleanup(); + + void testPriorDetect(); + void testDetect_data(); + void testDetect(); +}; + +void GLPlatformTest::cleanup() +{ + cleanupGL(); + delete s_gl; + s_gl = nullptr; +} + +void GLPlatformTest::testPriorDetect() +{ + auto *gl = GLPlatform::instance(); + QVERIFY(gl); + QCOMPARE(gl->supports(LooseBinding), false); + QCOMPARE(gl->supports(GLSL), false); + QCOMPARE(gl->supports(LimitedGLSL), false); + QCOMPARE(gl->supports(TextureNPOT), false); + QCOMPARE(gl->supports(LimitedNPOT), false); + + QCOMPARE(gl->glVersion(), 0); + QCOMPARE(gl->glslVersion(), 0); + QCOMPARE(gl->mesaVersion(), 0); + QCOMPARE(gl->galliumVersion(), 0); + QCOMPARE(gl->serverVersion(), 0); + QCOMPARE(gl->kernelVersion(), 0); + QCOMPARE(gl->driverVersion(), 0); + + QCOMPARE(gl->driver(), Driver_Unknown); + QCOMPARE(gl->chipClass(), UnknownChipClass); + + QCOMPARE(gl->isMesaDriver(), false); + QCOMPARE(gl->isGalliumDriver(), false); + QCOMPARE(gl->isRadeon(), false); + QCOMPARE(gl->isNvidia(), false); + QCOMPARE(gl->isIntel(), false); + QCOMPARE(gl->isVirtualBox(), false); + QCOMPARE(gl->isVMware(), false); + + QCOMPARE(gl->isSoftwareEmulation(), false); + QCOMPARE(gl->isVirtualMachine(), false); + + QCOMPARE(gl->glVersionString(), QByteArray()); + QCOMPARE(gl->glRendererString(), QByteArray()); + QCOMPARE(gl->glVendorString(), QByteArray()); + QCOMPARE(gl->glShadingLanguageVersionString(), QByteArray()); + + QCOMPARE(gl->isLooseBinding(), false); + QCOMPARE(gl->isGLES(), false); + QCOMPARE(gl->recommendedCompositor(), XRenderCompositing); + QCOMPARE(gl->preferBufferSubData(), false); + QCOMPARE(gl->platformInterface(), NoOpenGLPlatformInterface); +} + +void GLPlatformTest::testDetect_data() +{ + QTest::addColumn("configFile"); + + QDir dir(QFINDTESTDATA("data/glplatform")); + const QStringList entries = dir.entryList(QDir::NoDotAndDotDot | QDir::Files); + + for (const QString &file : entries) { + QTest::newRow(file.toUtf8().constData()) << dir.absoluteFilePath(file); + } +} + +static qint64 readVersion(const KConfigGroup &group, const char *entry) +{ + const QStringList parts = group.readEntry(entry, QString()).split(','); + if (parts.count() < 2) { + return 0; + } + QVector versionParts; + for (int i = 0; i < parts.count(); ++i) { + bool ok = false; + const auto value = parts.at(i).toLongLong(&ok); + if (ok) { + versionParts << value; + } else { + versionParts << 0; + } + } + while (versionParts.count() < 3) { + versionParts << 0; + } + return kVersionNumber(versionParts.at(0), versionParts.at(1), versionParts.at(2)); +} + +void GLPlatformTest::testDetect() +{ + QFETCH(QString, configFile); + KConfig config(configFile); + const KConfigGroup driverGroup = config.group("Driver"); + s_gl = new MockGL; + s_gl->getString.vendor = driverGroup.readEntry("Vendor").toUtf8(); + s_gl->getString.renderer = driverGroup.readEntry("Renderer").toUtf8(); + s_gl->getString.version = driverGroup.readEntry("Version").toUtf8(); + s_gl->getString.shadingLanguageVersion = driverGroup.readEntry("ShadingLanguageVersion").toUtf8(); + s_gl->getString.extensions = QVector{QByteArrayLiteral("GL_ARB_shader_objects"), + QByteArrayLiteral("GL_ARB_fragment_shader"), + QByteArrayLiteral("GL_ARB_vertex_shader"), + QByteArrayLiteral("GL_ARB_texture_non_power_of_two")}; + s_gl->getString.extensionsString = QByteArray(); + + auto *gl = GLPlatform::instance(); + QVERIFY(gl); + gl->detect(EglPlatformInterface); + QCOMPARE(gl->platformInterface(), EglPlatformInterface); + + const KConfigGroup settingsGroup = config.group("Settings"); + + QCOMPARE(gl->supports(LooseBinding), settingsGroup.readEntry("LooseBinding", false)); + QCOMPARE(gl->supports(GLSL), settingsGroup.readEntry("GLSL", false)); + QCOMPARE(gl->supports(LimitedGLSL), settingsGroup.readEntry("LimitedGLSL", false)); + QCOMPARE(gl->supports(TextureNPOT), settingsGroup.readEntry("TextureNPOT", false)); + QCOMPARE(gl->supports(LimitedNPOT), settingsGroup.readEntry("LimitedNPOT", false)); + + QCOMPARE(gl->glVersion(), readVersion(settingsGroup, "GLVersion")); + QCOMPARE(gl->glslVersion(), readVersion(settingsGroup, "GLSLVersion")); + QCOMPARE(gl->mesaVersion(), readVersion(settingsGroup, "MesaVersion")); + QCOMPARE(gl->galliumVersion(), readVersion(settingsGroup, "GalliumVersion")); + QCOMPARE(gl->serverVersion(), 0); + QCOMPARE(gl->driverVersion(), readVersion(settingsGroup, "DriverVersion")); + + QCOMPARE(gl->driver(), Driver(settingsGroup.readEntry("Driver", int(Driver_Unknown)))); + QCOMPARE(gl->chipClass(), ChipClass(settingsGroup.readEntry("ChipClass", int(UnknownChipClass)))); + + QCOMPARE(gl->isMesaDriver(), settingsGroup.readEntry("Mesa", false)); + QCOMPARE(gl->isGalliumDriver(), settingsGroup.readEntry("Gallium", false)); + QCOMPARE(gl->isRadeon(), settingsGroup.readEntry("Radeon", false)); + QCOMPARE(gl->isNvidia(), settingsGroup.readEntry("Nvidia", false)); + QCOMPARE(gl->isIntel(), settingsGroup.readEntry("Intel", false)); + QCOMPARE(gl->isVirtualBox(), settingsGroup.readEntry("VirtualBox", false)); + QCOMPARE(gl->isVMware(), settingsGroup.readEntry("VMware", false)); + + QCOMPARE(gl->isSoftwareEmulation(), settingsGroup.readEntry("SoftwareEmulation", false)); + QCOMPARE(gl->isVirtualMachine(), settingsGroup.readEntry("VirtualMachine", false)); + + QCOMPARE(gl->glVersionString(), s_gl->getString.version); + QCOMPARE(gl->glRendererString(), s_gl->getString.renderer); + QCOMPARE(gl->glVendorString(), s_gl->getString.vendor); + QCOMPARE(gl->glShadingLanguageVersionString(), s_gl->getString.shadingLanguageVersion); + + QCOMPARE(gl->isLooseBinding(), settingsGroup.readEntry("LooseBinding", false)); + QCOMPARE(gl->isGLES(), settingsGroup.readEntry("GLES", false)); + QCOMPARE(gl->recommendedCompositor(), CompositingType(settingsGroup.readEntry("Compositor", int(NoCompositing)))); + QCOMPARE(gl->preferBufferSubData(), settingsGroup.readEntry("PreferBufferSubData", false)); +} + +QTEST_GUILESS_MAIN(GLPlatformTest) +#include "kwinglplatformtest.moc" diff --git a/autotests/libkwineffects/mock_gl.cpp b/autotests/libkwineffects/mock_gl.cpp new file mode 100644 index 0000000000..51fffbe8ab --- /dev/null +++ b/autotests/libkwineffects/mock_gl.cpp @@ -0,0 +1,70 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2016 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "mock_gl.h" +#include + +MockGL *s_gl = nullptr; + +static const GLubyte *mock_glGetString(GLenum name) +{ + if (!s_gl) { + return nullptr; + } + switch (name) { + case GL_VENDOR: + return (const GLubyte*)s_gl->getString.vendor.constData(); + case GL_RENDERER: + return (const GLubyte*)s_gl->getString.renderer.constData(); + case GL_VERSION: + return (const GLubyte*)s_gl->getString.version.constData(); + case GL_EXTENSIONS: + return (const GLubyte*)s_gl->getString.extensionsString.constData(); + case GL_SHADING_LANGUAGE_VERSION: + return (const GLubyte*)s_gl->getString.shadingLanguageVersion.constData(); + default: + return nullptr; + } +} + +static const GLubyte *mock_glGetStringi(GLenum name, GLuint index) +{ + if (!s_gl) { + return nullptr; + } + if (name == GL_EXTENSIONS && index < uint(s_gl->getString.extensions.count())) { + return (const GLubyte*)s_gl->getString.extensions.at(index).constData(); + } + return nullptr; +} + +static void mock_glGetIntegerv(GLenum pname, GLint *data) +{ + Q_UNUSED(pname) + Q_UNUSED(data) + if (pname == GL_NUM_EXTENSIONS) { + if (data && s_gl) { + *data = s_gl->getString.extensions.count(); + } + } +} + +PFNGLGETSTRINGPROC epoxy_glGetString = mock_glGetString; +PFNGLGETSTRINGIPROC epoxy_glGetStringi = mock_glGetStringi; +PFNGLGETINTEGERVPROC epoxy_glGetIntegerv = mock_glGetIntegerv; diff --git a/autotests/libkwineffects/mock_gl.h b/autotests/libkwineffects/mock_gl.h new file mode 100644 index 0000000000..cd53320ab7 --- /dev/null +++ b/autotests/libkwineffects/mock_gl.h @@ -0,0 +1,39 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2016 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef MOCK_GL_H +#define MOCK_GL_H + +#include +#include + +struct MockGL { + struct { + QByteArray vendor; + QByteArray renderer; + QByteArray version; + QVector extensions; + QByteArray extensionsString; + QByteArray shadingLanguageVersion; + } getString; +}; + +extern MockGL *s_gl; + +#endif