Move opengl debug output initialization to kwinglutils

kwinglutils is a better place as the debug output is initialized for the
render backend's context, not scene's context.
This commit is contained in:
Vlad Zahorodnii 2021-11-08 21:35:52 +02:00
parent 2560288e4b
commit dabcb558b4
3 changed files with 82 additions and 83 deletions

View file

@ -50,6 +50,86 @@ static QList<QByteArray> glExtensions;
// Functions
static void initDebugOutput()
{
static bool enabled = qEnvironmentVariableIntValue("KWIN_GL_DEBUG");
if (!enabled) {
return;
}
const bool have_KHR_debug = hasGLExtension(QByteArrayLiteral("GL_KHR_debug"));
const bool have_ARB_debug = hasGLExtension(QByteArrayLiteral("GL_ARB_debug_output"));
if (!have_KHR_debug && !have_ARB_debug)
return;
if (!have_ARB_debug) {
// if we don't have ARB debug, but only KHR debug we need to verify whether the context is a debug context
// it should work without as well, but empirical tests show: no it doesn't
if (GLPlatform::instance()->isGLES()) {
if (!hasGLVersion(3, 2)) {
// empirical data shows extension doesn't work
return;
}
} else if (!hasGLVersion(3, 0)) {
return;
}
// can only be queried with either OpenGL >= 3.0 or OpenGL ES of at least 3.1
GLint value = 0;
glGetIntegerv(GL_CONTEXT_FLAGS, &value);
if (!(value & GL_CONTEXT_FLAG_DEBUG_BIT)) {
return;
}
}
// Set the callback function
auto callback = [](GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei length,
const GLchar *message,
const GLvoid *userParam) {
Q_UNUSED(source)
Q_UNUSED(severity)
Q_UNUSED(userParam)
while (length && std::isspace(message[length - 1])) {
--length;
}
switch (type) {
case GL_DEBUG_TYPE_ERROR:
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
qCWarning(LIBKWINGLUTILS, "%#x: %.*s", id, length, message);
break;
case GL_DEBUG_TYPE_OTHER:
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
case GL_DEBUG_TYPE_PORTABILITY:
case GL_DEBUG_TYPE_PERFORMANCE:
default:
qCDebug(LIBKWINGLUTILS, "%#x: %.*s", id, length, message);
break;
}
};
glDebugMessageCallback(callback, nullptr);
// This state exists only in GL_KHR_debug
if (have_KHR_debug)
glEnable(GL_DEBUG_OUTPUT);
#if !defined(QT_NO_DEBUG)
// Enable all debug messages
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
#else
// Enable error messages
glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, nullptr, GL_TRUE);
glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, GL_DONT_CARE, 0, nullptr, GL_TRUE);
#endif
// Insert a test message
const QByteArray message = QByteArrayLiteral("OpenGL debug output initialized");
glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0,
GL_DEBUG_SEVERITY_LOW, message.length(), message.constData());
}
void initGL(const std::function<resolveFuncPtr(const char*)> &resolveFunction)
{
// Get list of supported OpenGL extensions
@ -67,6 +147,8 @@ void initGL(const std::function<resolveFuncPtr(const char*)> &resolveFunction)
// handle OpenGL extensions functions
glResolveFunctions(resolveFunction);
initDebugOutput();
GLTexturePrivate::initStatic();
GLRenderTarget::initStatic();
GLVertexBuffer::initStatic();

View file

@ -96,9 +96,6 @@ SceneOpenGL::SceneOpenGL(OpenGLBackend *backend, QObject *parent)
glBindVertexArray(vao);
}
m_debug = qstrcmp(qgetenv("KWIN_GL_DEBUG"), "1") == 0;
initDebugOutput();
// set strict binding
if (options->isGlStrictBindingFollowsDriver()) {
options->setGlStrictBinding(!glPlatform->supports(LooseBinding));
@ -119,82 +116,6 @@ SceneOpenGL::~SceneOpenGL()
SceneOpenGL::EffectFrame::cleanup();
}
void SceneOpenGL::initDebugOutput()
{
const bool have_KHR_debug = hasGLExtension(QByteArrayLiteral("GL_KHR_debug"));
const bool have_ARB_debug = hasGLExtension(QByteArrayLiteral("GL_ARB_debug_output"));
if (!have_KHR_debug && !have_ARB_debug)
return;
if (!have_ARB_debug) {
// if we don't have ARB debug, but only KHR debug we need to verify whether the context is a debug context
// it should work without as well, but empirical tests show: no it doesn't
if (GLPlatform::instance()->isGLES()) {
if (!hasGLVersion(3, 2)) {
// empirical data shows extension doesn't work
return;
}
} else if (!hasGLVersion(3, 0)) {
return;
}
// can only be queried with either OpenGL >= 3.0 or OpenGL ES of at least 3.1
GLint value = 0;
glGetIntegerv(GL_CONTEXT_FLAGS, &value);
if (!(value & GL_CONTEXT_FLAG_DEBUG_BIT)) {
return;
}
}
// Set the callback function
auto callback = [](GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei length,
const GLchar *message,
const GLvoid *userParam) {
Q_UNUSED(source)
Q_UNUSED(severity)
Q_UNUSED(userParam)
while (length && std::isspace(message[length - 1])) {
--length;
}
switch (type) {
case GL_DEBUG_TYPE_ERROR:
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
qCWarning(KWIN_OPENGL, "%#x: %.*s", id, length, message);
break;
case GL_DEBUG_TYPE_OTHER:
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
case GL_DEBUG_TYPE_PORTABILITY:
case GL_DEBUG_TYPE_PERFORMANCE:
default:
qCDebug(KWIN_OPENGL, "%#x: %.*s", id, length, message);
break;
}
};
glDebugMessageCallback(callback, nullptr);
// This state exists only in GL_KHR_debug
if (have_KHR_debug)
glEnable(GL_DEBUG_OUTPUT);
#if !defined(QT_NO_DEBUG)
// Enable all debug messages
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
#else
// Enable error messages
glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, nullptr, GL_TRUE);
glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, GL_DONT_CARE, 0, nullptr, GL_TRUE);
#endif
// Insert a test message
const QByteArray message = QByteArrayLiteral("OpenGL debug output initialized");
glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0,
GL_DEBUG_SEVERITY_LOW, message.length(), message.constData());
}
SceneOpenGL *SceneOpenGL::createScene(OpenGLBackend *backend, QObject *parent)
{
if (SceneOpenGL::supported(backend)) {

View file

@ -47,9 +47,6 @@ public:
SurfaceTexture *createSurfaceTextureX11(SurfacePixmapX11 *pixmap) override;
SurfaceTexture *createSurfaceTextureWayland(SurfacePixmapWayland *pixmap) override;
bool debug() const { return m_debug; }
void initDebugOutput();
OpenGLBackend *backend() const {
return m_backend;
}
@ -86,7 +83,6 @@ private:
bool init_ok = true;
bool m_resetOccurred = false;
bool m_debug = false;
OpenGLBackend *m_backend;
LanczosFilter *m_lanczosFilter = nullptr;
QScopedPointer<GLTexture> m_cursorTexture;