opengl/glplatform: remove dependency on OpenGlContext

This commit is contained in:
Xaver Hugl 2024-02-28 17:17:16 +01:00
parent 605401dcfc
commit 7618be3697
23 changed files with 169 additions and 393 deletions

View file

@ -14,10 +14,7 @@ kwineffects_unit_tests(
timelinetest
)
if (KWIN_BUILD_X11 AND ARGS_LIBS MATCHES .*XCB.*)
add_executable(kwinglplatformtest kwinglplatformtest.cpp mock_gl.cpp ../../src/opengl/glplatform.cpp ../../src/opengl/openglcontext.cpp ../../src/utils/version.cpp)
add_test(NAME kwineffects-kwinglplatformtest COMMAND kwinglplatformtest)
target_link_libraries(kwinglplatformtest Qt::Test Qt::Gui KF6::ConfigCore XCB::XCB)
ecm_mark_as_test(kwinglplatformtest)
endif()
add_executable(kwinglplatformtest kwinglplatformtest.cpp ../../src/opengl/glplatform.cpp ../../src/utils/version.cpp)
add_test(NAME kwineffects-kwinglplatformtest COMMAND kwinglplatformtest)
target_link_libraries(kwinglplatformtest Qt::Test Qt::Gui KF6::ConfigCore)
ecm_mark_as_test(kwinglplatformtest)

View file

@ -6,7 +6,6 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "mock_gl.h"
#include "opengl/glplatform.h"
#include <QTest>
@ -22,24 +21,14 @@ class GLPlatformTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void cleanup();
void testDriverToString_data();
void testDriverToString();
void testChipClassToString_data();
void testChipClassToString();
void testPriorDetect();
void testDetect_data();
void testDetect();
};
void GLPlatformTest::cleanup()
{
GLPlatform::cleanup();
delete s_gl;
s_gl = nullptr;
}
void GLPlatformTest::testDriverToString_data()
{
QTest::addColumn<Driver>("driver");
@ -137,47 +126,6 @@ void GLPlatformTest::testChipClassToString()
QTEST(GLPlatform::chipClassToString(chipClass), "expected");
}
void GLPlatformTest::testPriorDetect()
{
auto *gl = GLPlatform::instance();
QVERIFY(gl);
QCOMPARE(gl->isLooseBinding(), false);
QCOMPARE(gl->glVersion(), Version());
QCOMPARE(gl->glslVersion(), Version());
QCOMPARE(gl->mesaVersion(), Version());
QCOMPARE(gl->driverVersion(), Version());
QCOMPARE(gl->driver(), Driver_Unknown);
QCOMPARE(gl->chipClass(), UnknownChipClass);
QCOMPARE(gl->isMesaDriver(), false);
QCOMPARE(gl->isRadeon(), false);
QCOMPARE(gl->isNvidia(), false);
QCOMPARE(gl->isIntel(), false);
QCOMPARE(gl->isPanfrost(), false);
QCOMPARE(gl->isLima(), false);
QCOMPARE(gl->isVideoCore4(), false);
QCOMPARE(gl->isVideoCore3D(), 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(), QPainterCompositing);
QCOMPARE(gl->preferBufferSubData(), false);
QCOMPARE(gl->platformInterface(), NoOpenGLPlatformInterface);
}
void GLPlatformTest::testDetect_data()
{
QTest::addColumn<QString>("configFile");
@ -217,60 +165,50 @@ void GLPlatformTest::testDetect()
QFETCH(QString, configFile);
KConfig config(configFile);
const KConfigGroup driverGroup = config.group(QStringLiteral("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 = QList<QByteArray>{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 auto version = driverGroup.readEntry("Version").toUtf8();
const auto glslVersion = driverGroup.readEntry("ShadingLanguageVersion").toUtf8();
const auto renderer = driverGroup.readEntry("Renderer").toUtf8();
const auto vendor = driverGroup.readEntry("Vendor").toUtf8();
GLPlatform gl(EglPlatformInterface, version, glslVersion, renderer, vendor);
QCOMPARE(gl.platformInterface(), EglPlatformInterface);
const KConfigGroup settingsGroup = config.group(QStringLiteral("Settings"));
QCOMPARE(gl->isLooseBinding(), settingsGroup.readEntry("LooseBinding", false));
QCOMPARE(gl.isLooseBinding(), settingsGroup.readEntry("LooseBinding", false));
QCOMPARE(gl->glVersion(), readVersion(settingsGroup, "GLVersion"));
QCOMPARE(gl->glslVersion(), readVersion(settingsGroup, "GLSLVersion"));
QCOMPARE(gl->mesaVersion(), readVersion(settingsGroup, "MesaVersion"));
QCOMPARE(gl.glVersion(), readVersion(settingsGroup, "GLVersion"));
QCOMPARE(gl.glslVersion(), readVersion(settingsGroup, "GLSLVersion"));
QCOMPARE(gl.mesaVersion(), readVersion(settingsGroup, "MesaVersion"));
QEXPECT_FAIL("amd-catalyst-radeonhd-7700M-3.1.13399", "Detects GL version instead of driver version", Continue);
QCOMPARE(gl->driverVersion(), readVersion(settingsGroup, "DriverVersion"));
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.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->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->isAdreno(), settingsGroup.readEntry("Adreno", false));
QCOMPARE(gl->isPanfrost(), settingsGroup.readEntry("Panfrost", false));
QCOMPARE(gl->isLima(), settingsGroup.readEntry("Lima", false));
QCOMPARE(gl->isVideoCore4(), settingsGroup.readEntry("VC4", false));
QCOMPARE(gl->isVideoCore3D(), settingsGroup.readEntry("V3D", false));
QCOMPARE(gl->isVirgl(), settingsGroup.readEntry("Virgl", false));
QCOMPARE(gl.isMesaDriver(), settingsGroup.readEntry("Mesa", 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.isAdreno(), settingsGroup.readEntry("Adreno", false));
QCOMPARE(gl.isPanfrost(), settingsGroup.readEntry("Panfrost", false));
QCOMPARE(gl.isLima(), settingsGroup.readEntry("Lima", false));
QCOMPARE(gl.isVideoCore4(), settingsGroup.readEntry("VC4", false));
QCOMPARE(gl.isVideoCore3D(), settingsGroup.readEntry("V3D", false));
QCOMPARE(gl.isVirgl(), settingsGroup.readEntry("Virgl", false));
QCOMPARE(gl->isSoftwareEmulation(), settingsGroup.readEntry("SoftwareEmulation", false));
QCOMPARE(gl->isVirtualMachine(), settingsGroup.readEntry("VirtualMachine", 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.glVersionString(), version);
QCOMPARE(gl.glRendererString(), renderer);
QCOMPARE(gl.glVendorString(), vendor);
QCOMPARE(gl.glShadingLanguageVersionString(), glslVersion);
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));
QCOMPARE(gl.isLooseBinding(), settingsGroup.readEntry("LooseBinding", false));
QCOMPARE(gl.recommendedCompositor(), CompositingType(settingsGroup.readEntry("Compositor", int(NoCompositing))));
QCOMPARE(gl.preferBufferSubData(), settingsGroup.readEntry("PreferBufferSubData", false));
}
QTEST_GUILESS_MAIN(GLPlatformTest)

View file

@ -1,57 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "mock_gl.h"
#include <epoxy/gl.h>
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)
{
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;

View file

@ -1,30 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef MOCK_GL_H
#define MOCK_GL_H
#include <QByteArray>
#include <QList>
struct MockGL
{
struct
{
QByteArray vendor;
QByteArray renderer;
QByteArray version;
QList<QByteArray> extensions;
QByteArray extensionsString;
QByteArray shadingLanguageVersion;
} getString;
};
extern MockGL *s_gl;
#endif

View file

@ -18,7 +18,8 @@ namespace KWin
{
GlxContext::GlxContext(::Display *display, GLXWindow window, GLXContext handle)
: m_display(display)
: OpenGlContext(false)
, m_display(display)
, m_window(window)
, m_handle(handle)
, m_shaderManager(std::make_unique<ShaderManager>())

View file

@ -177,9 +177,9 @@ void EglBackend::init()
// buffer copying is very fast with the nvidia blob
// but due to restrictions in DRI2 *incredibly* slow for all MESA drivers
// see https://www.x.org/releases/X11R7.7/doc/dri2proto/dri2proto.txt, item 2.5
if (GLPlatform::instance()->driver() == Driver_NVidia) {
if (m_context->glPlatform()->driver() == Driver_NVidia) {
m_swapStrategy = Options::CopyFrontBuffer;
} else if (GLPlatform::instance()->driver() != Driver_Unknown) { // undetected, finally resolved when context is initialized
} else if (m_context->glPlatform()->driver() != Driver_Unknown) { // undetected, finally resolved when context is initialized
m_swapStrategy = Options::ExtendDamage;
}
}

View file

@ -154,15 +154,7 @@ GlxBackend::~GlxBackend()
m_overlayWindow->destroy();
}
if (m_context) {
// TODO: cleanup in error case
// do cleanup after initBuffer()
GLPlatform::cleanup();
doneCurrent();
m_context.reset();
}
m_context.reset();
if (glxWindow) {
glXDestroyWindow(display(), glxWindow);
}
@ -221,23 +213,19 @@ void GlxBackend::init()
return;
}
// Initialize OpenGL
GLPlatform *glPlatform = GLPlatform::instance();
glPlatform->detect(GlxPlatformInterface);
const auto glPlatform = m_context->glPlatform();
m_swapStrategy = options->glPreferBufferSwap();
if (m_swapStrategy == Options::AutoSwapStrategy) {
// buffer copying is very fast with the nvidia blob
// but due to restrictions in DRI2 *incredibly* slow for all MESA drivers
// see https://www.x.org/releases/X11R7.7/doc/dri2proto/dri2proto.txt, item 2.5
if (GLPlatform::instance()->driver() == Driver_NVidia) {
if (glPlatform->driver() == Driver_NVidia) {
m_swapStrategy = Options::CopyFrontBuffer;
} else if (GLPlatform::instance()->driver() != Driver_Unknown) { // undetected, finally resolved when context is initialized
} else if (glPlatform->driver() != Driver_Unknown) { // undetected, finally resolved when context is initialized
m_swapStrategy = Options::ExtendDamage;
}
}
glPlatform->printResults();
initGL(&getProcAddress);
m_fbo = std::make_unique<GLFramebuffer>(0, workspace()->geometry().size());

View file

@ -73,7 +73,7 @@ bool WaylandCompositor::attemptOpenGLCompositing()
return false;
}
} else {
if (GLPlatform::instance()->recommendedCompositor() < OpenGLCompositing) {
if (backend->openglContext()->glPlatform()->recommendedCompositor() < OpenGLCompositing) {
qCDebug(KWIN_CORE) << "Driver does not recommend OpenGL compositing";
return false;
}
@ -276,7 +276,7 @@ void WaylandCompositor::addOutput(Output *output)
// possibly a kernel driver bug. Remove the workaround when https://gitlab.freedesktop.org/drm/intel/-/issues/9571 is fixed.
static bool forceSoftwareCursorIsSet;
static const bool forceSoftwareCursor = qEnvironmentVariableIntValue("KWIN_FORCE_SW_CURSOR", &forceSoftwareCursorIsSet) == 1
|| (!forceSoftwareCursorIsSet && GLPlatform::instance() && GLPlatform::instance()->isIntel());
|| (!forceSoftwareCursorIsSet && scene()->openglContext() && scene()->openglContext()->glPlatform()->isIntel());
auto updateCursorLayer = [this, output, cursorLayer]() {
const Cursor *cursor = Cursors::self()->currentCursor();

View file

@ -213,7 +213,7 @@ bool X11Compositor::attemptOpenGLCompositing()
return false;
}
} else {
if (GLPlatform::instance()->recommendedCompositor() < OpenGLCompositing) {
if (backend->openglContext()->glPlatform()->recommendedCompositor() < OpenGLCompositing) {
qCDebug(KWIN_CORE) << "Driver does not recommend OpenGL compositing";
return false;
}
@ -225,14 +225,14 @@ bool X11Compositor::attemptOpenGLCompositing()
return false;
}
m_scene = std::make_unique<WorkspaceSceneOpenGL>(backend.get());
m_backend = std::move(backend);
// set strict binding
if (options->isGlStrictBindingFollowsDriver()) {
options->setGlStrictBinding(!GLPlatform::instance()->isLooseBinding());
options->setGlStrictBinding(!backend->openglContext()->glPlatform()->isLooseBinding());
}
m_scene = std::make_unique<WorkspaceSceneOpenGL>(backend.get());
m_backend = std::move(backend);
qCDebug(KWIN_CORE) << "OpenGL compositing has been successfully initialized";
return true;
}

View file

@ -18,6 +18,7 @@
#include "opengl/glplatform.h"
#include "opengl/glutils.h"
#include "platformsupport/scenes/opengl/openglbackend.h"
#include "scene/workspacescene.h"
#include "utils/filedescriptor.h"
#include "utils/subsurfacemonitor.h"
#include "wayland/abstract_data_source.h"
@ -660,7 +661,7 @@ void DebugConsole::initGLTab()
m_ui->glInfoScrollArea->setVisible(false);
return;
}
GLPlatform *gl = GLPlatform::instance();
const auto gl = Compositor::self()->scene()->openglContext()->glPlatform();
m_ui->noOpenGLLabel->setVisible(false);
m_ui->glInfoScrollArea->setVisible(true);
m_ui->glVendorStringLabel->setText(QString::fromLocal8Bit(gl->glVendorString()));

View file

@ -42,7 +42,8 @@ std::unique_ptr<EglContext> EglContext::create(EglDisplay *display, EGLConfig co
}
EglContext::EglContext(EglDisplay *display, EGLConfig config, ::EGLContext context)
: m_display(display)
: OpenGlContext(true)
, m_display(display)
, m_handle(context)
, m_config(config)
, m_shaderManager(std::make_unique<ShaderManager>())

View file

@ -31,8 +31,6 @@
namespace KWin
{
std::unique_ptr<GLPlatform> GLPlatform::s_platform;
// Extracts the portion of a string that matches a regular expression
static QString extract(const QString &text, const QString &pattern)
{
@ -714,47 +712,36 @@ QByteArray GLPlatform::chipClassToString8(ChipClass chipClass)
// -------
GLPlatform::GLPlatform()
: m_driver(Driver_Unknown)
, m_chipClass(UnknownChipClass)
, m_recommendedCompositor(QPainterCompositing)
, m_looseBinding(false)
, m_virtualMachine(false)
, m_preferBufferSubData(false)
, m_platformInterface(NoOpenGLPlatformInterface)
static void print(const QByteArray &label, QByteArrayView setting)
{
qInfo("%-40s%s", label.data(), setting.data());
}
GLPlatform::~GLPlatform()
GLPlatform::GLPlatform(OpenGLPlatformInterface platformInterface, QByteArrayView openglVersionString, QByteArrayView glslVersionString, QByteArrayView renderer, QByteArrayView vendor)
: m_openglVersionString(openglVersionString)
, m_glslVersionString(glslVersionString)
, m_rendererString(renderer)
, m_vendorString(vendor)
, m_openglVersion(Version::parseString(openglVersionString))
, m_glslVersion(Version::parseString(m_glslVersionString))
, m_platformInterface(platformInterface)
{
}
void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
{
m_platformInterface = platformInterface;
m_context = std::make_unique<OpenGlContext>();
// Parse the Mesa version
const auto versionTokens = m_context->openglVersionString().toByteArray().split(' ');
const auto versionTokens = openglVersionString.toByteArray().split(' ');
const int mesaIndex = versionTokens.indexOf("Mesa");
if (mesaIndex != -1) {
m_mesaVersion = Version::parseString(versionTokens.at(mesaIndex + 1));
}
m_glsl_version = m_context->glslVersionString().toByteArray();
m_glslVersion = m_context->glslVersion();
m_chipset = QByteArrayLiteral("Unknown");
m_preferBufferSubData = false;
// Mesa classic drivers
// ====================================================
// Radeon
if (m_context->renderer().startsWith("Mesa DRI R")) {
if (renderer.startsWith("Mesa DRI R")) {
// Sample renderer string: Mesa DRI R600 (RV740 94B3) 20090101 x86/MMX/SSE2 TCL DRI2
const QList<QByteArray> tokens = m_context->renderer().toByteArray().split(' ');
const QList<QByteArray> tokens = renderer.toByteArray().split(' ');
const QByteArray &chipClass = tokens.at(2);
m_chipset = tokens.at(3).mid(1, -1); // Strip the leading '('
@ -779,15 +766,15 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
}
// Intel
else if (m_context->renderer().contains("Intel")) {
else if (renderer.contains("Intel")) {
// Vendor: Tungsten Graphics, Inc.
// Sample renderer string: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100328 2010Q1
QByteArrayView chipset;
if (m_context->renderer().startsWith("Intel(R) Integrated Graphics Device")) {
if (renderer.startsWith("Intel(R) Integrated Graphics Device")) {
chipset = "IGD";
} else {
chipset = m_context->renderer();
chipset = renderer;
}
m_driver = Driver_Intel;
@ -796,8 +783,8 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
// Properietary drivers
// ====================================================
else if (m_context->vendor() == "ATI Technologies Inc.") {
m_chipClass = detectRadeonClass(m_context->renderer());
else if (vendor == "ATI Technologies Inc.") {
m_chipClass = detectRadeonClass(renderer);
m_driver = Driver_Catalyst;
if (versionTokens.count() > 1 && versionTokens.at(2)[0] == '(') {
@ -809,8 +796,8 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
}
}
else if (m_context->vendor() == "NVIDIA Corporation") {
m_chipClass = detectNVidiaClass(m_context->renderer());
else if (vendor == "NVIDIA Corporation") {
m_chipClass = detectNVidiaClass(renderer);
m_driver = Driver_NVidia;
int index = versionTokens.indexOf("NVIDIA");
@ -821,38 +808,38 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
}
}
else if (m_context->vendor() == "Qualcomm") {
else if (vendor == "Qualcomm") {
m_driver = Driver_Qualcomm;
m_chipClass = detectQualcommClass(m_context->renderer());
m_chipClass = detectQualcommClass(renderer);
}
else if (m_context->renderer().contains("Panfrost")) {
else if (renderer.contains("Panfrost")) {
m_driver = Driver_Panfrost;
m_chipClass = detectPanfrostClass(m_context->renderer());
m_chipClass = detectPanfrostClass(renderer);
}
else if (m_context->renderer().contains("Mali")) {
else if (renderer.contains("Mali")) {
m_driver = Driver_Lima;
m_chipClass = detectLimaClass(m_context->renderer());
m_chipClass = detectLimaClass(renderer);
}
else if (m_context->renderer().startsWith("VC4 ")) {
else if (renderer.startsWith("VC4 ")) {
m_driver = Driver_VC4;
m_chipClass = detectVC4Class(m_context->renderer());
m_chipClass = detectVC4Class(renderer);
}
else if (m_context->renderer().startsWith("V3D ")) {
else if (renderer.startsWith("V3D ")) {
m_driver = Driver_V3D;
m_chipClass = detectV3DClass(m_context->renderer());
m_chipClass = detectV3DClass(renderer);
}
else if (m_context->renderer() == "Software Rasterizer") {
else if (renderer == "Software Rasterizer") {
m_driver = Driver_Swrast;
}
// Virtual Hardware
// ====================================================
else if (m_context->vendor() == "Humper" && m_context->renderer() == "Chromium") {
else if (vendor == "Humper" && renderer == "Chromium") {
// Virtual Box
m_driver = Driver_VirtualBox;
@ -867,8 +854,8 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
// Gallium drivers
// ====================================================
else {
const QList<QByteArray> tokens = m_context->renderer().toByteArray().split(' ');
if (m_context->renderer().contains("Gallium")) {
const QList<QByteArray> tokens = renderer.toByteArray().split(' ');
if (renderer.contains("Gallium")) {
// Sample renderer string: Gallium 0.4 on AMD RV740
m_chipset = (tokens.at(3) == "AMD" || tokens.at(3) == "ATI") ? tokens.at(4) : tokens.at(3);
} else {
@ -877,25 +864,25 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
}
// R300G
if (m_context->vendor() == QByteArrayLiteral("X.Org R300 Project")) {
if (vendor == QByteArrayLiteral("X.Org R300 Project")) {
m_chipClass = detectRadeonClass(m_chipset);
m_driver = Driver_R300G;
}
// R600G
else if (m_context->vendor() == "X.Org" && (m_context->renderer().contains("R6") || m_context->renderer().contains("R7") || m_context->renderer().contains("RV6") || m_context->renderer().contains("RV7") || m_context->renderer().contains("RS780") || m_context->renderer().contains("RS880") || m_context->renderer().contains("CEDAR") || m_context->renderer().contains("REDWOOD") || m_context->renderer().contains("JUNIPER") || m_context->renderer().contains("CYPRESS") || m_context->renderer().contains("HEMLOCK") || m_context->renderer().contains("PALM") || m_context->renderer().contains("EVERGREEN") || m_context->renderer().contains("SUMO") || m_context->renderer().contains("SUMO2") || m_context->renderer().contains("BARTS") || m_context->renderer().contains("TURKS") || m_context->renderer().contains("CAICOS") || m_context->renderer().contains("CAYMAN"))) {
else if (vendor == "X.Org" && (renderer.contains("R6") || renderer.contains("R7") || renderer.contains("RV6") || renderer.contains("RV7") || renderer.contains("RS780") || renderer.contains("RS880") || renderer.contains("CEDAR") || renderer.contains("REDWOOD") || renderer.contains("JUNIPER") || renderer.contains("CYPRESS") || renderer.contains("HEMLOCK") || renderer.contains("PALM") || renderer.contains("EVERGREEN") || renderer.contains("SUMO") || renderer.contains("SUMO2") || renderer.contains("BARTS") || renderer.contains("TURKS") || renderer.contains("CAICOS") || renderer.contains("CAYMAN"))) {
m_chipClass = detectRadeonClass(m_chipset);
m_driver = Driver_R600G;
}
// RadeonSI
else if ((m_context->vendor() == "X.Org" || m_context->vendor() == "AMD") && (m_context->renderer().contains("TAHITI") || m_context->renderer().contains("PITCAIRN") || m_context->renderer().contains("VERDE") || m_context->renderer().contains("OLAND") || m_context->renderer().contains("HAINAN") || m_context->renderer().contains("BONAIRE") || m_context->renderer().contains("KAVERI") || m_context->renderer().contains("KABINI") || m_context->renderer().contains("HAWAII") || m_context->renderer().contains("MULLINS") || m_context->renderer().contains("TOPAZ") || m_context->renderer().contains("TONGA") || m_context->renderer().contains("FIJI") || m_context->renderer().contains("CARRIZO") || m_context->renderer().contains("STONEY") || m_context->renderer().contains("POLARIS10") || m_context->renderer().contains("POLARIS11") || m_context->renderer().contains("POLARIS12") || m_context->renderer().contains("VEGAM") || m_context->renderer().contains("VEGA10") || m_context->renderer().contains("VEGA12") || m_context->renderer().contains("VEGA20") || m_context->renderer().contains("RAVEN") || m_context->renderer().contains("RAVEN2") || m_context->renderer().contains("RENOIR") || m_context->renderer().contains("ARCTURUS") || m_context->renderer().contains("NAVI10") || m_context->renderer().contains("NAVI12") || m_context->renderer().contains("NAVI14"))) {
m_chipClass = detectRadeonClass(m_context->renderer());
else if ((vendor == "X.Org" || vendor == "AMD") && (renderer.contains("TAHITI") || renderer.contains("PITCAIRN") || renderer.contains("VERDE") || renderer.contains("OLAND") || renderer.contains("HAINAN") || renderer.contains("BONAIRE") || renderer.contains("KAVERI") || renderer.contains("KABINI") || renderer.contains("HAWAII") || renderer.contains("MULLINS") || renderer.contains("TOPAZ") || renderer.contains("TONGA") || renderer.contains("FIJI") || renderer.contains("CARRIZO") || renderer.contains("STONEY") || renderer.contains("POLARIS10") || renderer.contains("POLARIS11") || renderer.contains("POLARIS12") || renderer.contains("VEGAM") || renderer.contains("VEGA10") || renderer.contains("VEGA12") || renderer.contains("VEGA20") || renderer.contains("RAVEN") || renderer.contains("RAVEN2") || renderer.contains("RENOIR") || renderer.contains("ARCTURUS") || renderer.contains("NAVI10") || renderer.contains("NAVI12") || renderer.contains("NAVI14"))) {
m_chipClass = detectRadeonClass(renderer);
m_driver = Driver_RadeonSI;
}
// Nouveau
else if (m_context->vendor() == "nouveau") {
else if (vendor == "nouveau") {
m_chipClass = detectNVidiaClass(m_chipset);
m_driver = Driver_Nouveau;
}
@ -911,12 +898,12 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
}
// SVGA3D
else if (m_context->vendor() == "VMware, Inc." && m_chipset.contains("SVGA3D")) {
else if (vendor == "VMware, Inc." && m_chipset.contains("SVGA3D")) {
m_driver = Driver_VMware;
}
// virgl
else if (m_context->renderer() == "virgl") {
else if (renderer == "virgl") {
m_driver = Driver_Virgl;
}
}
@ -934,7 +921,7 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
m_recommendedCompositor = OpenGLCompositing;
}
if (driver() == Driver_R600G || (driver() == Driver_R600C && m_context->renderer().contains("DRI2"))) {
if (driver() == Driver_R600G || (driver() == Driver_R600C && renderer.contains("DRI2"))) {
m_looseBinding = true;
}
}
@ -988,16 +975,6 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
m_looseBinding = true;
}
if (isSoftwareEmulation()) {
if (m_driver < Driver_Llvmpipe) {
// we recommend QPainter
m_recommendedCompositor = QPainterCompositing;
} else {
// llvmpipe does support GLSL
m_recommendedCompositor = OpenGLCompositing;
}
}
if (m_driver == Driver_Qualcomm) {
if (m_chipClass == Adreno1XX) {
m_recommendedCompositor = NoCompositing;
@ -1026,37 +1003,33 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
m_virtualMachine = true;
m_recommendedCompositor = OpenGLCompositing;
}
}
static void print(const QByteArray &label, QByteArrayView setting)
{
qInfo("%-40s%s", label.data(), setting.data());
}
void GLPlatform::printResults() const
{
print(QByteArrayLiteral("OpenGL vendor string:"), m_context->vendor());
print(QByteArrayLiteral("OpenGL renderer string:"), m_context->renderer());
print(QByteArrayLiteral("OpenGL version string:"), m_context->openglVersionString());
print(QByteArrayLiteral("OpenGL shading language version string:"), m_glsl_version);
// print the results
print(QByteArrayLiteral("OpenGL vendor string:"), m_vendorString);
print(QByteArrayLiteral("OpenGL renderer string:"), m_rendererString);
print(QByteArrayLiteral("OpenGL version string:"), m_openglVersionString);
print(QByteArrayLiteral("OpenGL shading language version string:"), m_glslVersionString);
print(QByteArrayLiteral("Driver:"), driverToString8(m_driver));
if (!isMesaDriver()) {
print(QByteArrayLiteral("Driver version:"), m_driverVersion.toByteArray());
}
print(QByteArrayLiteral("GPU class:"), chipClassToString8(m_chipClass));
print(QByteArrayLiteral("OpenGL version:"), m_context->openglVersion().toByteArray());
print(QByteArrayLiteral("OpenGL version:"), m_openglVersion.toByteArray());
print(QByteArrayLiteral("GLSL version:"), m_glslVersion.toByteArray());
if (isMesaDriver()) {
print(QByteArrayLiteral("Mesa version:"), mesaVersion().toByteArray());
}
print(QByteArrayLiteral("Requires strict binding:"), !m_looseBinding ? QByteArrayLiteral("yes") : QByteArrayLiteral("no"));
print(QByteArrayLiteral("Virtual Machine:"), m_virtualMachine ? QByteArrayLiteral("yes") : QByteArrayLiteral("no"));
print(QByteArrayLiteral("Timer query support:"), m_context->supportsTimerQueries() ? QByteArrayLiteral("yes") : QByteArrayLiteral("no"));
}
GLPlatform::~GLPlatform()
{
}
Version GLPlatform::glVersion() const
{
return m_context ? m_context->openglVersion() : Version();
return m_openglVersion;
}
Version GLPlatform::glslVersion() const
@ -1123,11 +1096,6 @@ bool GLPlatform::isVirgl() const
return m_driver == Driver_Virgl;
}
bool GLPlatform::isSoftwareEmulation() const
{
return m_context ? m_context->isSoftwareRenderer() : false;
}
bool GLPlatform::isAdreno() const
{
return m_chipClass >= Adreno1XX && m_chipClass <= UnknownAdreno;
@ -1155,22 +1123,22 @@ bool GLPlatform::isVideoCore3D() const
QByteArrayView GLPlatform::glRendererString() const
{
return m_context ? m_context->renderer() : "";
return m_rendererString;
}
QByteArrayView GLPlatform::glVendorString() const
{
return m_context ? m_context->vendor() : "";
return m_vendorString;
}
QByteArrayView GLPlatform::glVersionString() const
{
return m_context ? m_context->openglVersionString() : "";
return m_openglVersionString;
}
QByteArrayView GLPlatform::glShadingLanguageVersionString() const
{
return m_glsl_version;
return m_glslVersionString;
}
bool GLPlatform::isLooseBinding() const
@ -1198,14 +1166,4 @@ OpenGLPlatformInterface GLPlatform::platformInterface() const
return m_platformInterface;
}
bool GLPlatform::isGLES() const
{
return m_context ? m_context->isOpenglES() : false;
}
void GLPlatform::cleanup()
{
s_platform.reset();
}
} // namespace KWin

View file

@ -138,23 +138,9 @@ enum ChipClass {
class KWIN_EXPORT GLPlatform
{
public:
explicit GLPlatform(OpenGLPlatformInterface platformInterface, QByteArrayView openglVersionString, QByteArrayView glslVersionString, QByteArrayView renderer, QByteArrayView vendor);
~GLPlatform();
/**
* Runs the detection code using the current OpenGL context.
*/
void detect(OpenGLPlatformInterface platformInterface);
/**
* Prints the results of the detection code.
*/
void printResults() const;
/**
* Returns a pointer to the GLPlatform instance.
*/
static GLPlatform *instance();
/**
* Returns the OpenGL version.
*/
@ -219,12 +205,6 @@ public:
*/
bool isVMware() const;
/**
* @returns @c true if OpenGL is emulated in software.
* @since 4.7
*/
bool isSoftwareEmulation() const;
/**
* @returns @c true if the driver is known to be from a virtual machine.
* @since 4.10
@ -293,10 +273,6 @@ public:
* @since 4.9
*/
bool isLooseBinding() const;
/**
* @returns Whether OpenGL ES is used
*/
bool isGLES() const;
/**
* @returns The CompositingType recommended by the driver.
@ -344,34 +320,23 @@ public:
*/
static QByteArray chipClassToString8(ChipClass chipClass);
static void cleanup();
private:
GLPlatform();
private:
QByteArray m_glsl_version;
QByteArrayView m_chipset;
Driver m_driver;
ChipClass m_chipClass;
CompositingType m_recommendedCompositor;
QByteArrayView m_openglVersionString;
QByteArrayView m_glslVersionString;
QByteArrayView m_chipset = QByteArrayLiteral("Unknown");
QByteArrayView m_rendererString;
QByteArrayView m_vendorString;
Driver m_driver = Driver_Unknown;
ChipClass m_chipClass = UnknownChipClass;
CompositingType m_recommendedCompositor = OpenGLCompositing;
Version m_openglVersion;
Version m_glslVersion;
Version m_mesaVersion;
Version m_driverVersion;
bool m_looseBinding : 1;
bool m_virtualMachine : 1;
bool m_preferBufferSubData : 1;
bool m_looseBinding = false;
bool m_virtualMachine = false;
bool m_preferBufferSubData = false;
OpenGLPlatformInterface m_platformInterface;
std::unique_ptr<OpenGlContext> m_context;
static std::unique_ptr<GLPlatform> s_platform;
};
inline GLPlatform *GLPlatform::instance()
{
if (!s_platform) {
s_platform.reset(new GLPlatform());
}
return s_platform.get();
}
} // namespace KWin

View file

@ -34,7 +34,7 @@ void glResolveFunctions(const std::function<resolveFuncPtr(const char *)> &resol
const bool haveArbRobustness = context->hasOpenglExtension(QByteArrayLiteral("GL_ARB_robustness"));
const bool haveExtRobustness = context->hasOpenglExtension(QByteArrayLiteral("GL_EXT_robustness"));
bool robustContext = false;
if (GLPlatform::instance()->isGLES()) {
if (context->isOpenglES()) {
if (haveExtRobustness) {
GLint value = 0;
glGetIntegerv(GL_CONTEXT_ROBUST_ACCESS_EXT, &value);

View file

@ -381,9 +381,9 @@ GLvoid *GLVertexBuffer::map(size_t size)
glBindBuffer(GL_ARRAY_BUFFER, d->buffer);
bool preferBufferSubData = GLPlatform::instance()->preferBufferSubData();
if (OpenGlContext::currentContext()->hasMapBufferRange() && !preferBufferSubData) {
const auto context = OpenGlContext::currentContext();
const bool preferBufferSubData = context->glPlatform()->preferBufferSubData();
if (context->hasMapBufferRange() && !preferBufferSubData) {
return (GLvoid *)d->mapNextFreeRange(size);
}
@ -406,9 +406,10 @@ void GLVertexBuffer::unmap()
return;
}
bool preferBufferSubData = GLPlatform::instance()->preferBufferSubData();
const auto context = OpenGlContext::currentContext();
const bool preferBufferSubData = context->glPlatform()->preferBufferSubData();
if (OpenGlContext::currentContext()->hasMapBufferRange() && !preferBufferSubData) {
if (context->hasMapBufferRange() && !preferBufferSubData) {
glUnmapBuffer(GL_ARRAY_BUFFER);
d->baseAddress = d->nextOffset;

View file

@ -7,6 +7,7 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "openglcontext.h"
#include "glplatform.h"
#include "glvertexbuffer.h"
#include <QByteArray>
@ -69,7 +70,7 @@ static bool checkIndexedQuads(OpenGlContext *context)
}
}
OpenGlContext::OpenGlContext()
OpenGlContext::OpenGlContext(bool EGL)
: m_versionString((const char *)glGetString(GL_VERSION))
, m_version(Version::parseString(m_versionString))
, m_glslVersionString((const char *)glGetString(GL_SHADING_LANGUAGE_VERSION))
@ -93,6 +94,11 @@ OpenGlContext::OpenGlContext()
, m_haveSyncFences((m_isOpenglES && hasVersion(Version(3, 0))) || (!m_isOpenglES && hasVersion(Version(3, 2))) || hasOpenglExtension(QByteArrayLiteral("GL_ARB_sync")))
, m_supportsIndexedQuads(checkIndexedQuads(this))
, m_supportsPackInvert(hasOpenglExtension(QByteArrayLiteral("GL_MESA_pack_invert")))
, m_glPlatform(std::make_unique<GLPlatform>(EGL ? EglPlatformInterface : GlxPlatformInterface, m_versionString, m_glslVersionString, m_renderer, m_vendor))
{
}
OpenGlContext::~OpenGlContext()
{
}
@ -242,6 +248,11 @@ IndexBuffer *OpenGlContext::indexBuffer() const
return m_indexBuffer;
}
GLPlatform *OpenGlContext::glPlatform() const
{
return m_glPlatform.get();
}
bool OpenGlContext::checkSupported() const
{
const bool supportsGLSL = m_isOpenglES || (hasOpenglExtension("GL_ARB_shader_objects") && hasOpenglExtension("GL_ARB_fragment_shader") && hasOpenglExtension("GL_ARB_vertex_shader"));

View file

@ -23,12 +23,13 @@ class ShaderManager;
class GLFramebuffer;
class GLVertexBuffer;
class IndexBuffer;
class GLPlatform;
class KWIN_EXPORT OpenGlContext
{
public:
explicit OpenGlContext();
virtual ~OpenGlContext() = default;
explicit OpenGlContext(bool EGL);
virtual ~OpenGlContext();
bool hasVersion(const Version &version) const;
@ -57,6 +58,7 @@ public:
ShaderManager *shaderManager() const;
GLVertexBuffer *streamingVbo() const;
IndexBuffer *indexBuffer() const;
GLPlatform *glPlatform() const;
QSet<QByteArray> openglExtensions() const;
/**
@ -97,6 +99,7 @@ protected:
const bool m_haveSyncFences;
const bool m_supportsIndexedQuads;
const bool m_supportsPackInvert;
const std::unique_ptr<GLPlatform> m_glPlatform;
ShaderManager *m_shaderManager = nullptr;
GLVertexBuffer *m_streamingBuffer = nullptr;
IndexBuffer *m_indexBuffer = nullptr;

View file

@ -86,7 +86,6 @@ void AbstractEglBackend::cleanup()
}
cleanupSurfaces();
GLPlatform::cleanup();
m_context.reset();
}
@ -113,9 +112,6 @@ static eglFuncPtr getProcAddress(const char *name)
void AbstractEglBackend::initKWinGL()
{
GLPlatform *glPlatform = GLPlatform::instance();
glPlatform->detect(EglPlatformInterface);
glPlatform->printResults();
initGL(&getProcAddress);
}

View file

@ -277,8 +277,11 @@ QMatrix4x4 ContrastEffect::colorMatrix(qreal contrast, qreal intensity, qreal sa
bool ContrastEffect::enabledByDefault()
{
GLPlatform *gl = GLPlatform::instance();
const auto context = effects->openglContext();
if (!context || context->isSoftwareRenderer()) {
return false;
}
const auto gl = context->glPlatform();
if (gl->isIntel() && gl->chipClass() < SandyBridge) {
return false;
}
@ -288,10 +291,6 @@ bool ContrastEffect::enabledByDefault()
if (gl->isLima() || gl->isVideoCore4() || gl->isVideoCore3D()) {
return false;
}
if (gl->isSoftwareEmulation()) {
return false;
}
return true;
}

View file

@ -350,7 +350,11 @@ bool BlurEffect::eventFilter(QObject *watched, QEvent *event)
bool BlurEffect::enabledByDefault()
{
GLPlatform *gl = GLPlatform::instance();
const auto context = effects->openglContext();
if (!context || context->isSoftwareRenderer()) {
return false;
}
GLPlatform *gl = context->glPlatform();
if (gl->isIntel() && gl->chipClass() < SandyBridge) {
return false;
@ -362,10 +366,6 @@ bool BlurEffect::enabledByDefault()
if (gl->isLima() || gl->isVideoCore4() || gl->isVideoCore3D()) {
return false;
}
if (gl->isSoftwareEmulation()) {
return false;
}
return true;
}

View file

@ -62,12 +62,12 @@ static void doGrabTexture(GLTexture *texture, spa_data *spa, spa_video_format fo
texture->bind();
// BUG: The nvidia driver fails to glGetTexImage
// Drop driver() == DriverNVidia some time after that's fixed
if (GLPlatform::instance()->isGLES() || GLPlatform::instance()->driver() == Driver_NVidia) {
if (context->isOpenglES() || context->glPlatform()->driver() == Driver_NVidia) {
GLFramebuffer fbo(texture);
GLFramebuffer::pushFramebuffer(&fbo);
glReadPixels(0, 0, size.width(), size.height(), closestGLType(format), GL_UNSIGNED_BYTE, spa->data);
GLFramebuffer::popFramebuffer();
} else if (GLPlatform::instance()->glVersion() >= Version(4, 5)) {
} else if (context->openglVersion() >= Version(4, 5)) {
glGetTextureImage(texture->texture(), 0, closestGLType(format), GL_UNSIGNED_BYTE, spa->chunk->size, spa->data);
} else {
glGetTexImage(texture->target(), 0, closestGLType(format), GL_UNSIGNED_BYTE, spa->data);

View file

@ -82,7 +82,8 @@ std::unique_ptr<ShadowTextureProvider> WorkspaceSceneOpenGL::createShadowTexture
bool WorkspaceSceneOpenGL::animationsSupported() const
{
return !GLPlatform::instance()->isSoftwareEmulation();
const auto context = openglContext();
return context && !context->isSoftwareRenderer();
}
std::pair<std::shared_ptr<GLTexture>, ColorDescription> WorkspaceSceneOpenGL::textureForOutput(Output *output) const

View file

@ -41,6 +41,7 @@
#if KWIN_BUILD_TABBOX
#include "tabbox/tabbox.h"
#endif
#include "compositor.h"
#include "decorations/decorationbridge.h"
#include "dpmsinputeventfilter.h"
#include "lidswitchtracker.h"
@ -49,6 +50,7 @@
#include "placeholderinputeventfilter.h"
#include "placeholderoutput.h"
#include "placementtracker.h"
#include "scene/workspacescene.h"
#include "tabletmodemanager.h"
#include "tiles/tilemanager.h"
#include "useractions.h"
@ -1820,8 +1822,9 @@ QString Workspace::supportInformation() const
support.append(QStringLiteral("Compositing is active\n"));
switch (effects->compositingType()) {
case OpenGLCompositing: {
GLPlatform *platform = GLPlatform::instance();
if (platform->isGLES()) {
const auto context = Compositor::self()->scene()->openglContext();
GLPlatform *platform = context->glPlatform();
if (context->isOpenglES()) {
support.append(QStringLiteral("Compositing Type: OpenGL ES 2.0\n"));
} else {
support.append(QStringLiteral("Compositing Type: OpenGL\n"));