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 }