platformsupport/scenes/opengl: add opengl render query class

master
Xaver Hugl 1 year ago
parent 417eeaf44b
commit 02b996cf9c

@ -146,11 +146,11 @@ 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->supports(GLFeature::LooseBinding), false);
QCOMPARE(gl->supports(GLFeature::GLSL), false);
QCOMPARE(gl->supports(GLFeature::LimitedGLSL), false);
QCOMPARE(gl->supports(GLFeature::TextureNPOT), false);
QCOMPARE(gl->supports(GLFeature::LimitedNPOT), false);
QCOMPARE(gl->glVersion(), Version());
QCOMPARE(gl->glslVersion(), Version());
@ -248,11 +248,11 @@ void GLPlatformTest::testDetect()
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->supports(GLFeature::LooseBinding), settingsGroup.readEntry("LooseBinding", false));
QCOMPARE(gl->supports(GLFeature::GLSL), settingsGroup.readEntry("GLSL", false));
QCOMPARE(gl->supports(GLFeature::LimitedGLSL), settingsGroup.readEntry("LimitedGLSL", false));
QCOMPARE(gl->supports(GLFeature::TextureNPOT), settingsGroup.readEntry("TextureNPOT", false));
QCOMPARE(gl->supports(GLFeature::LimitedNPOT), settingsGroup.readEntry("LimitedNPOT", false));
QCOMPARE(gl->glVersion(), readVersion(settingsGroup, "GLVersion"));
QCOMPARE(gl->glslVersion(), readVersion(settingsGroup, "GLSLVersion"));

@ -212,7 +212,7 @@ bool Compositor::attemptOpenGLCompositing()
// set strict binding
if (options->isGlStrictBindingFollowsDriver()) {
options->setGlStrictBinding(!GLPlatform::instance()->supports(LooseBinding));
options->setGlStrictBinding(!GLPlatform::instance()->supports(GLFeature::LooseBinding));
}
qCDebug(KWIN_CORE) << "OpenGL compositing has been successfully initialized";

@ -807,6 +807,16 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
m_textureNPOT = m_extensions.contains("GL_ARB_texture_non_power_of_two");
}
if (!qEnvironmentVariableIsSet("KWIN_NO_TIMER_QUERY")) {
if (isGLES()) {
// 3.0 is required so query functions can be used without "EXT" suffix.
// Timer queries are still not part of the core OpenGL ES specification.
m_supportsTimerQuery = glVersion() >= Version(3, 0) && m_extensions.contains("GL_EXT_disjoint_timer_query");
} else {
m_supportsTimerQuery = glVersion() >= Version(3, 3) || m_extensions.contains("GL_ARB_timer_query");
}
}
m_serverVersion = getXServerVersion();
m_kernelVersion = getKernelVersion();
@ -1193,32 +1203,28 @@ void GLPlatform::printResults() const
print(QByteArrayLiteral("GLSL shaders:"), m_supportsGLSL ? (m_limitedGLSL ? QByteArrayLiteral("limited") : QByteArrayLiteral("yes")) : QByteArrayLiteral("no"));
print(QByteArrayLiteral("Texture NPOT support:"), m_textureNPOT ? (m_limitedNPOT ? QByteArrayLiteral("limited") : QByteArrayLiteral("yes")) : QByteArrayLiteral("no"));
print(QByteArrayLiteral("Virtual Machine:"), m_virtualMachine ? QByteArrayLiteral("yes") : QByteArrayLiteral("no"));
print(QByteArrayLiteral("Timer query support:"), m_supportsTimerQuery ? QByteArrayLiteral("yes") : QByteArrayLiteral("no"));
}
bool GLPlatform::supports(GLFeature feature) const
{
switch (feature) {
case LooseBinding:
case GLFeature::LooseBinding:
return m_looseBinding;
case GLSL:
case GLFeature::GLSL:
return m_supportsGLSL;
case LimitedGLSL:
case GLFeature::LimitedGLSL:
return m_limitedGLSL;
case TextureNPOT:
case GLFeature::TextureNPOT:
return m_textureNPOT;
case LimitedNPOT:
case GLFeature::LimitedNPOT:
return m_limitedNPOT;
case PackInvert:
case GLFeature::PackInvert:
return m_packInvert;
default:
return false;
case GLFeature::TimerQuery:
return m_supportsTimerQuery;
}
return false;
}
Version GLPlatform::glVersion() const

@ -24,7 +24,7 @@ void cleanupGL();
class Version;
enum GLFeature {
enum class GLFeature {
/**
* Set when a texture bound to a pixmap uses the same storage as the pixmap,
* and thus doesn't need to be rebound when the contents of the pixmap
@ -75,6 +75,11 @@ enum GLFeature {
* Set if the extension GL_MESA_pack_invert is present
*/
PackInvert,
/**
* Set if the driver supports GL_ARB_timer_query extension or OpenGL 3.3.
*/
TimerQuery,
};
enum Driver {
@ -479,6 +484,7 @@ private:
bool m_textureNPOT : 1;
bool m_limitedNPOT : 1;
bool m_packInvert : 1;
bool m_supportsTimerQuery : 1;
bool m_virtualMachine : 1;
bool m_preferBufferSubData : 1;
OpenGLPlatformInterface m_platformInterface;

@ -357,9 +357,9 @@ bool GLShader::compile(GLuint program, GLenum shaderType, const QByteArray &sour
bool GLShader::load(const QByteArray &vertexSource, const QByteArray &fragmentSource)
{
// Make sure shaders are actually supported
if (!(GLPlatform::instance()->supports(GLSL) &&
if (!(GLPlatform::instance()->supports(GLFeature::GLSL) &&
// we lack shader branching for Texture2DRectangle everywhere - and it's probably not worth it
GLPlatform::instance()->supports(TextureNPOT))) {
GLPlatform::instance()->supports(GLFeature::TextureNPOT))) {
qCCritical(LIBKWINGLUTILS) << "Shaders are not supported";
return false;
}

@ -5,6 +5,7 @@ target_sources(kwin PRIVATE
egldisplay.cpp
eglnativefence.cpp
eglswapchain.cpp
glrendertimequery.cpp
kwineglimagetexture.cpp
openglbackend.cpp
openglsurfacetexture.cpp

@ -0,0 +1,65 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "glrendertimequery.h"
#include "libkwineffects/kwinglplatform.h"
namespace KWin
{
GLRenderTimeQuery::GLRenderTimeQuery()
{
if (GLPlatform::instance()->supports(GLFeature::TimerQuery)) {
glGenQueries(1, &m_query);
}
}
GLRenderTimeQuery::~GLRenderTimeQuery()
{
if (m_query) {
glDeleteQueries(1, &m_query);
}
}
void GLRenderTimeQuery::begin()
{
if (m_query) {
GLint64 nanos = 0;
glGetInteger64v(GL_TIMESTAMP, &nanos);
m_cpuStart = std::chrono::nanoseconds(nanos);
} else {
m_cpuStart = std::chrono::steady_clock::now().time_since_epoch();
}
}
void GLRenderTimeQuery::end()
{
if (m_query) {
glQueryCounter(m_query, GL_TIMESTAMP);
} else {
m_cpuEnd = std::chrono::steady_clock::now().time_since_epoch();
}
m_hasResult = true;
}
std::chrono::nanoseconds GLRenderTimeQuery::result()
{
if (!m_hasResult) {
return std::chrono::nanoseconds::zero();
}
m_hasResult = false;
if (m_query) {
uint64_t nanos = 0;
glGetQueryObjectui64v(m_query, GL_QUERY_RESULT, &nanos);
return std::chrono::nanoseconds(nanos) - m_cpuStart;
} else {
return m_cpuEnd - m_cpuStart;
}
}
}

@ -0,0 +1,40 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <chrono>
#include <epoxy/gl.h>
#include "kwin_export.h"
namespace KWin
{
class KWIN_EXPORT GLRenderTimeQuery
{
public:
explicit GLRenderTimeQuery();
~GLRenderTimeQuery();
void begin();
void end();
/**
* fetches the result of the query. If rendering is not done yet, this will block!
*/
std::chrono::nanoseconds result();
private:
GLuint m_query = 0;
bool m_hasResult = false;
std::chrono::nanoseconds m_cpuStart = std::chrono::nanoseconds::zero();
std::chrono::nanoseconds m_cpuEnd = std::chrono::nanoseconds::zero();
};
}

@ -51,7 +51,7 @@ static void doGrabTexture(GLTexture *texture, spa_data *spa, spa_video_format fo
{
const QSize size = texture->size();
const bool invertNeeded = GLPlatform::instance()->isGLES() ^ !(texture->contentTransforms() & TextureTransform::MirrorY);
const bool invertNeededAndSupported = invertNeeded && GLPlatform::instance()->supports(PackInvert);
const bool invertNeededAndSupported = invertNeeded && GLPlatform::instance()->supports(GLFeature::PackInvert);
GLboolean prev;
if (invertNeededAndSupported) {
glGetBooleanv(GL_PACK_INVERT_MESA, &prev);

@ -1775,7 +1775,7 @@ QString Workspace::supportInformation() const
}
support.append(QStringLiteral("\n"));
if (platform->supports(LimitedGLSL) || platform->supports(GLSL)) {
if (platform->supports(GLFeature::LimitedGLSL) || platform->supports(GLFeature::GLSL)) {
support.append(QStringLiteral("OpenGL shading language version string: ") + QString::fromUtf8(platform->glShadingLanguageVersionString()) + QStringLiteral("\n"));
}
@ -1788,7 +1788,7 @@ QString Workspace::supportInformation() const
support.append(QStringLiteral("OpenGL version: ") + GLPlatform::versionToString(platform->glVersion()) + QStringLiteral("\n"));
if (platform->supports(LimitedGLSL) || platform->supports(GLSL)) {
if (platform->supports(GLFeature::LimitedGLSL) || platform->supports(GLFeature::GLSL)) {
support.append(QStringLiteral("GLSL version: ") + GLPlatform::versionToString(platform->glslVersion()) + QStringLiteral("\n"));
}
@ -1810,8 +1810,8 @@ QString Workspace::supportInformation() const
support.append(QStringLiteral("no\n"));
}
support.append(QStringLiteral("GLSL shaders: "));
if (platform->supports(GLSL)) {
if (platform->supports(LimitedGLSL)) {
if (platform->supports(GLFeature::GLSL)) {
if (platform->supports(GLFeature::LimitedGLSL)) {
support.append(QStringLiteral(" limited\n"));
} else {
support.append(QStringLiteral(" yes\n"));
@ -1820,8 +1820,8 @@ QString Workspace::supportInformation() const
support.append(QStringLiteral(" no\n"));
}
support.append(QStringLiteral("Texture NPOT support: "));
if (platform->supports(TextureNPOT)) {
if (platform->supports(LimitedNPOT)) {
if (platform->supports(GLFeature::TextureNPOT)) {
if (platform->supports(GLFeature::LimitedNPOT)) {
support.append(QStringLiteral(" limited\n"));
} else {
support.append(QStringLiteral(" yes\n"));

Loading…
Cancel
Save