File indexing completed on 2024-11-10 04:56:30

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 "drm_backend.h"
0013 #include "drm_gpu.h"
0014 #include "drm_layer.h"
0015 #include "drm_render_backend.h"
0016 #include "utils/softwarevsyncmonitor.h"
0017 
0018 namespace KWin
0019 {
0020 
0021 DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize &size, qreal scale)
0022     : DrmAbstractOutput(gpu)
0023     , m_vsyncMonitor(SoftwareVsyncMonitor::create())
0024 {
0025     connect(m_vsyncMonitor.get(), &VsyncMonitor::vblankOccurred, this, &DrmVirtualOutput::vblank);
0026 
0027     auto mode = std::make_shared<OutputMode>(size, 60000, OutputMode::Flag::Preferred);
0028     m_renderLoop->setRefreshRate(mode->refreshRate());
0029 
0030     setInformation(Information{
0031         .name = QStringLiteral("Virtual-") + name,
0032         .physicalSize = size,
0033     });
0034 
0035     setState(State{
0036         .scale = scale,
0037         .modes = {mode},
0038         .currentMode = mode,
0039     });
0040 
0041     recreateSurface();
0042 }
0043 
0044 DrmVirtualOutput::~DrmVirtualOutput()
0045 {
0046 }
0047 
0048 bool DrmVirtualOutput::present(const std::shared_ptr<OutputFrame> &frame)
0049 {
0050     m_frame = frame;
0051     m_vsyncMonitor->arm();
0052     m_pageFlipPending = true;
0053     Q_EMIT outputChange(m_layer->currentDamage());
0054     return true;
0055 }
0056 
0057 void DrmVirtualOutput::vblank(std::chrono::nanoseconds timestamp)
0058 {
0059     if (m_pageFlipPending) {
0060         DrmAbstractOutput::pageFlipped(timestamp, PresentationMode::VSync);
0061     }
0062 }
0063 
0064 void DrmVirtualOutput::setDpmsMode(DpmsMode mode)
0065 {
0066     State next = m_state;
0067     next.dpmsMode = mode;
0068     setState(next);
0069 }
0070 
0071 DrmOutputLayer *DrmVirtualOutput::primaryLayer() const
0072 {
0073     return m_layer.get();
0074 }
0075 
0076 DrmOutputLayer *DrmVirtualOutput::cursorLayer() const
0077 {
0078     return nullptr;
0079 }
0080 
0081 void DrmVirtualOutput::recreateSurface()
0082 {
0083     m_layer = m_gpu->platform()->renderBackend()->createLayer(this);
0084 }
0085 
0086 }
0087 
0088 #include "moc_drm_virtual_output.cpp"