[platforms/x11] Use a GlxContextAttributeBuilder
Summary:
Based on the work of 3f4995fb9b
this change
introduces a GlxContextAttributeBuilder to make the requesting of context
attributes cleaner, more verbose and less error prone copy and paste.
Test Plan:
Switched between Core and legacy and verified the output;
extended auto test
Reviewers: #kwin, #plasma
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D6411
icc-effect-5.14.5
parent
36a3189863
commit
f88c322a3b
|
@ -86,6 +86,14 @@ public:
|
|||
return m_compatibilityProfile;
|
||||
}
|
||||
|
||||
void setResetOnVideoMemoryPurge(bool reset) {
|
||||
m_resetOnVideoMemoryPurge = reset;
|
||||
}
|
||||
|
||||
bool isResetOnVideoMemoryPurge() const {
|
||||
return m_resetOnVideoMemoryPurge;
|
||||
}
|
||||
|
||||
virtual std::vector<int> build() const = 0;
|
||||
|
||||
QDebug operator<<(QDebug dbg) const;
|
||||
|
@ -98,6 +106,7 @@ private:
|
|||
bool m_forwardCompatible = false;
|
||||
bool m_coreProfile = false;
|
||||
bool m_compatibilityProfile = false;
|
||||
bool m_resetOnVideoMemoryPurge = false;
|
||||
};
|
||||
|
||||
inline QDebug operator<<(QDebug dbg, const AbstractOpenGLContextAttributeBuilder *attribs)
|
||||
|
|
|
@ -366,7 +366,16 @@ target_link_libraries(testX11TimestampUpdate
|
|||
add_test(kwin-testX11TimestampUpdate testX11TimestampUpdate)
|
||||
ecm_mark_as_test(testX11TimestampUpdate)
|
||||
|
||||
add_executable(testOpenGLContextAttributeBuilder opengl_context_attribute_builder_test.cpp ../abstract_opengl_context_attribute_builder.cpp ../egl_context_attribute_builder.cpp)
|
||||
set(testOpenGLContextAttributeBuilder_SRCS
|
||||
opengl_context_attribute_builder_test.cpp
|
||||
../abstract_opengl_context_attribute_builder.cpp
|
||||
../egl_context_attribute_builder.cpp
|
||||
)
|
||||
|
||||
if(HAVE_EPOXY_GLX)
|
||||
set(testOpenGLContextAttributeBuilder_SRCS ${testOpenGLContextAttributeBuilder_SRCS} ../plugins/platforms/x11/standalone/glx_context_attribute_builder.cpp)
|
||||
endif()
|
||||
add_executable(testOpenGLContextAttributeBuilder ${testOpenGLContextAttributeBuilder_SRCS})
|
||||
target_link_libraries(testOpenGLContextAttributeBuilder Qt5::Test)
|
||||
add_test(kwin-testOpenGLContextAttributeBuilder testOpenGLContextAttributeBuilder)
|
||||
ecm_mark_as_test(testOpenGLContextAttributeBuilder)
|
||||
|
|
|
@ -22,6 +22,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <QtTest/QtTest>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
#include <kwinconfig.h>
|
||||
#if HAVE_EPOXY_GLX
|
||||
#include "../plugins/platforms/x11/standalone/glx_context_attribute_builder.h"
|
||||
#include <epoxy/glx.h>
|
||||
|
||||
#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV
|
||||
#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace KWin;
|
||||
|
||||
class OpenGLContextAttributeBuilderTest : public QObject
|
||||
|
@ -32,12 +42,15 @@ private Q_SLOTS:
|
|||
void testRobust();
|
||||
void testForwardCompatible();
|
||||
void testProfile();
|
||||
void testResetOnVideoMemoryPurge();
|
||||
void testVersionMajor();
|
||||
void testVersionMajorAndMinor();
|
||||
void testEgl_data();
|
||||
void testEgl();
|
||||
void testGles_data();
|
||||
void testGles();
|
||||
void testGlx_data();
|
||||
void testGlx();
|
||||
};
|
||||
|
||||
class MockOpenGLContextAttributeBuilder : public AbstractOpenGLContextAttributeBuilder
|
||||
|
@ -61,6 +74,7 @@ void OpenGLContextAttributeBuilderTest::testCtor()
|
|||
QCOMPARE(builder.isForwardCompatible(), false);
|
||||
QCOMPARE(builder.isCoreProfile(), false);
|
||||
QCOMPARE(builder.isCompatibilityProfile(), false);
|
||||
QCOMPARE(builder.isResetOnVideoMemoryPurge(), false);
|
||||
}
|
||||
|
||||
void OpenGLContextAttributeBuilderTest::testRobust()
|
||||
|
@ -99,6 +113,16 @@ void OpenGLContextAttributeBuilderTest::testProfile()
|
|||
QCOMPARE(builder.isCompatibilityProfile(), false);
|
||||
}
|
||||
|
||||
void OpenGLContextAttributeBuilderTest::testResetOnVideoMemoryPurge()
|
||||
{
|
||||
MockOpenGLContextAttributeBuilder builder;
|
||||
QCOMPARE(builder.isResetOnVideoMemoryPurge(), false);
|
||||
builder.setResetOnVideoMemoryPurge(true);
|
||||
QCOMPARE(builder.isResetOnVideoMemoryPurge(), true);
|
||||
builder.setResetOnVideoMemoryPurge(false);
|
||||
QCOMPARE(builder.isResetOnVideoMemoryPurge(), false);
|
||||
}
|
||||
|
||||
void OpenGLContextAttributeBuilderTest::testVersionMajor()
|
||||
{
|
||||
MockOpenGLContextAttributeBuilder builder;
|
||||
|
@ -249,5 +273,73 @@ void OpenGLContextAttributeBuilderTest::testGles()
|
|||
QTEST(attribs, "expectedAttribs");
|
||||
}
|
||||
|
||||
void OpenGLContextAttributeBuilderTest::testGlx_data()
|
||||
{
|
||||
#if HAVE_EPOXY_GLX
|
||||
QTest::addColumn<bool>("requestVersion");
|
||||
QTest::addColumn<int>("major");
|
||||
QTest::addColumn<int>("minor");
|
||||
QTest::addColumn<bool>("robust");
|
||||
QTest::addColumn<bool>("videoPurge");
|
||||
QTest::addColumn<std::vector<int>>("expectedAttribs");
|
||||
|
||||
QTest::newRow("fallback") << true << 2 << 1 << false << false << std::vector<int>{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
0};
|
||||
QTest::newRow("legacy/robust") << false << 0 << 0 << true << false << std::vector<int>{
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
0
|
||||
};
|
||||
QTest::newRow("legacy/robust/videoPurge") << false << 0 << 0 << true << true << std::vector<int>{
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, GL_TRUE,
|
||||
0
|
||||
};
|
||||
QTest::newRow("core") << true << 3 << 1 << false << false << std::vector<int>{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
0};
|
||||
QTest::newRow("core/robust") << true << 3 << 1 << true << false << std::vector<int>{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
0
|
||||
};
|
||||
QTest::newRow("core/robust/videoPurge") << true << 3 << 1 << true << true << std::vector<int>{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, GL_TRUE,
|
||||
0
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenGLContextAttributeBuilderTest::testGlx()
|
||||
{
|
||||
#if HAVE_EPOXY_GLX
|
||||
QFETCH(bool, requestVersion);
|
||||
QFETCH(int, major);
|
||||
QFETCH(int, minor);
|
||||
QFETCH(bool, robust);
|
||||
QFETCH(bool, videoPurge);
|
||||
|
||||
GlxContextAttributeBuilder builder;
|
||||
if (requestVersion) {
|
||||
builder.setVersion(major, minor);
|
||||
}
|
||||
builder.setRobust(robust);
|
||||
builder.setResetOnVideoMemoryPurge(videoPurge);
|
||||
|
||||
auto attribs = builder.build();
|
||||
QTEST(attribs, "expectedAttribs");
|
||||
#endif
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(OpenGLContextAttributeBuilderTest)
|
||||
#include "opengl_context_attribute_builder_test.moc"
|
||||
|
|
|
@ -13,7 +13,7 @@ if(X11_Xinput_FOUND)
|
|||
endif()
|
||||
|
||||
if(HAVE_EPOXY_GLX)
|
||||
set(X11PLATFORM_SOURCES ${X11PLATFORM_SOURCES} glxbackend.cpp)
|
||||
set(X11PLATFORM_SOURCES ${X11PLATFORM_SOURCES} glxbackend.cpp glx_context_attribute_builder.cpp)
|
||||
endif()
|
||||
|
||||
add_library(KWinX11Platform MODULE ${X11PLATFORM_SOURCES})
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#include "glx_context_attribute_builder.h"
|
||||
#include <epoxy/glx.h>
|
||||
|
||||
#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV
|
||||
#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
|
||||
#endif
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
std::vector<int> GlxContextAttributeBuilder::build() const
|
||||
{
|
||||
std::vector<int> attribs;
|
||||
if (isVersionRequested()) {
|
||||
attribs.emplace_back(GLX_CONTEXT_MAJOR_VERSION_ARB);
|
||||
attribs.emplace_back(majorVersion());
|
||||
attribs.emplace_back(GLX_CONTEXT_MINOR_VERSION_ARB);
|
||||
attribs.emplace_back(minorVersion());
|
||||
}
|
||||
if (isRobust()) {
|
||||
attribs.emplace_back(GLX_CONTEXT_FLAGS_ARB);
|
||||
attribs.emplace_back(GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB);
|
||||
attribs.emplace_back(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
|
||||
attribs.emplace_back(GLX_LOSE_CONTEXT_ON_RESET_ARB);
|
||||
if (isResetOnVideoMemoryPurge()) {
|
||||
attribs.emplace_back(GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV);
|
||||
attribs.emplace_back(GL_TRUE);
|
||||
}
|
||||
}
|
||||
attribs.emplace_back(0);
|
||||
return attribs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#pragma once
|
||||
#include "abstract_opengl_context_attribute_builder.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class GlxContextAttributeBuilder : public AbstractOpenGLContextAttributeBuilder
|
||||
{
|
||||
public:
|
||||
std::vector<int> build() const override;
|
||||
};
|
||||
|
||||
}
|
|
@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
// own
|
||||
#include "glxbackend.h"
|
||||
#include "logging.h"
|
||||
#include "glx_context_attribute_builder.h"
|
||||
// kwin
|
||||
#include "options.h"
|
||||
#include "overlaywindow.h"
|
||||
|
@ -65,10 +66,6 @@ typedef struct xcb_glx_buffer_swap_complete_event_t {
|
|||
} xcb_glx_buffer_swap_complete_event_t;
|
||||
#endif
|
||||
|
||||
#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV
|
||||
#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
|
||||
#endif
|
||||
|
||||
#include <tuple>
|
||||
#include <memory>
|
||||
|
||||
|
@ -288,77 +285,51 @@ bool GlxBackend::initRenderingContext()
|
|||
|
||||
// Use glXCreateContextAttribsARB() when it's available
|
||||
if (hasExtension(QByteArrayLiteral("GLX_ARB_create_context"))) {
|
||||
const int attribs_31_core_nv_robustness[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, GL_TRUE,
|
||||
0
|
||||
};
|
||||
|
||||
const int attribs_31_core_robustness[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
0
|
||||
};
|
||||
|
||||
const int attribs_31_core[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
0
|
||||
};
|
||||
|
||||
const int attribs_legacy_nv_robustness[] = {
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, GL_TRUE,
|
||||
0
|
||||
};
|
||||
|
||||
const int attribs_legacy_robustness[] = {
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
0
|
||||
};
|
||||
|
||||
const int attribs_legacy[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
0
|
||||
};
|
||||
|
||||
const bool have_robustness = hasExtension(QByteArrayLiteral("GLX_ARB_create_context_robustness"));
|
||||
const bool haveVideoMemoryPurge = hasExtension(QByteArrayLiteral("GLX_NV_robustness_video_memory_purge"));
|
||||
|
||||
// Try to create a 3.1 context first
|
||||
std::vector<GlxContextAttributeBuilder> candidates;
|
||||
if (options->glCoreProfile()) {
|
||||
if (have_robustness) {
|
||||
if (have_robustness) {
|
||||
if (haveVideoMemoryPurge) {
|
||||
ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_31_core_nv_robustness);
|
||||
}
|
||||
if (!ctx) {
|
||||
ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_31_core_robustness);
|
||||
GlxContextAttributeBuilder purgeMemoryCore;
|
||||
purgeMemoryCore.setVersion(3, 1);
|
||||
purgeMemoryCore.setRobust(true);
|
||||
purgeMemoryCore.setResetOnVideoMemoryPurge(true);
|
||||
candidates.emplace_back(std::move(purgeMemoryCore));
|
||||
}
|
||||
GlxContextAttributeBuilder robustCore;
|
||||
robustCore.setVersion(3, 1);
|
||||
robustCore.setRobust(true);
|
||||
candidates.emplace_back(std::move(robustCore));
|
||||
}
|
||||
|
||||
if (!ctx)
|
||||
ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_31_core);
|
||||
GlxContextAttributeBuilder core;
|
||||
core.setVersion(3, 1);
|
||||
candidates.emplace_back(std::move(core));
|
||||
} else {
|
||||
if (have_robustness) {
|
||||
if (haveVideoMemoryPurge) {
|
||||
GlxContextAttributeBuilder purgeMemoryLegacy;
|
||||
purgeMemoryLegacy.setRobust(true);
|
||||
purgeMemoryLegacy.setResetOnVideoMemoryPurge(true);
|
||||
candidates.emplace_back(std::move(purgeMemoryLegacy));
|
||||
}
|
||||
GlxContextAttributeBuilder robustLegacy;
|
||||
robustLegacy.setRobust(true);
|
||||
candidates.emplace_back(std::move(robustLegacy));
|
||||
}
|
||||
GlxContextAttributeBuilder legacy;
|
||||
legacy.setVersion(2, 1);
|
||||
candidates.emplace_back(std::move(legacy));
|
||||
}
|
||||
|
||||
if (!ctx && have_robustness) {
|
||||
if (haveVideoMemoryPurge) {
|
||||
ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_legacy_nv_robustness);
|
||||
}
|
||||
if (!ctx) {
|
||||
ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_legacy_robustness);
|
||||
for (auto it = candidates.begin(); it != candidates.end(); it++) {
|
||||
const auto attribs = it->build();
|
||||
ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, true, attribs.data());
|
||||
if (ctx) {
|
||||
qCDebug(KWIN_X11STANDALONE) << "Created GLX context with attributes:" << &(*it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx)
|
||||
ctx = glXCreateContextAttribsARB(display(), fbconfig, 0, direct, attribs_legacy);
|
||||
}
|
||||
|
||||
if (!ctx)
|
||||
|
|
Loading…
Reference in New Issue