kwin/src/plugins/platforms/drm/drm_virtual_output.cpp
Aleix Pol 1330376220 screencast: Support the creation of virtual displays to cast
In case the user has just the one display but they don't want to show it
in their main workspace when sharing video, allow creating a virtual
display.
This also will allow using remote devices as support displays.
2021-10-25 19:43:41 +02:00

107 lines
2.8 KiB
C++

/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2018 Roman Gilg <subdiff@gmail.com>
SPDX-FileCopyrightText: 2021 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "drm_virtual_output.h"
#include "renderloop_p.h"
#include "softwarevsyncmonitor.h"
#include "drm_gpu.h"
#include "drm_backend.h"
#include "logging.h"
namespace KWin
{
static int s_serial = 0;
DrmVirtualOutput::DrmVirtualOutput(DrmGpu *gpu, const QSize &size)
: DrmVirtualOutput(QString::number(s_serial++), gpu, size)
{
}
DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize &size)
: DrmAbstractOutput(gpu)
, m_vsyncMonitor(SoftwareVsyncMonitor::create(this))
{
connect(m_vsyncMonitor, &VsyncMonitor::vblankOccurred, this, &DrmVirtualOutput::vblank);
setName("Virtual-" + name);
m_modeIndex = 0;
QVector<Mode> modes = {{size, 60000, AbstractWaylandOutput::ModeFlags(AbstractWaylandOutput::ModeFlag::Current) | AbstractWaylandOutput::ModeFlag::Preferred, 0}};
initialize(QLatin1String("model_") + name,
QLatin1String("manufacturer_") + name,
QLatin1String("eisa_") + name,
QLatin1String("serial_") + name,
modes[m_modeIndex].size,
modes,
QByteArray("EDID_") + name.toUtf8());
m_renderLoop->setRefreshRate(modes[m_modeIndex].refreshRate);
}
DrmVirtualOutput::~DrmVirtualOutput()
{
}
bool DrmVirtualOutput::present(const QSharedPointer<DrmBuffer> &buffer, QRegion damagedRegion)
{
Q_UNUSED(damagedRegion)
m_currentBuffer = buffer;
m_vsyncMonitor->arm();
m_pageFlipPending = true;
Q_EMIT outputChange(damagedRegion);
return true;
}
void DrmVirtualOutput::vblank(std::chrono::nanoseconds timestamp)
{
if (m_pageFlipPending) {
RenderLoopPrivate *renderLoopPrivate = RenderLoopPrivate::get(m_renderLoop);
renderLoopPrivate->notifyFrameCompleted(timestamp);
}
}
void DrmVirtualOutput::applyMode(int modeIndex)
{
Q_UNUSED(modeIndex)
}
void DrmVirtualOutput::updateMode(const QSize &size, uint32_t refreshRate)
{
Q_UNUSED(size)
Q_UNUSED(refreshRate)
}
void DrmVirtualOutput::setDpmsMode(DpmsMode mode)
{
setDpmsModeInternal(mode);
}
void DrmVirtualOutput::updateEnablement(bool enable)
{
gpu()->platform()->enableOutput(this, enable);
}
QSize DrmVirtualOutput::sourceSize() const
{
return pixelSize();
}
bool DrmVirtualOutput::isFormatSupported(uint32_t drmFormat) const
{
Q_UNUSED(drmFormat);
return true;
}
QVector<uint64_t> DrmVirtualOutput::supportedModifiers(uint32_t drmFormat) const
{
Q_UNUSED(drmFormat);
// empty list -> implicit modifiers are used / modifier is freely chosen by gbm
return {};
}
}