From a4a2ee0428b80de0a13bb72e92c43f0b5c2230bd Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 19 Apr 2022 14:46:15 +0300 Subject: [PATCH] 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. --- src/backends/drm/drm_object_connector.cpp | 31 ++++---- src/backends/drm/drm_object_connector.h | 13 +--- src/backends/drm/drm_output.cpp | 54 ++++++------- src/backends/drm/drm_output.h | 2 +- src/backends/drm/drm_virtual_output.cpp | 10 +-- src/backends/drm/drm_virtual_output.h | 1 - src/backends/virtual/virtual_output.cpp | 11 +-- src/backends/wayland/wayland_output.cpp | 22 ++---- src/backends/x11/standalone/x11_output.cpp | 3 +- .../x11/standalone/x11placeholderoutput.cpp | 12 +-- .../x11/windowed/x11windowed_output.cpp | 9 +-- src/output.cpp | 78 +++++++++++-------- src/output.h | 53 +++++++------ src/waylandoutputdevicev2.cpp | 8 +- 14 files changed, 149 insertions(+), 158 deletions(-) diff --git a/src/backends/drm/drm_object_connector.cpp b/src/backends/drm/drm_object_connector.cpp index 299a29620e..81a9cb2fbf 100644 --- a/src/backends/drm/drm_object_connector.cpp +++ b/src/backends/drm/drm_object_connector.cpp @@ -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> DrmConnector::modes() const +QList> DrmConnector::modes() const { return m_modes; } diff --git a/src/backends/drm/drm_object_connector.h b/src/backends/drm/drm_object_connector.h index 01c4eacdad..2e4479a828 100644 --- a/src/backends/drm/drm_object_connector.h +++ b/src/backends/drm/drm_object_connector.h @@ -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> modes() const; + QList> modes() const; QSharedPointer findMode(const drmModeModeInfo &modeInfo) const; Output::SubPixel subpixel() const; @@ -114,7 +109,7 @@ private: DrmScopedPointer m_conn; Edid m_edid; QSize m_physicalSize = QSize(-1, -1); - QVector> m_modes; + QList> m_modes; uint32_t m_possibleCrtcs = 0; friend QDebug &operator<<(QDebug &s, const KWin::DrmConnector *obj); diff --git a/src/backends/drm/drm_output.cpp b/src/backends/drm/drm_output.cpp index 93859a9f46..5af27c1353 100644 --- a/src/backends/drm/drm_output.cpp +++ b/src/backends/drm/drm_output.cpp @@ -165,34 +165,16 @@ void DrmOutput::moveCursor() } } -QVector DrmOutput::getModes() const +QList> DrmOutput::getModes() const { - bool modeFound = false; - QVector 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> ret; + ret.reserve(drmModes.count()); + for (const QSharedPointer &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> modes = getModes(); + QSharedPointer 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> 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 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); diff --git a/src/backends/drm/drm_output.h b/src/backends/drm/drm_output.h index cc3309f5a2..43891e6c07 100644 --- a/src/backends/drm/drm_output.h +++ b/src/backends/drm/drm_output.h @@ -66,7 +66,7 @@ private: bool setDrmDpmsMode(DpmsMode mode); void setDpmsMode(DpmsMode mode) override; - QVector getModes() const; + QList> getModes() const; void updateCursor(); void moveCursor(); diff --git a/src/backends/drm/drm_virtual_output.cpp b/src/backends/drm/drm_virtual_output.cpp index 1e677b3d76..b7356efc13 100644 --- a/src/backends/drm/drm_virtual_output.cpp +++ b/src/backends/drm/drm_virtual_output.cpp @@ -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 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::create(size, 60000, OutputMode::Flag::Preferred); + setModesInternal({mode}, mode); + m_renderLoop->setRefreshRate(mode->refreshRate()); recreateSurface(); } diff --git a/src/backends/drm/drm_virtual_output.h b/src/backends/drm/drm_virtual_output.h index b42092673a..ef28b3f648 100644 --- a/src/backends/drm/drm_virtual_output.h +++ b/src/backends/drm/drm_virtual_output.h @@ -40,7 +40,6 @@ private: QSharedPointer m_layer; bool m_pageFlipPending = true; - int m_modeIndex = 0; SoftwareVsyncMonitor *m_vsyncMonitor; }; diff --git a/src/backends/virtual/virtual_output.cpp b/src/backends/virtual/virtual_output.cpp index 0427358da6..a9630de184 100644 --- a/src/backends/virtual/virtual_output.cpp +++ b/src/backends/virtual/virtual_output.cpp @@ -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::create(geo.size(), m_vsyncMonitor->refreshRate()); + setModesInternal({mode}, mode); moveTo(geo.topLeft()); } diff --git a/src/backends/wayland/wayland_output.cpp b/src/backends/wayland/wayland_output.cpp index e35dc5042a..f51e90dcba 100644 --- a/src/backends/wayland/wayland_output.cpp +++ b/src/backends/wayland/wayland_output.cpp @@ -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::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::create(pixelSize, s_refreshRate); + setModesInternal({mode}, mode); moveTo(logicalPosition); Q_EMIT m_backend->screensQueried(); diff --git a/src/backends/x11/standalone/x11_output.cpp b/src/backends/x11/standalone/x11_output.cpp index 968daf1fb0..2ab5020940 100644 --- a/src/backends/x11/standalone/x11_output.cpp +++ b/src/backends/x11/standalone/x11_output.cpp @@ -65,7 +65,8 @@ bool X11Output::usesSoftwareCursor() const void X11Output::setMode(const QSize &size, int refreshRate) { - setCurrentModeInternal(size, refreshRate); + auto mode = QSharedPointer::create(size, refreshRate); + setModesInternal({mode}, mode); } void X11Output::setPhysicalSize(const QSize &size) diff --git a/src/backends/x11/standalone/x11placeholderoutput.cpp b/src/backends/x11/standalone/x11placeholderoutput.cpp index 9d43318e25..e1c4361f5c 100644 --- a/src/backends/x11/standalone/x11placeholderoutput.cpp +++ b/src/backends/x11/standalone/x11placeholderoutput.cpp @@ -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::create(pixelSize, 60000); + setModesInternal({mode}, mode); } RenderLoop *X11PlaceholderOutput::renderLoop() const diff --git a/src/backends/x11/windowed/x11windowed_output.cpp b/src/backends/x11/windowed/x11windowed_output.cpp index e39f11b5ed..8b5d57268f 100644 --- a/src/backends/x11/windowed/x11windowed_output.cpp +++ b/src/backends/x11/windowed/x11windowed_output.cpp @@ -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::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()); diff --git a/src/output.cpp b/src/output.cpp index 664cef7990..1372aa1076 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -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::modes() const +QList> Output::modes() const { return m_modes; } -void Output::setModes(const QVector &modes) +QSharedPointer Output::currentMode() const { - if (m_modes != modes) { - m_modes = modes; + return m_currentMode; +} + +void Output::setModesInternal(const QList> &modes, const QSharedPointer ¤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 ¤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 &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 diff --git a/src/output.h b/src/output.h index 8f11acec0f..afad24a3b2 100644 --- a/src/output.h +++ b/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 modes() const; - void setModes(const QVector &modes); + QList> modes() const; + QSharedPointer 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 &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> &modes, const QSharedPointer ¤tMode); + void setCurrentModeInternal(const QSharedPointer ¤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 m_modes; + QList> m_modes; + QSharedPointer 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; diff --git a/src/waylandoutputdevicev2.cpp b/src/waylandoutputdevicev2.cpp index 1a02f89354..8bf7d768d2 100644 --- a/src/waylandoutputdevicev2.cpp +++ b/src/waylandoutputdevicev2.cpp @@ -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 &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);