You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

84 lines
2.1 KiB

/*
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 "opengl/glplatform.h"
namespace KWin
{
GLRenderTimeQuery::GLRenderTimeQuery(const std::shared_ptr<OpenGlContext> &context)
: m_context(context)
{
if (context->supportsTimerQueries()) {
glGenQueries(1, &m_gpuProbe.query);
}
}
GLRenderTimeQuery::~GLRenderTimeQuery()
{
if (!m_gpuProbe.query) {
return;
}
const auto context = m_context.lock();
if (!context) {
return;
}
context->makeCurrent();
glDeleteQueries(1, &m_gpuProbe.query);
}
void GLRenderTimeQuery::begin()
{
if (m_gpuProbe.query) {
GLint64 start = 0;
glGetInteger64v(GL_TIMESTAMP, &start);
m_gpuProbe.start = std::chrono::nanoseconds(start);
}
m_cpuProbe.start = std::chrono::steady_clock::now();
}
void GLRenderTimeQuery::end()
{
m_hasResult = true;
if (m_gpuProbe.query) {
glQueryCounter(m_gpuProbe.query, GL_TIMESTAMP);
}
m_cpuProbe.end = std::chrono::steady_clock::now();
}
std::optional<RenderTimeSpan> GLRenderTimeQuery::query()
{
if (!m_hasResult) {
return std::nullopt;
}
m_hasResult = false;
if (m_gpuProbe.query) {
const auto context = m_context.lock();
if (!context) {
return std::nullopt;
}
context->makeCurrent();
GLint64 end = 0;
glGetQueryObjecti64v(m_gpuProbe.query, GL_QUERY_RESULT, &end);
m_gpuProbe.end = std::chrono::nanoseconds(end);
}
// timings are pretty unpredictable in the sub-millisecond range; this minimum
// ensures that when CPU or GPU power states change, we don't drop any frames
const std::chrono::nanoseconds minimumTime = std::chrono::milliseconds(2);
const auto end = std::max({m_cpuProbe.start + (m_gpuProbe.end - m_gpuProbe.start), m_cpuProbe.end, m_cpuProbe.start + minimumTime});
return RenderTimeSpan{
.start = m_cpuProbe.start,
.end = end,
};
}
}