platformsupport/scenes/opengl: add opengl render query class
This commit is contained in:
parent
417eeaf44b
commit
02b996cf9c
10 changed files with 153 additions and 35 deletions
|
@ -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
|
||||
|
|
65
src/platformsupport/scenes/opengl/glrendertimequery.cpp
Normal file
65
src/platformsupport/scenes/opengl/glrendertimequery.cpp
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
40
src/platformsupport/scenes/opengl/glrendertimequery.h
Normal file
40
src/platformsupport/scenes/opengl/glrendertimequery.h
Normal file
|
@ -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…
Reference in a new issue