Changeset View
Changeset View
Standalone View
Standalone View
plugins/platforms/drm/drm_output.cpp
Show First 20 Lines • Show All 231 Lines • ▼ Show 20 Line(s) | 220 | static QHash<int, QByteArray> s_connectorNames = { | |||
---|---|---|---|---|---|
232 | {DRM_MODE_CONNECTOR_HDMIA, QByteArrayLiteral("HDMI-A")}, | 232 | {DRM_MODE_CONNECTOR_HDMIA, QByteArrayLiteral("HDMI-A")}, | ||
233 | {DRM_MODE_CONNECTOR_HDMIB, QByteArrayLiteral("HDMI-B")}, | 233 | {DRM_MODE_CONNECTOR_HDMIB, QByteArrayLiteral("HDMI-B")}, | ||
234 | {DRM_MODE_CONNECTOR_TV, QByteArrayLiteral("TV")}, | 234 | {DRM_MODE_CONNECTOR_TV, QByteArrayLiteral("TV")}, | ||
235 | {DRM_MODE_CONNECTOR_eDP, QByteArrayLiteral("eDP")}, | 235 | {DRM_MODE_CONNECTOR_eDP, QByteArrayLiteral("eDP")}, | ||
236 | {DRM_MODE_CONNECTOR_VIRTUAL, QByteArrayLiteral("Virtual")}, | 236 | {DRM_MODE_CONNECTOR_VIRTUAL, QByteArrayLiteral("Virtual")}, | ||
237 | {DRM_MODE_CONNECTOR_DSI, QByteArrayLiteral("DSI")} | 237 | {DRM_MODE_CONNECTOR_DSI, QByteArrayLiteral("DSI")} | ||
238 | }; | 238 | }; | ||
239 | 239 | | |||
240 | namespace { | ||||
241 | quint64 refreshRateForMode(_drmModeModeInfo *m) | ||||
242 | { | ||||
243 | // Calculate higher precision (mHz) refresh rate | ||||
244 | // logic based on Weston, see compositor-drm.c | ||||
245 | quint64 refreshRate = (m->clock * 1000000LL / m->htotal + m->vtotal / 2) / m->vtotal; | ||||
246 | if (m->flags & DRM_MODE_FLAG_INTERLACE) { | ||||
247 | refreshRate *= 2; | ||||
248 | } | ||||
249 | if (m->flags & DRM_MODE_FLAG_DBLSCAN) { | ||||
250 | refreshRate /= 2; | ||||
251 | } | ||||
252 | if (m->vscan > 1) { | ||||
253 | refreshRate /= m->vscan; | ||||
254 | } | ||||
255 | return refreshRate; | ||||
256 | } | ||||
257 | } | ||||
240 | 258 | | |||
241 | bool DrmOutput::init(drmModeConnector *connector) | 259 | bool DrmOutput::init(drmModeConnector *connector) | ||
242 | { | 260 | { | ||
243 | initEdid(connector); | 261 | initEdid(connector); | ||
244 | initDpms(connector); | 262 | initDpms(connector); | ||
245 | initUuid(); | 263 | initUuid(); | ||
246 | if (m_backend->atomicModeSetting()) { | 264 | if (m_backend->atomicModeSetting()) { | ||
247 | if (!initPrimaryPlane()) { | 265 | if (!initPrimaryPlane()) { | ||
248 | return false; | 266 | return false; | ||
249 | } | 267 | } | ||
250 | } else if (!m_crtc->blank()) { | 268 | } else if (!m_crtc->blank()) { | ||
251 | return false; | 269 | return false; | ||
252 | } | 270 | } | ||
253 | 271 | | |||
254 | setDpms(DpmsMode::On); | 272 | setDpms(DpmsMode::On); | ||
255 | if (!m_waylandOutput.isNull()) { | 273 | if (!m_waylandOutput.isNull()) { | ||
davidedmundson: This method is coded so that init() can be called twice.
Either:
- that's pointless, and… | |||||
256 | delete m_waylandOutput.data(); | 274 | delete m_waylandOutput.data(); | ||
257 | m_waylandOutput.clear(); | 275 | m_waylandOutput.clear(); | ||
258 | } | 276 | } | ||
259 | m_waylandOutput = waylandServer()->display()->createOutput(); | 277 | m_waylandOutput = waylandServer()->display()->createOutput(); | ||
278 | connect(this, &DrmOutput::modeChanged, this, | ||||
279 | [this] { | ||||
280 | if (m_waylandOutput.isNull()) { | ||||
Every other setFooBar guards m_waylandOutput. It seems currently superfuous, but as soon as we code up enabledChanged to work it'll be needed. davidedmundson: Every other setFooBar guards m_waylandOutput.
It seems currently superfuous, but as soon as we… | |||||
281 | return; | ||||
282 | } | ||||
283 | m_waylandOutput->setCurrentMode(QSize(m_mode.hdisplay, m_mode.vdisplay), refreshRateForMode(&m_mode)); | ||||
284 | } | ||||
285 | ); | ||||
260 | if (!m_waylandOutputDevice.isNull()) { | 286 | if (!m_waylandOutputDevice.isNull()) { | ||
261 | delete m_waylandOutputDevice.data(); | 287 | delete m_waylandOutputDevice.data(); | ||
262 | m_waylandOutputDevice.clear(); | 288 | m_waylandOutputDevice.clear(); | ||
263 | } | 289 | } | ||
264 | m_waylandOutputDevice = waylandServer()->display()->createOutputDevice(); | 290 | m_waylandOutputDevice = waylandServer()->display()->createOutputDevice(); | ||
265 | m_waylandOutputDevice->setUuid(m_uuid); | 291 | m_waylandOutputDevice->setUuid(m_uuid); | ||
266 | 292 | | |||
267 | if (!m_edid.eisaId.isEmpty()) { | 293 | if (!m_edid.eisaId.isEmpty()) { | ||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Line(s) | 344 | if (isCurrentMode(m)) { | |||
319 | flags |= KWayland::Server::OutputInterface::ModeFlag::Current; | 345 | flags |= KWayland::Server::OutputInterface::ModeFlag::Current; | ||
320 | deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Current; | 346 | deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Current; | ||
321 | } | 347 | } | ||
322 | if (m->type & DRM_MODE_TYPE_PREFERRED) { | 348 | if (m->type & DRM_MODE_TYPE_PREFERRED) { | ||
323 | flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred; | 349 | flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred; | ||
324 | deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred; | 350 | deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred; | ||
325 | } | 351 | } | ||
326 | 352 | | |||
327 | // Calculate higher precision (mHz) refresh rate | 353 | const auto refreshRate = refreshRateForMode(m); | ||
328 | // logic based on Weston, see compositor-drm.c | | |||
329 | quint64 refreshRate = (m->clock * 1000000LL / m->htotal + m->vtotal / 2) / m->vtotal; | | |||
330 | if (m->flags & DRM_MODE_FLAG_INTERLACE) { | | |||
331 | refreshRate *= 2; | | |||
332 | } | | |||
333 | if (m->flags & DRM_MODE_FLAG_DBLSCAN) { | | |||
334 | refreshRate /= 2; | | |||
335 | } | | |||
336 | if (m->vscan > 1) { | | |||
337 | refreshRate /= m->vscan; | | |||
338 | } | | |||
339 | m_waylandOutput->addMode(QSize(m->hdisplay, m->vdisplay), flags, refreshRate); | 354 | m_waylandOutput->addMode(QSize(m->hdisplay, m->vdisplay), flags, refreshRate); | ||
340 | 355 | | |||
341 | KWayland::Server::OutputDeviceInterface::Mode mode; | 356 | KWayland::Server::OutputDeviceInterface::Mode mode; | ||
342 | mode.id = i; | 357 | mode.id = i; | ||
343 | mode.size = QSize(m->hdisplay, m->vdisplay); | 358 | mode.size = QSize(m->hdisplay, m->vdisplay); | ||
344 | mode.flags = deviceflags; | 359 | mode.flags = deviceflags; | ||
345 | mode.refreshRate = refreshRate; | 360 | mode.refreshRate = refreshRate; | ||
346 | qCDebug(KWIN_DRM) << "Adding mode: " << i << mode.size; | 361 | qCDebug(KWIN_DRM) << "Adding mode: " << i << mode.size; | ||
▲ Show 20 Lines • Show All 404 Lines • ▼ Show 20 Line(s) | 756 | { | |||
751 | if (m_changeset->enabledChanged()) { | 766 | if (m_changeset->enabledChanged()) { | ||
752 | qCDebug(KWIN_DRM) << "Setting enabled:"; | 767 | qCDebug(KWIN_DRM) << "Setting enabled:"; | ||
753 | m_waylandOutputDevice->setEnabled(m_changeset->enabled()); | 768 | m_waylandOutputDevice->setEnabled(m_changeset->enabled()); | ||
754 | } | 769 | } | ||
755 | if (m_changeset->modeChanged()) { | 770 | if (m_changeset->modeChanged()) { | ||
756 | qCDebug(KWIN_DRM) << "Setting new mode:" << m_changeset->mode(); | 771 | qCDebug(KWIN_DRM) << "Setting new mode:" << m_changeset->mode(); | ||
757 | m_waylandOutputDevice->setCurrentMode(m_changeset->mode()); | 772 | m_waylandOutputDevice->setCurrentMode(m_changeset->mode()); | ||
758 | updateMode(m_changeset->mode()); | 773 | updateMode(m_changeset->mode()); | ||
759 | // FIXME: implement for wl_output | | |||
760 | } | 774 | } | ||
761 | if (m_changeset->transformChanged()) { | 775 | if (m_changeset->transformChanged()) { | ||
762 | qCDebug(KWIN_DRM) << "Server setting transform: " << (int)(m_changeset->transform()); | 776 | qCDebug(KWIN_DRM) << "Server setting transform: " << (int)(m_changeset->transform()); | ||
763 | m_waylandOutputDevice->setTransform(m_changeset->transform()); | 777 | m_waylandOutputDevice->setTransform(m_changeset->transform()); | ||
764 | using KWayland::Server::OutputDeviceInterface; | 778 | using KWayland::Server::OutputDeviceInterface; | ||
765 | using KWayland::Server::OutputInterface; | 779 | using KWayland::Server::OutputInterface; | ||
766 | switch (m_changeset->transform()) { | 780 | switch (m_changeset->transform()) { | ||
767 | case OutputDeviceInterface::Transform::Normal: | 781 | case OutputDeviceInterface::Transform::Normal: | ||
▲ Show 20 Lines • Show All 418 Lines • Show Last 20 Lines |
This method is coded so that init() can be called twice.
Either:
(either through disconnecting or just putting the m_waylandOutput->setCurrentMode() call in ::updateMode