Refactor output mode abstractions
With this, the drm backend will be able to associate drmModeModeInfo with Output's modes, which can be useful if there are several modes with the same resolution and refresh rate but different flags.
This commit is contained in:
parent
6b4daeddc9
commit
a4a2ee0428
14 changed files with 149 additions and 158 deletions
|
@ -30,6 +30,11 @@ static bool checkIfEqual(const drmModeModeInfo *one, const drmModeModeInfo *two)
|
|||
return std::memcmp(one, two, sizeof(drmModeModeInfo)) == 0;
|
||||
}
|
||||
|
||||
static QSize resolutionForMode(const drmModeModeInfo *info)
|
||||
{
|
||||
return QSize(info->hdisplay, info->vdisplay);
|
||||
}
|
||||
|
||||
static quint64 refreshRateForMode(_drmModeModeInfo *m)
|
||||
{
|
||||
// Calculate higher precision (mHz) refresh rate
|
||||
|
@ -47,11 +52,19 @@ static quint64 refreshRateForMode(_drmModeModeInfo *m)
|
|||
return refreshRate;
|
||||
}
|
||||
|
||||
static OutputMode::Flags flagsForMode(const drmModeModeInfo *info)
|
||||
{
|
||||
OutputMode::Flags flags;
|
||||
if (info->type & DRM_MODE_TYPE_PREFERRED) {
|
||||
flags |= OutputMode::Flag::Preferred;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
DrmConnectorMode::DrmConnectorMode(DrmConnector *connector, drmModeModeInfo nativeMode)
|
||||
: m_connector(connector)
|
||||
: OutputMode(resolutionForMode(&nativeMode), refreshRateForMode(&nativeMode), flagsForMode(&nativeMode))
|
||||
, m_connector(connector)
|
||||
, m_nativeMode(nativeMode)
|
||||
, m_size(nativeMode.hdisplay, nativeMode.vdisplay)
|
||||
, m_refreshRate(refreshRateForMode(&nativeMode))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -68,16 +81,6 @@ drmModeModeInfo *DrmConnectorMode::nativeMode()
|
|||
return &m_nativeMode;
|
||||
}
|
||||
|
||||
QSize DrmConnectorMode::size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
uint32_t DrmConnectorMode::refreshRate() const
|
||||
{
|
||||
return m_refreshRate;
|
||||
}
|
||||
|
||||
uint32_t DrmConnectorMode::blobId()
|
||||
{
|
||||
if (!m_blobId) {
|
||||
|
@ -194,7 +197,7 @@ QSize DrmConnector::physicalSize() const
|
|||
return m_physicalSize;
|
||||
}
|
||||
|
||||
QVector<QSharedPointer<DrmConnectorMode>> DrmConnector::modes() const
|
||||
QList<QSharedPointer<DrmConnectorMode>> DrmConnector::modes() const
|
||||
{
|
||||
return m_modes;
|
||||
}
|
||||
|
|
|
@ -29,25 +29,20 @@ class DrmCrtc;
|
|||
/**
|
||||
* The DrmConnectorMode class represents a native mode and the associated blob.
|
||||
*/
|
||||
class DrmConnectorMode
|
||||
class DrmConnectorMode : public OutputMode
|
||||
{
|
||||
public:
|
||||
DrmConnectorMode(DrmConnector *connector, drmModeModeInfo nativeMode);
|
||||
~DrmConnectorMode();
|
||||
~DrmConnectorMode() override;
|
||||
|
||||
uint32_t blobId();
|
||||
|
||||
drmModeModeInfo *nativeMode();
|
||||
QSize size() const;
|
||||
uint32_t refreshRate() const;
|
||||
|
||||
bool operator==(const DrmConnectorMode &otherMode);
|
||||
|
||||
private:
|
||||
DrmConnector *m_connector;
|
||||
drmModeModeInfo m_nativeMode;
|
||||
QSize m_size;
|
||||
uint32_t m_refreshRate;
|
||||
uint32_t m_blobId = 0;
|
||||
};
|
||||
|
||||
|
@ -98,7 +93,7 @@ public:
|
|||
QString modelName() const;
|
||||
QSize physicalSize() const;
|
||||
|
||||
QVector<QSharedPointer<DrmConnectorMode>> modes() const;
|
||||
QList<QSharedPointer<DrmConnectorMode>> modes() const;
|
||||
QSharedPointer<DrmConnectorMode> findMode(const drmModeModeInfo &modeInfo) const;
|
||||
|
||||
Output::SubPixel subpixel() const;
|
||||
|
@ -114,7 +109,7 @@ private:
|
|||
DrmScopedPointer<drmModeConnector> m_conn;
|
||||
Edid m_edid;
|
||||
QSize m_physicalSize = QSize(-1, -1);
|
||||
QVector<QSharedPointer<DrmConnectorMode>> m_modes;
|
||||
QList<QSharedPointer<DrmConnectorMode>> m_modes;
|
||||
uint32_t m_possibleCrtcs = 0;
|
||||
|
||||
friend QDebug &operator<<(QDebug &s, const KWin::DrmConnector *obj);
|
||||
|
|
|
@ -165,34 +165,16 @@ void DrmOutput::moveCursor()
|
|||
}
|
||||
}
|
||||
|
||||
QVector<Output::Mode> DrmOutput::getModes() const
|
||||
QList<QSharedPointer<OutputMode>> DrmOutput::getModes() const
|
||||
{
|
||||
bool modeFound = false;
|
||||
QVector<Mode> modes;
|
||||
const auto modelist = m_pipeline->connector()->modes();
|
||||
const auto drmModes = m_pipeline->connector()->modes();
|
||||
|
||||
modes.reserve(modelist.count());
|
||||
for (int i = 0; i < modelist.count(); ++i) {
|
||||
Mode mode;
|
||||
// compare the actual mode objects, not the pointers!
|
||||
if (*modelist[i] == *m_pipeline->pending.mode) {
|
||||
mode.flags |= ModeFlag::Current;
|
||||
modeFound = true;
|
||||
}
|
||||
if (modelist[i]->nativeMode()->type & DRM_MODE_TYPE_PREFERRED) {
|
||||
mode.flags |= ModeFlag::Preferred;
|
||||
}
|
||||
|
||||
mode.id = i;
|
||||
mode.size = modelist[i]->size();
|
||||
mode.refreshRate = modelist[i]->refreshRate();
|
||||
modes << mode;
|
||||
QList<QSharedPointer<OutputMode>> ret;
|
||||
ret.reserve(drmModes.count());
|
||||
for (const QSharedPointer<DrmConnectorMode> &drmMode : drmModes) {
|
||||
ret.append(drmMode);
|
||||
}
|
||||
if (!modeFound) {
|
||||
// select first mode by default
|
||||
modes[0].flags |= ModeFlag::Current;
|
||||
}
|
||||
return modes;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DrmOutput::initOutputDevice()
|
||||
|
@ -201,7 +183,14 @@ void DrmOutput::initOutputDevice()
|
|||
setName(conn->connectorName());
|
||||
initialize(conn->modelName(), conn->edid()->manufacturerString(),
|
||||
conn->edid()->eisaId(), conn->edid()->serialNumber(),
|
||||
conn->physicalSize(), getModes(), conn->edid()->raw());
|
||||
conn->physicalSize(), conn->edid()->raw());
|
||||
|
||||
const QList<QSharedPointer<OutputMode>> modes = getModes();
|
||||
QSharedPointer<OutputMode> currentMode = m_pipeline->pending.mode;
|
||||
if (!currentMode) {
|
||||
currentMode = modes.constFirst();
|
||||
}
|
||||
setModesInternal(modes, currentMode);
|
||||
}
|
||||
|
||||
void DrmOutput::updateEnablement(bool enable)
|
||||
|
@ -290,7 +279,8 @@ DrmPlane::Transformations outputToPlaneTransform(DrmOutput::Transform transform)
|
|||
|
||||
void DrmOutput::updateModes()
|
||||
{
|
||||
setModes(getModes());
|
||||
const QList<QSharedPointer<OutputMode>> modes = getModes();
|
||||
|
||||
if (m_pipeline->pending.crtc) {
|
||||
const auto currentMode = m_pipeline->connector()->findMode(m_pipeline->pending.crtc->queryCurrentMode());
|
||||
if (currentMode != m_pipeline->pending.mode) {
|
||||
|
@ -298,7 +288,6 @@ void DrmOutput::updateModes()
|
|||
m_pipeline->pending.mode = currentMode ? currentMode : m_pipeline->connector()->modes().constFirst();
|
||||
if (m_gpu->testPendingConfiguration()) {
|
||||
m_pipeline->applyPendingChanges();
|
||||
setCurrentModeInternal(m_pipeline->pending.mode->size(), m_pipeline->pending.mode->refreshRate());
|
||||
m_renderLoop->setRefreshRate(m_pipeline->pending.mode->refreshRate());
|
||||
} else {
|
||||
qCWarning(KWIN_DRM) << "Setting changed mode failed!";
|
||||
|
@ -306,6 +295,13 @@ void DrmOutput::updateModes()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSharedPointer<OutputMode> currentMode = m_pipeline->pending.mode;
|
||||
if (!currentMode) {
|
||||
currentMode = modes.constFirst();
|
||||
}
|
||||
|
||||
setModesInternal(modes, currentMode);
|
||||
}
|
||||
|
||||
bool DrmOutput::present()
|
||||
|
@ -384,7 +380,7 @@ void DrmOutput::applyQueuedChanges(const OutputConfiguration &config)
|
|||
setTransformInternal(props->transform);
|
||||
|
||||
const auto &mode = m_pipeline->pending.mode;
|
||||
setCurrentModeInternal(mode->size(), mode->refreshRate());
|
||||
setCurrentModeInternal(mode);
|
||||
m_renderLoop->setRefreshRate(mode->refreshRate());
|
||||
setOverscanInternal(m_pipeline->pending.overscan);
|
||||
setRgbRangeInternal(m_pipeline->pending.rgbRange);
|
||||
|
|
|
@ -66,7 +66,7 @@ private:
|
|||
bool setDrmDpmsMode(DpmsMode mode);
|
||||
void setDpmsMode(DpmsMode mode) override;
|
||||
|
||||
QVector<Output::Mode> getModes() const;
|
||||
QList<QSharedPointer<OutputMode>> getModes() const;
|
||||
|
||||
void updateCursor();
|
||||
void moveCursor();
|
||||
|
|
|
@ -33,16 +33,16 @@ DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize
|
|||
connect(m_vsyncMonitor, &VsyncMonitor::vblankOccurred, this, &DrmVirtualOutput::vblank);
|
||||
|
||||
setName("Virtual-" + name);
|
||||
m_modeIndex = 0;
|
||||
QVector<Mode> modes = {{size, 60000, Output::ModeFlags(Output::ModeFlag::Current) | Output::ModeFlag::Preferred, 0}};
|
||||
initialize(QLatin1String("model_") + name,
|
||||
QLatin1String("manufacturer_") + name,
|
||||
QLatin1String("eisa_") + name,
|
||||
QLatin1String("serial_") + name,
|
||||
modes[m_modeIndex].size,
|
||||
modes,
|
||||
size,
|
||||
QByteArray("EDID_") + name.toUtf8());
|
||||
m_renderLoop->setRefreshRate(modes[m_modeIndex].refreshRate);
|
||||
|
||||
auto mode = QSharedPointer<OutputMode>::create(size, 60000, OutputMode::Flag::Preferred);
|
||||
setModesInternal({mode}, mode);
|
||||
m_renderLoop->setRefreshRate(mode->refreshRate());
|
||||
|
||||
recreateSurface();
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ private:
|
|||
|
||||
QSharedPointer<DrmOutputLayer> m_layer;
|
||||
bool m_pageFlipPending = true;
|
||||
int m_modeIndex = 0;
|
||||
|
||||
SoftwareVsyncMonitor *m_vsyncMonitor;
|
||||
};
|
||||
|
|
|
@ -48,22 +48,19 @@ void VirtualOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)
|
|||
m_renderLoop->setRefreshRate(refreshRate);
|
||||
m_vsyncMonitor->setRefreshRate(refreshRate);
|
||||
|
||||
Mode mode;
|
||||
mode.id = 0;
|
||||
mode.size = pixelSize;
|
||||
mode.flags = ModeFlag::Current;
|
||||
mode.refreshRate = refreshRate;
|
||||
initialize(QByteArray("model_").append(QByteArray::number(m_identifier)),
|
||||
QByteArray("manufacturer_").append(QByteArray::number(m_identifier)),
|
||||
QByteArray("eisa_").append(QByteArray::number(m_identifier)),
|
||||
QByteArray("serial_").append(QByteArray::number(m_identifier)),
|
||||
pixelSize, {mode}, QByteArray("EDID_").append(QByteArray::number(m_identifier)));
|
||||
pixelSize, QByteArray("EDID_").append(QByteArray::number(m_identifier)));
|
||||
|
||||
setGeometry(QRect(logicalPosition, pixelSize));
|
||||
}
|
||||
|
||||
void VirtualOutput::setGeometry(const QRect &geo)
|
||||
{
|
||||
// TODO: set mode to have updated pixelSize
|
||||
auto mode = QSharedPointer<OutputMode>::create(geo.size(), m_vsyncMonitor->refreshRate());
|
||||
setModesInternal({mode}, mode);
|
||||
moveTo(geo.topLeft());
|
||||
}
|
||||
|
||||
|
|
|
@ -61,32 +61,20 @@ void WaylandOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)
|
|||
{
|
||||
m_renderLoop->setRefreshRate(s_refreshRate);
|
||||
|
||||
const Mode mode{
|
||||
.size = pixelSize,
|
||||
.refreshRate = s_refreshRate,
|
||||
.flags = ModeFlag::Current,
|
||||
.id = 0,
|
||||
};
|
||||
auto mode = QSharedPointer<OutputMode>::create(pixelSize, s_refreshRate);
|
||||
setModesInternal({mode}, mode);
|
||||
|
||||
static uint i = 0;
|
||||
initialize(QStringLiteral("model_%1").arg(i++), "manufacturer_TODO", "eisa_TODO", "serial_TODO", pixelSize, {mode}, {});
|
||||
initialize(QStringLiteral("model_%1").arg(i++), "manufacturer_TODO", "eisa_TODO", "serial_TODO", pixelSize, {});
|
||||
|
||||
moveTo(logicalPosition);
|
||||
setCurrentModeInternal(mode.size, mode.refreshRate);
|
||||
setScale(backend()->initialOutputScale());
|
||||
}
|
||||
|
||||
void WaylandOutput::setGeometry(const QPoint &logicalPosition, const QSize &pixelSize)
|
||||
{
|
||||
const Mode mode{
|
||||
.size = pixelSize,
|
||||
.refreshRate = s_refreshRate,
|
||||
.flags = ModeFlag::Current,
|
||||
.id = 0,
|
||||
};
|
||||
|
||||
setModes({mode});
|
||||
setCurrentModeInternal(mode.size, mode.refreshRate);
|
||||
auto mode = QSharedPointer<OutputMode>::create(pixelSize, s_refreshRate);
|
||||
setModesInternal({mode}, mode);
|
||||
|
||||
moveTo(logicalPosition);
|
||||
Q_EMIT m_backend->screensQueried();
|
||||
|
|
|
@ -65,7 +65,8 @@ bool X11Output::usesSoftwareCursor() const
|
|||
|
||||
void X11Output::setMode(const QSize &size, int refreshRate)
|
||||
{
|
||||
setCurrentModeInternal(size, refreshRate);
|
||||
auto mode = QSharedPointer<OutputMode>::create(size, refreshRate);
|
||||
setModesInternal({mode}, mode);
|
||||
}
|
||||
|
||||
void X11Output::setPhysicalSize(const QSize &size)
|
||||
|
|
|
@ -20,20 +20,16 @@ X11PlaceholderOutput::X11PlaceholderOutput(RenderLoop *loop, QObject *parent)
|
|||
pixelSize = QSize(screen->width_in_pixels, screen->height_in_pixels);
|
||||
}
|
||||
|
||||
const Mode mode{
|
||||
.size = pixelSize,
|
||||
.refreshRate = 60000,
|
||||
.flags = ModeFlag::Current,
|
||||
.id = 0,
|
||||
};
|
||||
|
||||
const QByteArray model = QByteArrayLiteral("kwin");
|
||||
const QByteArray manufacturer = QByteArrayLiteral("xorg");
|
||||
const QByteArray eisaId;
|
||||
const QByteArray serial;
|
||||
|
||||
initialize(model, manufacturer, eisaId, serial, pixelSize, {mode}, QByteArray());
|
||||
initialize(model, manufacturer, eisaId, serial, pixelSize, QByteArray());
|
||||
setName(QStringLiteral("Placeholder-0"));
|
||||
|
||||
auto mode = QSharedPointer<OutputMode>::create(pixelSize, 60000);
|
||||
setModesInternal({mode}, mode);
|
||||
}
|
||||
|
||||
RenderLoop *X11PlaceholderOutput::renderLoop() const
|
||||
|
|
|
@ -64,16 +64,13 @@ void X11WindowedOutput::init(const QPoint &logicalPosition, const QSize &pixelSi
|
|||
m_renderLoop->setRefreshRate(refreshRate);
|
||||
m_vsyncMonitor->setRefreshRate(refreshRate);
|
||||
|
||||
Mode mode;
|
||||
mode.id = 0;
|
||||
mode.size = pixelSize;
|
||||
mode.flags = ModeFlag::Current;
|
||||
mode.refreshRate = refreshRate;
|
||||
auto mode = QSharedPointer<OutputMode>::create(pixelSize, refreshRate);
|
||||
setModesInternal({mode}, mode);
|
||||
|
||||
// Physicial size must be adjusted, such that QPA calculates correct sizes of
|
||||
// internal elements.
|
||||
const QSize physicalSize = pixelSize / 96.0 * 25.4 / m_backend->initialOutputScale();
|
||||
initialize("model_TODO", "manufacturer_TODO", "eisa_TODO", "serial_TODO", physicalSize, {mode}, {});
|
||||
initialize("model_TODO", "manufacturer_TODO", "eisa_TODO", "serial_TODO", physicalSize, {});
|
||||
setGeometry(logicalPosition, pixelSize);
|
||||
setScale(m_backend->initialOutputScale());
|
||||
|
||||
|
|
|
@ -38,6 +38,28 @@ QDebug operator<<(QDebug debug, const Output *output)
|
|||
return debug;
|
||||
}
|
||||
|
||||
OutputMode::OutputMode(const QSize &size, int refreshRate, Flags flags)
|
||||
: m_size(size)
|
||||
, m_refreshRate(refreshRate)
|
||||
, m_flags(flags)
|
||||
{
|
||||
}
|
||||
|
||||
QSize OutputMode::size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
int OutputMode::refreshRate() const
|
||||
{
|
||||
return m_refreshRate;
|
||||
}
|
||||
|
||||
OutputMode::Flags OutputMode::flags() const
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
|
||||
Output::Output(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
|
@ -157,7 +179,7 @@ QSize Output::physicalSize() const
|
|||
|
||||
int Output::refreshRate() const
|
||||
{
|
||||
return m_refreshRate;
|
||||
return m_currentMode->refreshRate();
|
||||
}
|
||||
|
||||
void Output::moveTo(const QPoint &pos)
|
||||
|
@ -170,12 +192,12 @@ void Output::moveTo(const QPoint &pos)
|
|||
|
||||
QSize Output::modeSize() const
|
||||
{
|
||||
return m_modeSize;
|
||||
return m_currentMode->size();
|
||||
}
|
||||
|
||||
QSize Output::pixelSize() const
|
||||
{
|
||||
return orientateSize(m_modeSize);
|
||||
return orientateSize(m_currentMode->size());
|
||||
}
|
||||
|
||||
QByteArray Output::edid() const
|
||||
|
@ -183,22 +205,30 @@ QByteArray Output::edid() const
|
|||
return m_edid;
|
||||
}
|
||||
|
||||
bool Output::Mode::operator==(const Mode &other) const
|
||||
{
|
||||
return id == other.id && other.flags == flags && size == other.size && refreshRate == other.refreshRate;
|
||||
}
|
||||
|
||||
QVector<Output::Mode> Output::modes() const
|
||||
QList<QSharedPointer<OutputMode>> Output::modes() const
|
||||
{
|
||||
return m_modes;
|
||||
}
|
||||
|
||||
void Output::setModes(const QVector<Mode> &modes)
|
||||
QSharedPointer<OutputMode> Output::currentMode() const
|
||||
{
|
||||
if (m_modes != modes) {
|
||||
m_modes = modes;
|
||||
return m_currentMode;
|
||||
}
|
||||
|
||||
void Output::setModesInternal(const QList<QSharedPointer<OutputMode>> &modes, const QSharedPointer<OutputMode> ¤tMode)
|
||||
{
|
||||
const auto oldModes = m_modes;
|
||||
const auto oldCurrentMode = m_currentMode;
|
||||
|
||||
m_modes = modes;
|
||||
m_currentMode = currentMode;
|
||||
|
||||
if (m_modes != oldModes) {
|
||||
Q_EMIT modesChanged();
|
||||
}
|
||||
if (m_currentMode != oldCurrentMode) {
|
||||
Q_EMIT currentModeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Output::SubPixel Output::subPixel() const
|
||||
|
@ -245,17 +275,13 @@ QString Output::description() const
|
|||
return m_manufacturer + ' ' + m_model;
|
||||
}
|
||||
|
||||
void Output::setCurrentModeInternal(const QSize &size, int refreshRate)
|
||||
void Output::setCurrentModeInternal(const QSharedPointer<OutputMode> ¤tMode)
|
||||
{
|
||||
const bool sizeChanged = m_modeSize != size;
|
||||
if (sizeChanged || m_refreshRate != refreshRate) {
|
||||
m_modeSize = size;
|
||||
m_refreshRate = refreshRate;
|
||||
if (m_currentMode != currentMode) {
|
||||
m_currentMode = currentMode;
|
||||
|
||||
Q_EMIT currentModeChanged();
|
||||
if (sizeChanged) {
|
||||
Q_EMIT geometryChanged();
|
||||
}
|
||||
Q_EMIT geometryChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,8 +297,7 @@ static QUuid generateOutputId(const QString &eisaId, const QString &model,
|
|||
|
||||
void Output::initialize(const QString &model, const QString &manufacturer,
|
||||
const QString &eisaId, const QString &serialNumber,
|
||||
const QSize &physicalSize,
|
||||
const QVector<Mode> &modes, const QByteArray &edid)
|
||||
const QSize &physicalSize, const QByteArray &edid)
|
||||
{
|
||||
m_serialNumber = serialNumber;
|
||||
m_eisaId = eisaId;
|
||||
|
@ -280,16 +305,7 @@ void Output::initialize(const QString &model, const QString &manufacturer,
|
|||
m_model = model;
|
||||
m_physicalSize = physicalSize;
|
||||
m_edid = edid;
|
||||
m_modes = modes;
|
||||
m_uuid = generateOutputId(m_eisaId, m_model, m_serialNumber, m_name);
|
||||
|
||||
for (const Mode &mode : modes) {
|
||||
if (mode.flags & ModeFlag::Current) {
|
||||
m_modeSize = mode.size;
|
||||
m_refreshRate = mode.refreshRate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSize Output::orientateSize(const QSize &size) const
|
||||
|
|
53
src/output.h
53
src/output.h
|
@ -29,6 +29,27 @@ class RenderLoop;
|
|||
class OutputConfiguration;
|
||||
class ColorTransformation;
|
||||
|
||||
class KWIN_EXPORT OutputMode
|
||||
{
|
||||
public:
|
||||
enum class Flag : uint {
|
||||
Preferred = 0x1,
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
OutputMode(const QSize &size, int refreshRate, Flags flags = {});
|
||||
virtual ~OutputMode() = default;
|
||||
|
||||
QSize size() const;
|
||||
int refreshRate() const;
|
||||
Flags flags() const;
|
||||
|
||||
private:
|
||||
const QSize m_size;
|
||||
const int m_refreshRate;
|
||||
const Flags m_flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic output representation.
|
||||
*/
|
||||
|
@ -37,23 +58,6 @@ class KWIN_EXPORT Output : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class ModeFlag : uint {
|
||||
Current = 0x1,
|
||||
Preferred = 0x2,
|
||||
};
|
||||
Q_DECLARE_FLAGS(ModeFlags, ModeFlag)
|
||||
Q_ENUM(ModeFlag)
|
||||
|
||||
struct Mode
|
||||
{
|
||||
QSize size;
|
||||
int refreshRate;
|
||||
ModeFlags flags;
|
||||
int id;
|
||||
|
||||
inline bool operator==(const Mode &other) const;
|
||||
};
|
||||
|
||||
enum class DpmsMode {
|
||||
On,
|
||||
Standby,
|
||||
|
@ -218,8 +222,8 @@ public:
|
|||
QString description() const;
|
||||
Capabilities capabilities() const;
|
||||
QByteArray edid() const;
|
||||
QVector<Mode> modes() const;
|
||||
void setModes(const QVector<Mode> &modes);
|
||||
QList<QSharedPointer<OutputMode>> modes() const;
|
||||
QSharedPointer<OutputMode> currentMode() const;
|
||||
DpmsMode dpmsMode() const;
|
||||
virtual void setDpmsMode(DpmsMode mode);
|
||||
|
||||
|
@ -295,8 +299,7 @@ Q_SIGNALS:
|
|||
protected:
|
||||
void initialize(const QString &model, const QString &manufacturer,
|
||||
const QString &eisaId, const QString &serialNumber,
|
||||
const QSize &physicalSize,
|
||||
const QVector<Mode> &modes, const QByteArray &edid);
|
||||
const QSize &physicalSize, const QByteArray &edid);
|
||||
|
||||
void setName(const QString &name)
|
||||
{
|
||||
|
@ -312,7 +315,8 @@ protected:
|
|||
Q_UNUSED(enable);
|
||||
}
|
||||
|
||||
void setCurrentModeInternal(const QSize &size, int refreshRate);
|
||||
void setModesInternal(const QList<QSharedPointer<OutputMode>> &modes, const QSharedPointer<OutputMode> ¤tMode);
|
||||
void setCurrentModeInternal(const QSharedPointer<OutputMode> ¤tMode);
|
||||
void setTransformInternal(Transform transform);
|
||||
void setDpmsModeInternal(DpmsMode dpmsMode);
|
||||
void setCapabilityInternal(Capability capability, bool on = true);
|
||||
|
@ -334,17 +338,16 @@ private:
|
|||
QString m_model;
|
||||
QString m_serialNumber;
|
||||
QUuid m_uuid;
|
||||
QSize m_modeSize;
|
||||
QSize m_physicalSize;
|
||||
QPoint m_position;
|
||||
qreal m_scale = 1;
|
||||
Capabilities m_capabilities;
|
||||
Transform m_transform = Transform::Normal;
|
||||
QByteArray m_edid;
|
||||
QVector<Mode> m_modes;
|
||||
QList<QSharedPointer<OutputMode>> m_modes;
|
||||
QSharedPointer<OutputMode> m_currentMode;
|
||||
DpmsMode m_dpmsMode = DpmsMode::On;
|
||||
SubPixel m_subPixel = SubPixel::Unknown;
|
||||
int m_refreshRate = -1;
|
||||
bool m_isEnabled = true;
|
||||
bool m_internal = false;
|
||||
bool m_isPlaceholder = false;
|
||||
|
|
|
@ -100,17 +100,17 @@ void WaylandOutputDevice::updateModes(Output *output)
|
|||
|
||||
const auto modes = output->modes();
|
||||
deviceModes.reserve(modes.size());
|
||||
for (const Output::Mode &mode : modes) {
|
||||
for (const QSharedPointer<OutputMode> &mode : modes) {
|
||||
OutputDeviceModeV2Interface::ModeFlags flags;
|
||||
|
||||
if (mode.flags & Output::ModeFlag::Current) {
|
||||
if (output->currentMode() == mode) {
|
||||
flags |= OutputDeviceModeV2Interface::ModeFlag::Current;
|
||||
}
|
||||
if (mode.flags & Output::ModeFlag::Preferred) {
|
||||
if (mode->flags() & OutputMode::Flag::Preferred) {
|
||||
flags |= OutputDeviceModeV2Interface::ModeFlag::Preferred;
|
||||
}
|
||||
|
||||
OutputDeviceModeV2Interface *deviceMode = new OutputDeviceModeV2Interface(mode.size, mode.refreshRate, flags);
|
||||
OutputDeviceModeV2Interface *deviceMode = new OutputDeviceModeV2Interface(mode->size(), mode->refreshRate(), flags);
|
||||
deviceModes << deviceMode;
|
||||
}
|
||||
m_outputDeviceV2->setModes(deviceModes);
|
||||
|
|
Loading…
Reference in a new issue