File indexing completed on 2025-04-20 10:57:37

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2018 Roman Gilg <subdiff@gmail.com>
0006     SPDX-FileCopyrightText: 2021 Xaver Hugl <xaver.hugl@gmail.com>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #include "drm_virtual_output.h"
0011 
0012 #include "core/renderloop_p.h"
0013 #include "drm_backend.h"
0014 #include "drm_gpu.h"
0015 #include "drm_layer.h"
0016 #include "drm_logging.h"
0017 #include "drm_render_backend.h"
0018 #include "softwarevsyncmonitor.h"
0019 
0020 namespace KWin
0021 {
0022 
0023 DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize &size, qreal scale)
0024     : DrmAbstractOutput(gpu)
0025     , m_vsyncMonitor(SoftwareVsyncMonitor::create())
0026 {
0027     connect(m_vsyncMonitor.get(), &VsyncMonitor::vblankOccurred, this, &DrmVirtualOutput::vblank);
0028 
0029     auto mode = std::make_shared<OutputMode>(size, 60000, OutputMode::Flag::Preferred);
0030     m_renderLoop->setRefreshRate(mode->refreshRate());
0031 
0032     setInformation(Information{
0033         .name = QStringLiteral("Virtual-") + name,
0034         .physicalSize = size,
0035     });
0036 
0037     setState(State{
0038         .scale = scale,
0039         .modes = {mode},
0040         .currentMode = mode,
0041     });
0042 
0043     recreateSurface();
0044 }
0045 
0046 DrmVirtualOutput::~DrmVirtualOutput()
0047 {
0048 }
0049 
0050 bool DrmVirtualOutput::present()
0051 {
0052     m_vsyncMonitor->arm();
0053     m_pageFlipPending = true;
0054     Q_EMIT outputChange(m_layer->currentDamage());
0055     return true;
0056 }
0057 
0058 void DrmVirtualOutput::vblank(std::chrono::nanoseconds timestamp)
0059 {
0060     if (m_pageFlipPending) {
0061         DrmAbstractOutput::pageFlipped(timestamp);
0062     }
0063 }
0064 
0065 void DrmVirtualOutput::setDpmsMode(DpmsMode mode)
0066 {
0067     State next = m_state;
0068     next.dpmsMode = mode;
0069     setState(next);
0070 }
0071 
0072 DrmOutputLayer *DrmVirtualOutput::primaryLayer() const
0073 {
0074     return m_layer.get();
0075 }
0076 
0077 void DrmVirtualOutput::recreateSurface()
0078 {
0079     m_layer = m_gpu->platform()->renderBackend()->createLayer(this);
0080 }
0081 
0082 }