core/renderloop: also log the predicted render time

It can be used to better judge why a frame was dropped
This commit is contained in:
Xaver Hugl 2024-06-24 19:45:57 +02:00
parent 92ceb00b37
commit 03eb688818
4 changed files with 20 additions and 2 deletions

View file

@ -48,6 +48,7 @@ OutputFrame::OutputFrame(RenderLoop *loop, std::chrono::nanoseconds refreshDurat
: m_loop(loop)
, m_refreshDuration(refreshDuration)
, m_targetPageflipTime(loop->nextPresentationTimestamp())
, m_predictedRenderTime(loop->predictedRenderTime())
{
}
@ -141,6 +142,11 @@ std::chrono::nanoseconds OutputFrame::refreshDuration() const
return m_refreshDuration;
}
std::chrono::nanoseconds OutputFrame::predictedRenderTime() const
{
return m_predictedRenderTime;
}
RenderBackend::RenderBackend(QObject *parent)
: QObject(parent)
{

View file

@ -94,6 +94,7 @@ public:
std::chrono::steady_clock::time_point targetPageflipTime() const;
std::chrono::nanoseconds refreshDuration() const;
std::chrono::nanoseconds predictedRenderTime() const;
private:
std::optional<RenderTimeSpan> queryRenderTime() const;
@ -101,6 +102,7 @@ private:
const QPointer<RenderLoop> m_loop;
const std::chrono::nanoseconds m_refreshDuration;
const std::chrono::steady_clock::time_point m_targetPageflipTime;
const std::chrono::nanoseconds m_predictedRenderTime;
std::vector<std::unique_ptr<PresentationFeedback>> m_feedbacks;
std::optional<ContentType> m_contentType;
PresentationMode m_presentationMode = PresentationMode::VSync;

View file

@ -93,14 +93,14 @@ void RenderLoopPrivate::notifyFrameCompleted(std::chrono::nanoseconds timestamp,
{
if (output && s_printDebugInfo && !m_debugOutput) {
m_debugOutput = std::fstream(qPrintable("kwin perf statistics " + output->name() + ".csv"), std::ios::out);
*m_debugOutput << "target pageflip timestamp,pageflip timestamp,render start,render end,safety margin,refresh duration,vrr,tearing\n";
*m_debugOutput << "target pageflip timestamp,pageflip timestamp,render start,render end,safety margin,refresh duration,vrr,tearing,predicted render time\n";
}
if (m_debugOutput) {
auto times = renderTime.value_or(RenderTimeSpan{});
const bool vrr = mode == PresentationMode::AdaptiveSync || mode == PresentationMode::AdaptiveAsync;
const bool tearing = mode == PresentationMode::Async || mode == PresentationMode::AdaptiveAsync;
*m_debugOutput << frame->targetPageflipTime().time_since_epoch().count() << "," << timestamp.count() << "," << times.start.time_since_epoch().count() << "," << times.end.time_since_epoch().count()
<< "," << safetyMargin.count() << "," << frame->refreshDuration().count() << "," << (vrr ? 1 : 0) << "," << (tearing ? 1 : 0) << "\n";
<< "," << safetyMargin.count() << "," << frame->refreshDuration().count() << "," << (vrr ? 1 : 0) << "," << (tearing ? 1 : 0) << "," << frame->predictedRenderTime().count() << "\n";
}
Q_ASSERT(pendingFrameCount > 0);
@ -253,6 +253,11 @@ void RenderLoop::setMaxPendingFrameCount(uint32_t maxCount)
d->maxPendingFrameCount = maxCount;
}
std::chrono::nanoseconds RenderLoop::predictedRenderTime() const
{
return d->renderJournal.result();
}
} // namespace KWin
#include "moc_renderloop.cpp"

View file

@ -95,6 +95,11 @@ public:
void setMaxPendingFrameCount(uint32_t maxCount);
/**
* Returns the expected time how long it is going to take to render the next frame.
*/
std::chrono::nanoseconds predictedRenderTime() const;
Q_SIGNALS:
/**
* This signal is emitted when the refresh rate of this RenderLoop has changed.