File indexing completed on 2024-11-10 04:56:33
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 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #include "virtual_output.h" 0010 #include "virtual_backend.h" 0011 0012 #include "compositor.h" 0013 #include "core/outputlayer.h" 0014 #include "core/renderbackend.h" 0015 #include "core/renderloop.h" 0016 #include "utils/softwarevsyncmonitor.h" 0017 0018 namespace KWin 0019 { 0020 0021 VirtualOutput::VirtualOutput(VirtualBackend *parent, bool internal) 0022 : Output(parent) 0023 , m_backend(parent) 0024 , m_renderLoop(std::make_unique<RenderLoop>(this)) 0025 , m_vsyncMonitor(SoftwareVsyncMonitor::create()) 0026 { 0027 connect(m_vsyncMonitor.get(), &VsyncMonitor::vblankOccurred, this, &VirtualOutput::vblank); 0028 0029 static int identifier = -1; 0030 m_identifier = ++identifier; 0031 setInformation(Information{ 0032 .name = QStringLiteral("Virtual-%1").arg(identifier), 0033 .internal = internal, 0034 }); 0035 } 0036 0037 VirtualOutput::~VirtualOutput() 0038 { 0039 } 0040 0041 RenderLoop *VirtualOutput::renderLoop() const 0042 { 0043 return m_renderLoop.get(); 0044 } 0045 0046 void VirtualOutput::present(const std::shared_ptr<OutputFrame> &frame) 0047 { 0048 m_frame = frame; 0049 m_vsyncMonitor->arm(); 0050 } 0051 0052 void VirtualOutput::init(const QPoint &logicalPosition, const QSize &pixelSize, qreal scale) 0053 { 0054 const int refreshRate = 60000; // TODO: Make the refresh rate configurable. 0055 m_renderLoop->setRefreshRate(refreshRate); 0056 m_vsyncMonitor->setRefreshRate(refreshRate); 0057 0058 auto mode = std::make_shared<OutputMode>(pixelSize, m_vsyncMonitor->refreshRate()); 0059 0060 setState(State{ 0061 .position = logicalPosition, 0062 .scale = scale, 0063 .modes = {mode}, 0064 .currentMode = mode, 0065 }); 0066 } 0067 0068 void VirtualOutput::updateEnabled(bool enabled) 0069 { 0070 State next = m_state; 0071 next.enabled = enabled; 0072 setState(next); 0073 } 0074 0075 void VirtualOutput::vblank(std::chrono::nanoseconds timestamp) 0076 { 0077 const auto primaryLayer = Compositor::self()->backend()->primaryLayer(this); 0078 m_frame->presented(std::chrono::nanoseconds(1'000'000'000'000 / refreshRate()), timestamp, primaryLayer->queryRenderTime(), PresentationMode::VSync); 0079 m_frame.reset(); 0080 } 0081 0082 } 0083 0084 #include "moc_virtual_output.cpp"