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"