/* SPDX-FileCopyrightText: 2021 Vlad Zahorodnii SPDX-License-Identifier: GPL-2.0-or-later */ #include "renderbackend.h" #include "renderloop_p.h" #include "scene/surfaceitem.h" #include "syncobjtimeline.h" #include #include #include #include namespace KWin { RenderTimeSpan RenderTimeSpan::operator|(const RenderTimeSpan &other) const { return RenderTimeSpan{ .start = std::min(start, other.start), .end = std::max(end, other.end), }; } CpuRenderTimeQuery::CpuRenderTimeQuery() : m_start(std::chrono::steady_clock::now()) { } void CpuRenderTimeQuery::end() { m_end = std::chrono::steady_clock::now(); } std::optional CpuRenderTimeQuery::query() { Q_ASSERT(m_end); return RenderTimeSpan{ .start = m_start, .end = *m_end, }; } OutputFrame::OutputFrame(RenderLoop *loop, std::chrono::nanoseconds refreshDuration) : m_loop(loop) , m_refreshDuration(refreshDuration) , m_targetPageflipTime(loop->nextPresentationTimestamp()) , m_predictedRenderTime(loop->predictedRenderTime()) { } OutputFrame::~OutputFrame() { Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread()); if (!m_presented && m_loop) { RenderLoopPrivate::get(m_loop)->notifyFrameDropped(); } } void OutputFrame::addFeedback(std::unique_ptr &&feedback) { m_feedbacks.push_back(std::move(feedback)); } std::optional OutputFrame::queryRenderTime() const { if (m_renderTimeQueries.empty()) { return RenderTimeSpan{}; } const auto first = m_renderTimeQueries.front()->query(); if (!first) { return std::nullopt; } RenderTimeSpan ret = *first; for (const auto &query : m_renderTimeQueries | std::views::drop(1)) { const auto opt = query->query(); if (!opt) { return std::nullopt; } ret = ret | *opt; } return ret; } void OutputFrame::presented(std::chrono::nanoseconds timestamp, PresentationMode mode) { Q_ASSERT(!m_presented); m_presented = true; const auto renderTime = queryRenderTime(); if (m_loop) { RenderLoopPrivate::get(m_loop)->notifyFrameCompleted(timestamp, renderTime, mode, this); } for (const auto &feedback : m_feedbacks) { feedback->presented(m_refreshDuration, timestamp, mode); } } void OutputFrame::setContentType(ContentType type) { m_contentType = type; } std::optional OutputFrame::contentType() const { return m_contentType; } void OutputFrame::setPresentationMode(PresentationMode mode) { m_presentationMode = mode; } PresentationMode OutputFrame::presentationMode() const { return m_presentationMode; } void OutputFrame::setDamage(const QRegion ®ion) { m_damage = region; } QRegion OutputFrame::damage() const { return m_damage; } void OutputFrame::addRenderTimeQuery(std::unique_ptr &&query) { m_renderTimeQueries.push_back(std::move(query)); } std::chrono::steady_clock::time_point OutputFrame::targetPageflipTime() const { return m_targetPageflipTime; } std::chrono::nanoseconds OutputFrame::refreshDuration() const { return m_refreshDuration; } std::chrono::nanoseconds OutputFrame::predictedRenderTime() const { return m_predictedRenderTime; } OutputLayer *RenderBackend::cursorLayer(Output *output) { return nullptr; } OverlayWindow *RenderBackend::overlayWindow() const { return nullptr; } bool RenderBackend::checkGraphicsReset() { return false; } DrmDevice *RenderBackend::drmDevice() const { return nullptr; } bool RenderBackend::testImportBuffer(GraphicsBuffer *buffer) { return false; } QHash> RenderBackend::supportedFormats() const { return QHash>{{DRM_FORMAT_XRGB8888, QList{DRM_FORMAT_MOD_LINEAR}}}; } std::unique_ptr RenderBackend::createSurfaceTextureX11(SurfacePixmapX11 *pixmap) { return nullptr; } std::unique_ptr RenderBackend::createSurfaceTextureWayland(SurfacePixmap *pixmap) { return nullptr; } void RenderBackend::repairPresentation(Output *output) { } } // namespace KWin #include "moc_renderbackend.cpp"