Changeset View
Changeset View
Standalone View
Standalone View
plugins/platforms/drm/drm_output.cpp
Show All 30 Lines | |||||
31 | #include "main.h" | 31 | #include "main.h" | ||
32 | #include "orientation_sensor.h" | 32 | #include "orientation_sensor.h" | ||
33 | #include "screens_drm.h" | 33 | #include "screens_drm.h" | ||
34 | #include "wayland_server.h" | 34 | #include "wayland_server.h" | ||
35 | // KWayland | 35 | // KWayland | ||
36 | #include <KWayland/Server/display.h> | 36 | #include <KWayland/Server/display.h> | ||
37 | #include <KWayland/Server/output_interface.h> | 37 | #include <KWayland/Server/output_interface.h> | ||
38 | #include <KWayland/Server/outputchangeset.h> | 38 | #include <KWayland/Server/outputchangeset.h> | ||
39 | #include <KWayland/Server/outputdevice_interface.h> | | |||
40 | #include <KWayland/Server/outputmanagement_interface.h> | 39 | #include <KWayland/Server/outputmanagement_interface.h> | ||
41 | #include <KWayland/Server/outputconfiguration_interface.h> | 40 | #include <KWayland/Server/outputconfiguration_interface.h> | ||
42 | #include <KWayland/Server/xdgoutput_interface.h> | 41 | #include <KWayland/Server/xdgoutput_interface.h> | ||
43 | // KF5 | 42 | // KF5 | ||
44 | #include <KConfigGroup> | 43 | #include <KConfigGroup> | ||
45 | #include <KLocalizedString> | 44 | #include <KLocalizedString> | ||
46 | #include <KSharedConfig> | 45 | #include <KSharedConfig> | ||
47 | // Qt | 46 | // Qt | ||
48 | #include <QMatrix4x4> | 47 | #include <QMatrix4x4> | ||
49 | #include <QCryptographicHash> | 48 | #include <QCryptographicHash> | ||
50 | #include <QPainter> | 49 | #include <QPainter> | ||
51 | // drm | 50 | // drm | ||
52 | #include <xf86drm.h> | 51 | #include <xf86drm.h> | ||
53 | #include <xf86drmMode.h> | 52 | #include <xf86drmMode.h> | ||
54 | #include <libdrm/drm_mode.h> | 53 | #include <libdrm/drm_mode.h> | ||
55 | 54 | | |||
56 | #include <cmath> | | |||
57 | | ||||
58 | namespace KWin | 55 | namespace KWin | ||
59 | { | 56 | { | ||
60 | 57 | | |||
61 | DrmOutput::DrmOutput(DrmBackend *backend) | 58 | DrmOutput::DrmOutput(DrmBackend *backend) | ||
62 | : QObject() | 59 | : AbstractOutput(backend) | ||
63 | , m_backend(backend) | 60 | , m_backend(backend) | ||
64 | { | 61 | { | ||
65 | } | 62 | } | ||
66 | 63 | | |||
67 | DrmOutput::~DrmOutput() | 64 | DrmOutput::~DrmOutput() | ||
68 | { | 65 | { | ||
69 | Q_ASSERT(!m_pageFlipPending); | 66 | Q_ASSERT(!m_pageFlipPending); | ||
70 | if (!m_deleted) { | 67 | if (!m_deleted) { | ||
Show All 14 Lines | 78 | if (m_primaryPlane) { | |||
85 | if (m_backend->deleteBufferAfterPageFlip()) { | 82 | if (m_backend->deleteBufferAfterPageFlip()) { | ||
86 | delete m_primaryPlane->current(); | 83 | delete m_primaryPlane->current(); | ||
87 | } | 84 | } | ||
88 | m_primaryPlane->setCurrent(nullptr); | 85 | m_primaryPlane->setCurrent(nullptr); | ||
89 | } | 86 | } | ||
90 | 87 | | |||
91 | m_crtc->setOutput(nullptr); | 88 | m_crtc->setOutput(nullptr); | ||
92 | m_conn->setOutput(nullptr); | 89 | m_conn->setOutput(nullptr); | ||
93 | 90 | | |||
94 | delete m_waylandOutput.data(); | | |||
95 | delete m_waylandOutputDevice.data(); | | |||
96 | delete m_cursor[0]; | 91 | delete m_cursor[0]; | ||
zzag: Is it safe? Shouldn't you test the pointer for validity?
Also, it looks like DrmOutput deletes… | |||||
You can delete a nullptr. But in general yes, the waylandOutput() and waylandOutputDevice() data fields should be deleted on Output level. I just wanted to keep the logical changes minimal and delete them at the same position as before. But yea, accepting this logical change in this case probably makes more sense. romangg: You can delete a nullptr.
But in general yes, the waylandOutput() and waylandOutputDevice()… | |||||
97 | delete m_cursor[1]; | 92 | delete m_cursor[1]; | ||
98 | if (!m_pageFlipPending) { | 93 | if (!m_pageFlipPending) { | ||
99 | deleteLater(); | 94 | deleteLater(); | ||
100 | } //else will be deleted in the page flip handler | 95 | } //else will be deleted in the page flip handler | ||
101 | //this is needed so that the pageflipcallback handle isn't deleted | 96 | //this is needed so that the pageflipcallback handle isn't deleted | ||
102 | } | 97 | } | ||
103 | 98 | | |||
104 | void DrmOutput::releaseGbm() | 99 | void DrmOutput::releaseGbm() | ||
Show All 36 Lines | |||||
141 | { | 136 | { | ||
142 | QImage cursorImage = m_backend->softwareCursor(); | 137 | QImage cursorImage = m_backend->softwareCursor(); | ||
143 | if (cursorImage.isNull()) { | 138 | if (cursorImage.isNull()) { | ||
144 | return; | 139 | return; | ||
145 | } | 140 | } | ||
146 | m_hasNewCursor = true; | 141 | m_hasNewCursor = true; | ||
147 | QImage *c = m_cursor[m_cursorIndex]->image(); | 142 | QImage *c = m_cursor[m_cursorIndex]->image(); | ||
148 | c->fill(Qt::transparent); | 143 | c->fill(Qt::transparent); | ||
149 | c->setDevicePixelRatio(m_scale); | 144 | c->setDevicePixelRatio(scale()); | ||
150 | 145 | | |||
151 | QPainter p; | 146 | QPainter p; | ||
152 | p.begin(c); | 147 | p.begin(c); | ||
153 | if (m_orientation == Qt::InvertedLandscapeOrientation) { | 148 | if (orientation() == Qt::InvertedLandscapeOrientation) { | ||
154 | QMatrix4x4 matrix; | 149 | QMatrix4x4 matrix; | ||
155 | matrix.translate(cursorImage.width() / 2.0, cursorImage.height() / 2.0); | 150 | matrix.translate(cursorImage.width() / 2.0, cursorImage.height() / 2.0); | ||
156 | matrix.rotate(180.0f, 0.0f, 0.0f, 1.0f); | 151 | matrix.rotate(180.0f, 0.0f, 0.0f, 1.0f); | ||
157 | matrix.translate(-cursorImage.width() / 2.0, -cursorImage.height() / 2.0); | 152 | matrix.translate(-cursorImage.width() / 2.0, -cursorImage.height() / 2.0); | ||
158 | p.setWorldTransform(matrix.toTransform()); | 153 | p.setWorldTransform(matrix.toTransform()); | ||
159 | } | 154 | } | ||
160 | p.drawImage(QPoint(0, 0), cursorImage); | 155 | p.drawImage(QPoint(0, 0), cursorImage); | ||
161 | p.end(); | 156 | p.end(); | ||
162 | } | 157 | } | ||
163 | 158 | | |||
164 | void DrmOutput::moveCursor(const QPoint &globalPos) | 159 | void DrmOutput::moveCursor(const QPoint &globalPos) | ||
165 | { | 160 | { | ||
166 | QMatrix4x4 matrix; | 161 | QMatrix4x4 matrix; | ||
167 | QMatrix4x4 hotspotMatrix; | 162 | QMatrix4x4 hotspotMatrix; | ||
168 | if (m_orientation == Qt::InvertedLandscapeOrientation) { | 163 | if (orientation() == Qt::InvertedLandscapeOrientation) { | ||
169 | matrix.translate(pixelSize().width() /2.0, pixelSize().height() / 2.0); | 164 | matrix.translate(pixelSize().width() /2.0, pixelSize().height() / 2.0); | ||
170 | matrix.rotate(180.0f, 0.0f, 0.0f, 1.0f); | 165 | matrix.rotate(180.0f, 0.0f, 0.0f, 1.0f); | ||
171 | matrix.translate(-pixelSize().width() /2.0, -pixelSize().height() / 2.0); | 166 | matrix.translate(-pixelSize().width() /2.0, -pixelSize().height() / 2.0); | ||
172 | const auto cursorSize = m_backend->softwareCursor().size(); | 167 | const auto cursorSize = m_backend->softwareCursor().size(); | ||
173 | hotspotMatrix.translate(cursorSize.width()/2.0, cursorSize.height()/2.0); | 168 | hotspotMatrix.translate(cursorSize.width()/2.0, cursorSize.height()/2.0); | ||
174 | hotspotMatrix.rotate(180.0f, 0.0f, 0.0f, 1.0f); | 169 | hotspotMatrix.rotate(180.0f, 0.0f, 0.0f, 1.0f); | ||
175 | hotspotMatrix.translate(-cursorSize.width()/2.0, -cursorSize.height()/2.0); | 170 | hotspotMatrix.translate(-cursorSize.width()/2.0, -cursorSize.height()/2.0); | ||
176 | } | 171 | } | ||
177 | hotspotMatrix.scale(m_scale); | 172 | hotspotMatrix.scale(scale()); | ||
178 | matrix.scale(m_scale); | 173 | matrix.scale(scale()); | ||
179 | matrix.translate(-m_globalPos.x(), -m_globalPos.y()); | 174 | const auto outputGlobalPos = AbstractOutput::globalPos(); | ||
175 | matrix.translate(-outputGlobalPos.x(), -outputGlobalPos.y()); | ||||
180 | const QPoint p = matrix.map(globalPos) - hotspotMatrix.map(m_backend->softwareCursorHotspot()); | 176 | const QPoint p = matrix.map(globalPos) - hotspotMatrix.map(m_backend->softwareCursorHotspot()); | ||
181 | drmModeMoveCursor(m_backend->fd(), m_crtc->id(), p.x(), p.y()); | 177 | drmModeMoveCursor(m_backend->fd(), m_crtc->id(), p.x(), p.y()); | ||
182 | } | 178 | } | ||
183 | 179 | | |||
184 | QSize DrmOutput::pixelSize() const | 180 | QSize DrmOutput::pixelSize() const | ||
185 | { | 181 | { | ||
186 | if (m_orientation == Qt::PortraitOrientation || m_orientation == Qt::InvertedPortraitOrientation) { | 182 | auto orient = orientation(); | ||
183 | if (orient == Qt::PortraitOrientation || orient == Qt::InvertedPortraitOrientation) { | ||||
187 | return QSize(m_mode.vdisplay, m_mode.hdisplay); | 184 | return QSize(m_mode.vdisplay, m_mode.hdisplay); | ||
188 | } | 185 | } | ||
189 | return QSize(m_mode.hdisplay, m_mode.vdisplay); | 186 | return QSize(m_mode.hdisplay, m_mode.vdisplay); | ||
190 | } | 187 | } | ||
191 | 188 | | |||
192 | QSize DrmOutput::physicalSize() const | | |||
193 | { | | |||
194 | if (m_orientation == Qt::PortraitOrientation || m_orientation == Qt::InvertedPortraitOrientation) { | | |||
195 | return QSize(m_physicalSize.height(), m_physicalSize.width()); | | |||
196 | } | | |||
197 | return m_physicalSize; | | |||
198 | } | | |||
199 | | ||||
200 | QRect DrmOutput::geometry() const | | |||
201 | { | | |||
202 | return QRect(m_globalPos, pixelSize() / m_scale); | | |||
203 | } | | |||
204 | | ||||
205 | qreal DrmOutput::scale() const | | |||
206 | { | | |||
207 | return m_scale; | | |||
208 | } | | |||
209 | | ||||
210 | void DrmOutput::setEnabled(bool enabled) | 189 | void DrmOutput::setEnabled(bool enabled) | ||
211 | { | 190 | { | ||
212 | if (enabled == isEnabled()) { | 191 | if (enabled == isEnabled()) { | ||
213 | return; | 192 | return; | ||
214 | } | 193 | } | ||
215 | if (enabled) { | 194 | if (enabled) { | ||
216 | setDpms(DpmsMode::On); | 195 | setDpms(DpmsMode::On); | ||
217 | initOutput(); | 196 | initOutput(); | ||
218 | } else { | 197 | } else { | ||
219 | setDpms(DpmsMode::Off); | 198 | setDpms(DpmsMode::Off); | ||
220 | delete m_waylandOutput.data(); | 199 | delete waylandOutput().data(); | ||
221 | } | 200 | } | ||
222 | m_waylandOutputDevice->setEnabled(enabled ? | 201 | waylandOutputDevice()->setEnabled(enabled ? | ||
223 | KWayland::Server::OutputDeviceInterface::Enablement::Enabled : KWayland::Server::OutputDeviceInterface::Enablement::Disabled); | 202 | KWayland::Server::OutputDeviceInterface::Enablement::Enabled : KWayland::Server::OutputDeviceInterface::Enablement::Disabled); | ||
224 | } | 203 | } | ||
225 | 204 | | |||
226 | bool DrmOutput::isEnabled() const | | |||
227 | { | | |||
228 | return !m_waylandOutput.isNull(); | | |||
229 | } | | |||
230 | | ||||
231 | static KWayland::Server::OutputInterface::DpmsMode toWaylandDpmsMode(DrmOutput::DpmsMode mode) | 205 | static KWayland::Server::OutputInterface::DpmsMode toWaylandDpmsMode(DrmOutput::DpmsMode mode) | ||
232 | { | 206 | { | ||
233 | using namespace KWayland::Server; | 207 | using namespace KWayland::Server; | ||
234 | switch (mode) { | 208 | switch (mode) { | ||
235 | case DrmOutput::DpmsMode::On: | 209 | case DrmOutput::DpmsMode::On: | ||
236 | return OutputInterface::DpmsMode::On; | 210 | return OutputInterface::DpmsMode::On; | ||
237 | case DrmOutput::DpmsMode::Standby: | 211 | case DrmOutput::DpmsMode::Standby: | ||
238 | return OutputInterface::DpmsMode::Standby; | 212 | return OutputInterface::DpmsMode::Standby; | ||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Line(s) | 279 | { | |||
309 | if (m_backend->atomicModeSetting()) { | 283 | if (m_backend->atomicModeSetting()) { | ||
310 | if (!initPrimaryPlane()) { | 284 | if (!initPrimaryPlane()) { | ||
311 | return false; | 285 | return false; | ||
312 | } | 286 | } | ||
313 | } else if (!m_crtc->blank()) { | 287 | } else if (!m_crtc->blank()) { | ||
314 | return false; | 288 | return false; | ||
315 | } | 289 | } | ||
316 | 290 | | |||
317 | m_internal = connector->connector_type == DRM_MODE_CONNECTOR_LVDS || connector->connector_type == DRM_MODE_CONNECTOR_eDP; | 291 | setInternal(connector->connector_type == DRM_MODE_CONNECTOR_LVDS || connector->connector_type == DRM_MODE_CONNECTOR_eDP); | ||
318 | 292 | | |||
319 | if (m_internal) { | 293 | if (internal()) { | ||
320 | connect(kwinApp(), &Application::screensCreated, this, | 294 | connect(kwinApp(), &Application::screensCreated, this, | ||
321 | [this] { | 295 | [this] { | ||
322 | connect(screens()->orientationSensor(), &OrientationSensor::orientationChanged, this, &DrmOutput::automaticRotation); | 296 | connect(screens()->orientationSensor(), &OrientationSensor::orientationChanged, this, &DrmOutput::automaticRotation); | ||
323 | } | 297 | } | ||
324 | ); | 298 | ); | ||
325 | } | 299 | } | ||
326 | 300 | | |||
327 | QSize physicalSize = !m_edid.physicalSize.isEmpty() ? m_edid.physicalSize : QSize(connector->mmWidth, connector->mmHeight); | 301 | QSize physicalSize = !m_edid.physicalSize.isEmpty() ? m_edid.physicalSize : QSize(connector->mmWidth, connector->mmHeight); | ||
328 | // the size might be completely borked. E.g. Samsung SyncMaster 2494HS reports 160x90 while in truth it's 520x292 | 302 | // the size might be completely borked. E.g. Samsung SyncMaster 2494HS reports 160x90 while in truth it's 520x292 | ||
329 | // as this information is used to calculate DPI info, it's going to result in everything being huge | 303 | // as this information is used to calculate DPI info, it's going to result in everything being huge | ||
330 | const QByteArray unknown = QByteArrayLiteral("unknown"); | 304 | const QByteArray unknown = QByteArrayLiteral("unknown"); | ||
331 | KConfigGroup group = kwinApp()->config()->group("EdidOverwrite").group(m_edid.eisaId.isEmpty() ? unknown : m_edid.eisaId) | 305 | KConfigGroup group = kwinApp()->config()->group("EdidOverwrite").group(m_edid.eisaId.isEmpty() ? unknown : m_edid.eisaId) | ||
332 | .group(m_edid.monitorName.isEmpty() ? unknown : m_edid.monitorName) | 306 | .group(m_edid.monitorName.isEmpty() ? unknown : m_edid.monitorName) | ||
333 | .group(m_edid.serialNumber.isEmpty() ? unknown : m_edid.serialNumber); | 307 | .group(m_edid.serialNumber.isEmpty() ? unknown : m_edid.serialNumber); | ||
334 | if (group.hasKey("PhysicalSize")) { | 308 | if (group.hasKey("PhysicalSize")) { | ||
335 | const QSize overwriteSize = group.readEntry("PhysicalSize", physicalSize); | 309 | const QSize overwriteSize = group.readEntry("PhysicalSize", physicalSize); | ||
336 | qCWarning(KWIN_DRM) << "Overwriting monitor physical size for" << m_edid.eisaId << "/" << m_edid.monitorName << "/" << m_edid.serialNumber << " from " << physicalSize << "to " << overwriteSize; | 310 | qCWarning(KWIN_DRM) << "Overwriting monitor physical size for" << m_edid.eisaId << "/" << m_edid.monitorName << "/" << m_edid.serialNumber << " from " << physicalSize << "to " << overwriteSize; | ||
337 | physicalSize = overwriteSize; | 311 | physicalSize = overwriteSize; | ||
338 | } | 312 | } | ||
339 | m_physicalSize = physicalSize; | 313 | setRawPhysicalSize(physicalSize); | ||
340 | 314 | | |||
341 | initOutputDevice(connector); | 315 | initOutputDevice(connector); | ||
342 | 316 | | |||
343 | setEnabled(true); | 317 | setEnabled(true); | ||
344 | return true; | 318 | return true; | ||
345 | } | 319 | } | ||
346 | 320 | | |||
347 | void DrmOutput::initUuid() | 321 | void DrmOutput::initUuid() | ||
348 | { | 322 | { | ||
349 | QCryptographicHash hash(QCryptographicHash::Md5); | 323 | QCryptographicHash hash(QCryptographicHash::Md5); | ||
350 | hash.addData(QByteArray::number(m_conn->id())); | 324 | hash.addData(QByteArray::number(m_conn->id())); | ||
351 | hash.addData(m_edid.eisaId); | 325 | hash.addData(m_edid.eisaId); | ||
352 | hash.addData(m_edid.monitorName); | 326 | hash.addData(m_edid.monitorName); | ||
353 | hash.addData(m_edid.serialNumber); | 327 | hash.addData(m_edid.serialNumber); | ||
354 | m_uuid = hash.result().toHex().left(10); | 328 | m_uuid = hash.result().toHex().left(10); | ||
355 | } | 329 | } | ||
356 | 330 | | |||
357 | void DrmOutput::initOutput() | 331 | void DrmOutput::initOutput() | ||
358 | { | 332 | { | ||
359 | Q_ASSERT(m_waylandOutputDevice); | 333 | auto wlOutputDevice = waylandOutputDevice(); | ||
360 | if (!m_waylandOutput.isNull()) { | 334 | Q_ASSERT(wlOutputDevice); | ||
361 | delete m_waylandOutput.data(); | 335 | | ||
362 | m_waylandOutput.clear(); | 336 | auto wlOutput = waylandOutput(); | ||
363 | } | 337 | if (!wlOutput.isNull()) { | ||
364 | m_waylandOutput = waylandServer()->display()->createOutput(); | 338 | delete wlOutput.data(); | ||
365 | m_xdgOutput = waylandServer()->xdgOutputManager()->createXdgOutput(m_waylandOutput, m_waylandOutput); | 339 | wlOutput.clear(); | ||
340 | } | ||||
341 | wlOutput = waylandServer()->display()->createOutput(); | ||||
342 | setWaylandOutput(wlOutput.data()); | ||||
343 | createXdgOutput(); | ||||
366 | connect(this, &DrmOutput::modeChanged, this, | 344 | connect(this, &DrmOutput::modeChanged, this, | ||
367 | [this] { | 345 | [this] { | ||
368 | if (m_waylandOutput.isNull()) { | 346 | auto wlOutput = waylandOutput(); | ||
347 | if (wlOutput.isNull()) { | ||||
369 | return; | 348 | return; | ||
370 | } | 349 | } | ||
371 | m_waylandOutput->setCurrentMode(QSize(m_mode.hdisplay, m_mode.vdisplay), refreshRateForMode(&m_mode)); | 350 | wlOutput->setCurrentMode(QSize(m_mode.hdisplay, m_mode.vdisplay), | ||
372 | if (m_xdgOutput) { | 351 | refreshRateForMode(&m_mode)); | ||
373 | m_xdgOutput->setLogicalSize(pixelSize() / m_scale); | 352 | auto xdg = xdgOutput(); | ||
374 | m_xdgOutput->done(); | 353 | if (xdg) { | ||
354 | xdg->setLogicalSize(pixelSize() / scale()); | ||||
355 | xdg->done(); | ||||
375 | } | 356 | } | ||
376 | } | 357 | } | ||
377 | ); | 358 | ); | ||
378 | m_waylandOutput->setManufacturer(m_waylandOutputDevice->manufacturer()); | 359 | wlOutput->setManufacturer(wlOutputDevice->manufacturer()); | ||
379 | m_waylandOutput->setModel(m_waylandOutputDevice->model()); | 360 | wlOutput->setModel(wlOutputDevice->model()); | ||
380 | m_waylandOutput->setPhysicalSize(m_physicalSize); | 361 | wlOutput->setPhysicalSize(rawPhysicalSize()); | ||
381 | 362 | | |||
382 | // set dpms | 363 | // set dpms | ||
383 | if (!m_dpms.isNull()) { | 364 | if (!m_dpms.isNull()) { | ||
384 | m_waylandOutput->setDpmsSupported(true); | 365 | wlOutput->setDpmsSupported(true); | ||
385 | m_waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsMode)); | 366 | wlOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsMode)); | ||
386 | connect(m_waylandOutput.data(), &KWayland::Server::OutputInterface::dpmsModeRequested, this, | 367 | connect(wlOutput.data(), &KWayland::Server::OutputInterface::dpmsModeRequested, this, | ||
387 | [this] (KWayland::Server::OutputInterface::DpmsMode mode) { | 368 | [this] (KWayland::Server::OutputInterface::DpmsMode mode) { | ||
388 | setDpms(fromWaylandDpmsMode(mode)); | 369 | setDpms(fromWaylandDpmsMode(mode)); | ||
389 | }, Qt::QueuedConnection | 370 | }, Qt::QueuedConnection | ||
390 | ); | 371 | ); | ||
391 | } | 372 | } | ||
392 | 373 | | |||
393 | for(const auto &mode: m_waylandOutputDevice->modes()) { | 374 | for(const auto &mode: wlOutputDevice->modes()) { | ||
394 | KWayland::Server::OutputInterface::ModeFlags flags; | 375 | KWayland::Server::OutputInterface::ModeFlags flags; | ||
395 | if (mode.flags & KWayland::Server::OutputDeviceInterface::ModeFlag::Current) { | 376 | if (mode.flags & KWayland::Server::OutputDeviceInterface::ModeFlag::Current) { | ||
396 | flags |= KWayland::Server::OutputInterface::ModeFlag::Current; | 377 | flags |= KWayland::Server::OutputInterface::ModeFlag::Current; | ||
397 | } | 378 | } | ||
398 | if (mode.flags & KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred) { | 379 | if (mode.flags & KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred) { | ||
399 | flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred; | 380 | flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred; | ||
400 | } | 381 | } | ||
401 | m_waylandOutput->addMode(mode.size, flags, mode.refreshRate); | 382 | wlOutput->addMode(mode.size, flags, mode.refreshRate); | ||
402 | } | 383 | } | ||
403 | 384 | | |||
404 | m_waylandOutput->create(); | 385 | wlOutput->create(); | ||
405 | } | 386 | } | ||
406 | 387 | | |||
407 | void DrmOutput::initOutputDevice(drmModeConnector *connector) | 388 | void DrmOutput::initOutputDevice(drmModeConnector *connector) | ||
408 | { | 389 | { | ||
409 | if (!m_waylandOutputDevice.isNull()) { | 390 | auto wlOutputDevice = waylandOutputDevice(); | ||
410 | delete m_waylandOutputDevice.data(); | 391 | if (!wlOutputDevice.isNull()) { | ||
411 | m_waylandOutputDevice.clear(); | 392 | delete wlOutputDevice.data(); | ||
393 | wlOutputDevice.clear(); | ||||
412 | } | 394 | } | ||
413 | m_waylandOutputDevice = waylandServer()->display()->createOutputDevice(); | 395 | wlOutputDevice = waylandServer()->display()->createOutputDevice(); | ||
414 | m_waylandOutputDevice->setUuid(m_uuid); | 396 | wlOutputDevice->setUuid(m_uuid); | ||
415 | 397 | | |||
416 | if (!m_edid.eisaId.isEmpty()) { | 398 | if (!m_edid.eisaId.isEmpty()) { | ||
417 | m_waylandOutputDevice->setManufacturer(QString::fromLatin1(m_edid.eisaId)); | 399 | wlOutputDevice->setManufacturer(QString::fromLatin1(m_edid.eisaId)); | ||
418 | } else { | 400 | } else { | ||
419 | m_waylandOutputDevice->setManufacturer(i18n("unknown")); | 401 | wlOutputDevice->setManufacturer(i18n("unknown")); | ||
420 | } | 402 | } | ||
421 | 403 | | |||
422 | QString connectorName = s_connectorNames.value(connector->connector_type, QByteArrayLiteral("Unknown")); | 404 | QString connectorName = s_connectorNames.value(connector->connector_type, QByteArrayLiteral("Unknown")); | ||
423 | QString modelName; | 405 | QString modelName; | ||
424 | 406 | | |||
425 | if (!m_edid.monitorName.isEmpty()) { | 407 | if (!m_edid.monitorName.isEmpty()) { | ||
426 | QString model = QString::fromLatin1(m_edid.monitorName); | 408 | QString model = QString::fromLatin1(m_edid.monitorName); | ||
427 | if (!m_edid.serialNumber.isEmpty()) { | 409 | if (!m_edid.serialNumber.isEmpty()) { | ||
428 | model.append('/'); | 410 | model.append('/'); | ||
429 | model.append(QString::fromLatin1(m_edid.serialNumber)); | 411 | model.append(QString::fromLatin1(m_edid.serialNumber)); | ||
430 | } | 412 | } | ||
431 | modelName = model; | 413 | modelName = model; | ||
432 | } else if (!m_edid.serialNumber.isEmpty()) { | 414 | } else if (!m_edid.serialNumber.isEmpty()) { | ||
433 | modelName = QString::fromLatin1(m_edid.serialNumber); | 415 | modelName = QString::fromLatin1(m_edid.serialNumber); | ||
434 | } else { | 416 | } else { | ||
435 | modelName = i18n("unknown"); | 417 | modelName = i18n("unknown"); | ||
436 | } | 418 | } | ||
437 | 419 | | |||
438 | m_waylandOutputDevice->setModel(connectorName + QStringLiteral("-") + QString::number(connector->connector_type_id) + QStringLiteral("-") + modelName); | 420 | wlOutputDevice->setModel(connectorName + QStringLiteral("-") + QString::number(connector->connector_type_id) + QStringLiteral("-") + modelName); | ||
439 | 421 | | |||
440 | m_waylandOutputDevice->setPhysicalSize(m_physicalSize); | 422 | wlOutputDevice->setPhysicalSize(rawPhysicalSize()); | ||
441 | 423 | | |||
442 | // read in mode information | 424 | // read in mode information | ||
443 | for (int i = 0; i < connector->count_modes; ++i) { | 425 | for (int i = 0; i < connector->count_modes; ++i) { | ||
444 | // TODO: in AMS here we could read and store for later every mode's blob_id | 426 | // TODO: in AMS here we could read and store for later every mode's blob_id | ||
445 | // would simplify isCurrentMode(..) and presentAtomically(..) in case of mode set | 427 | // would simplify isCurrentMode(..) and presentAtomically(..) in case of mode set | ||
446 | auto *m = &connector->modes[i]; | 428 | auto *m = &connector->modes[i]; | ||
447 | KWayland::Server::OutputDeviceInterface::ModeFlags deviceflags; | 429 | KWayland::Server::OutputDeviceInterface::ModeFlags deviceflags; | ||
448 | if (isCurrentMode(m)) { | 430 | if (isCurrentMode(m)) { | ||
449 | deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Current; | 431 | deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Current; | ||
450 | } | 432 | } | ||
451 | if (m->type & DRM_MODE_TYPE_PREFERRED) { | 433 | if (m->type & DRM_MODE_TYPE_PREFERRED) { | ||
452 | deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred; | 434 | deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred; | ||
453 | } | 435 | } | ||
454 | 436 | | |||
455 | const auto refreshRate = refreshRateForMode(m); | 437 | const auto refreshRate = refreshRateForMode(m); | ||
456 | 438 | | |||
457 | KWayland::Server::OutputDeviceInterface::Mode mode; | 439 | KWayland::Server::OutputDeviceInterface::Mode mode; | ||
458 | mode.id = i; | 440 | mode.id = i; | ||
459 | mode.size = QSize(m->hdisplay, m->vdisplay); | 441 | mode.size = QSize(m->hdisplay, m->vdisplay); | ||
460 | mode.flags = deviceflags; | 442 | mode.flags = deviceflags; | ||
461 | mode.refreshRate = refreshRate; | 443 | mode.refreshRate = refreshRate; | ||
462 | qCDebug(KWIN_DRM) << "Adding mode: " << i << mode.size; | 444 | qCDebug(KWIN_DRM) << "Adding mode: " << i << mode.size; | ||
463 | m_waylandOutputDevice->addMode(mode); | 445 | wlOutputDevice->addMode(mode); | ||
464 | } | 446 | } | ||
465 | m_waylandOutputDevice->create(); | 447 | wlOutputDevice->create(); | ||
448 | setWaylandOutputDevice(wlOutputDevice.data()); | ||||
466 | } | 449 | } | ||
467 | 450 | | |||
468 | bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const | 451 | bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const | ||
469 | { | 452 | { | ||
470 | return mode->clock == m_mode.clock | 453 | return mode->clock == m_mode.clock | ||
471 | && mode->hdisplay == m_mode.hdisplay | 454 | && mode->hdisplay == m_mode.hdisplay | ||
472 | && mode->hsync_start == m_mode.hsync_start | 455 | && mode->hsync_start == m_mode.hsync_start | ||
473 | && mode->hsync_end == m_mode.hsync_end | 456 | && mode->hsync_end == m_mode.hsync_end | ||
▲ Show 20 Lines • Show All 278 Lines • ▼ Show 20 Line(s) | 724 | } else { | |||
752 | m_dpmsMode = m_dpmsModePending; | 735 | m_dpmsMode = m_dpmsModePending; | ||
753 | } | 736 | } | ||
754 | } | 737 | } | ||
755 | 738 | | |||
756 | void DrmOutput::dpmsOnHandler() | 739 | void DrmOutput::dpmsOnHandler() | ||
757 | { | 740 | { | ||
758 | qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to On."; | 741 | qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to On."; | ||
759 | 742 | | |||
760 | if (m_waylandOutput) { | 743 | auto wlOutput = waylandOutput(); | ||
761 | m_waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); | 744 | if (wlOutput) { | ||
745 | wlOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); | ||||
762 | } | 746 | } | ||
763 | emit dpmsChanged(); | 747 | emit dpmsChanged(); | ||
764 | 748 | | |||
765 | m_backend->checkOutputsAreOn(); | 749 | m_backend->checkOutputsAreOn(); | ||
766 | if (!m_backend->atomicModeSetting()) { | 750 | if (!m_backend->atomicModeSetting()) { | ||
767 | m_crtc->blank(); | 751 | m_crtc->blank(); | ||
768 | } | 752 | } | ||
769 | if (Compositor *compositor = Compositor::self()) { | 753 | if (Compositor *compositor = Compositor::self()) { | ||
770 | compositor->addRepaintFull(); | 754 | compositor->addRepaintFull(); | ||
771 | } | 755 | } | ||
772 | } | 756 | } | ||
773 | 757 | | |||
774 | void DrmOutput::dpmsOffHandler() | 758 | void DrmOutput::dpmsOffHandler() | ||
775 | { | 759 | { | ||
776 | qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to Off."; | 760 | qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to Off."; | ||
777 | 761 | | |||
778 | if (m_waylandOutput) { | 762 | auto wlOutput = waylandOutput(); | ||
779 | m_waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); | 763 | if (wlOutput) { | ||
764 | wlOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); | ||||
780 | } | 765 | } | ||
781 | emit dpmsChanged(); | 766 | emit dpmsChanged(); | ||
782 | 767 | | |||
783 | m_backend->outputWentOff(); | 768 | m_backend->outputWentOff(); | ||
784 | } | 769 | } | ||
785 | 770 | | |||
786 | QString DrmOutput::name() const | | |||
787 | { | | |||
788 | if (!m_waylandOutput) { | | |||
789 | return i18n("unknown"); | | |||
790 | } | | |||
791 | return QStringLiteral("%1 %2").arg(m_waylandOutput->manufacturer()).arg(m_waylandOutput->model()); | | |||
792 | } | | |||
793 | | ||||
794 | int DrmOutput::currentRefreshRate() const | 771 | int DrmOutput::currentRefreshRate() const | ||
795 | { | 772 | { | ||
796 | if (!m_waylandOutput) { | 773 | auto wlOutput = waylandOutput(); | ||
774 | if (!wlOutput) { | ||||
797 | return 60000; | 775 | return 60000; | ||
798 | } | 776 | } | ||
799 | return m_waylandOutput->refreshRate(); | 777 | return wlOutput->refreshRate(); | ||
800 | } | | |||
801 | | ||||
802 | void DrmOutput::setGlobalPos(const QPoint &pos) | | |||
803 | { | | |||
804 | m_globalPos = pos; | | |||
805 | if (m_waylandOutput) { | | |||
806 | m_waylandOutput->setGlobalPosition(pos); | | |||
807 | } | | |||
808 | if (m_waylandOutputDevice) { | | |||
809 | m_waylandOutputDevice->setGlobalPosition(pos); | | |||
810 | } | | |||
811 | if (m_xdgOutput) { | | |||
812 | m_xdgOutput->setLogicalPosition(pos); | | |||
813 | m_xdgOutput->done(); | | |||
814 | } | | |||
815 | } | | |||
816 | | ||||
817 | void DrmOutput::setScale(qreal scale) | | |||
818 | { | | |||
819 | m_scale = scale; | | |||
820 | if (m_waylandOutput) { | | |||
821 | // this is the scale that clients will ideally use for their buffers | | |||
822 | // this has to be an int which is fine | | |||
823 | | ||||
824 | // I don't know whether we want to round or ceil | | |||
825 | // or maybe even set this to 3 when we're scaling to 1.5 | | |||
826 | // don't treat this like it's chosen deliberately | | |||
827 | m_waylandOutput->setScale(std::ceil(scale)); | | |||
828 | } | | |||
829 | if (m_waylandOutputDevice) { | | |||
830 | m_waylandOutputDevice->setScaleF(scale); | | |||
831 | } | | |||
832 | if (m_xdgOutput) { | | |||
833 | m_xdgOutput->setLogicalSize(pixelSize() / m_scale); | | |||
834 | m_xdgOutput->done(); | | |||
835 | } | | |||
836 | } | | |||
837 | | ||||
838 | void DrmOutput::setChanges(KWayland::Server::OutputChangeSet *changes) | | |||
839 | { | | |||
840 | m_changeset = changes; | | |||
841 | qCDebug(KWIN_DRM) << "set changes in DrmOutput"; | | |||
842 | commitChanges(); | | |||
843 | } | 778 | } | ||
844 | 779 | | |||
845 | bool DrmOutput::commitChanges() | 780 | bool DrmOutput::commitChanges() | ||
846 | { | 781 | { | ||
847 | Q_ASSERT(!m_waylandOutputDevice.isNull()); | 782 | auto wlOutputDevice = waylandOutputDevice(); | ||
783 | Q_ASSERT(!wlOutputDevice.isNull()); | ||||
848 | 784 | | |||
849 | if (m_changeset.isNull()) { | 785 | auto changeset = changes(); | ||
786 | | ||||
787 | if (changeset.isNull()) { | ||||
850 | qCDebug(KWIN_DRM) << "no changes"; | 788 | qCDebug(KWIN_DRM) << "no changes"; | ||
851 | // No changes to an output is an entirely valid thing | 789 | // No changes to an output is an entirely valid thing | ||
852 | return true; | 790 | return true; | ||
853 | } | 791 | } | ||
854 | //enabledChanged is handled by drmbackend | 792 | //enabledChanged is handled by drmbackend | ||
855 | if (m_changeset->modeChanged()) { | 793 | if (changeset->modeChanged()) { | ||
856 | qCDebug(KWIN_DRM) << "Setting new mode:" << m_changeset->mode(); | 794 | qCDebug(KWIN_DRM) << "Setting new mode:" << changeset->mode(); | ||
857 | m_waylandOutputDevice->setCurrentMode(m_changeset->mode()); | 795 | wlOutputDevice->setCurrentMode(changeset->mode()); | ||
858 | updateMode(m_changeset->mode()); | 796 | updateMode(changeset->mode()); | ||
859 | } | 797 | } | ||
860 | if (m_changeset->transformChanged()) { | 798 | if (changeset->transformChanged()) { | ||
861 | qCDebug(KWIN_DRM) << "Server setting transform: " << (int)(m_changeset->transform()); | 799 | qCDebug(KWIN_DRM) << "Server setting transform: " << (int)(changeset->transform()); | ||
862 | transform(m_changeset->transform()); | 800 | transform(changeset->transform()); | ||
863 | } | 801 | } | ||
864 | if (m_changeset->positionChanged()) { | 802 | if (changeset->positionChanged()) { | ||
865 | qCDebug(KWIN_DRM) << "Server setting position: " << m_changeset->position(); | 803 | qCDebug(KWIN_DRM) << "Server setting position: " << changeset->position(); | ||
866 | setGlobalPos(m_changeset->position()); | 804 | setGlobalPos(changeset->position()); | ||
867 | // may just work already! | 805 | // may just work already! | ||
868 | } | 806 | } | ||
869 | if (m_changeset->scaleChanged()) { | 807 | if (changeset->scaleChanged()) { | ||
870 | qCDebug(KWIN_DRM) << "Setting scale:" << m_changeset->scale(); | 808 | qCDebug(KWIN_DRM) << "Setting scale:" << changeset->scale(); | ||
871 | setScale(m_changeset->scaleF()); | 809 | setScale(changeset->scaleF()); | ||
872 | } | 810 | } | ||
873 | return true; | 811 | return true; | ||
874 | } | 812 | } | ||
875 | 813 | | |||
876 | void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform transform) | 814 | void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform transform) | ||
877 | { | 815 | { | ||
878 | m_waylandOutputDevice->setTransform(transform); | 816 | waylandOutputDevice()->setTransform(transform); | ||
879 | using KWayland::Server::OutputDeviceInterface; | 817 | using KWayland::Server::OutputDeviceInterface; | ||
880 | using KWayland::Server::OutputInterface; | 818 | using KWayland::Server::OutputInterface; | ||
819 | auto wlOutput = waylandOutput(); | ||||
820 | | ||||
881 | switch (transform) { | 821 | switch (transform) { | ||
882 | case OutputDeviceInterface::Transform::Normal: | 822 | case OutputDeviceInterface::Transform::Normal: | ||
883 | if (m_primaryPlane) { | 823 | if (m_primaryPlane) { | ||
884 | m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate0); | 824 | m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate0); | ||
885 | } | 825 | } | ||
886 | if (m_waylandOutput) { | 826 | if (wlOutput) { | ||
887 | m_waylandOutput->setTransform(OutputInterface::Transform::Normal); | 827 | wlOutput->setTransform(OutputInterface::Transform::Normal); | ||
888 | } | 828 | } | ||
889 | m_orientation = Qt::PrimaryOrientation; | 829 | setOrientation(Qt::PrimaryOrientation); | ||
890 | break; | 830 | break; | ||
891 | case OutputDeviceInterface::Transform::Rotated90: | 831 | case OutputDeviceInterface::Transform::Rotated90: | ||
892 | if (m_primaryPlane) { | 832 | if (m_primaryPlane) { | ||
893 | m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate90); | 833 | m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate90); | ||
894 | } | 834 | } | ||
895 | if (m_waylandOutput) { | 835 | if (wlOutput) { | ||
896 | m_waylandOutput->setTransform(OutputInterface::Transform::Rotated90); | 836 | wlOutput->setTransform(OutputInterface::Transform::Rotated90); | ||
897 | } | 837 | } | ||
898 | m_orientation = Qt::PortraitOrientation; | 838 | setOrientation(Qt::PortraitOrientation); | ||
899 | break; | 839 | break; | ||
900 | case OutputDeviceInterface::Transform::Rotated180: | 840 | case OutputDeviceInterface::Transform::Rotated180: | ||
901 | if (m_primaryPlane) { | 841 | if (m_primaryPlane) { | ||
902 | m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate180); | 842 | m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate180); | ||
903 | } | 843 | } | ||
904 | if (m_waylandOutput) { | 844 | if (wlOutput) { | ||
905 | m_waylandOutput->setTransform(OutputInterface::Transform::Rotated180); | 845 | wlOutput->setTransform(OutputInterface::Transform::Rotated180); | ||
906 | } | 846 | } | ||
907 | m_orientation = Qt::InvertedLandscapeOrientation; | 847 | setOrientation(Qt::InvertedLandscapeOrientation); | ||
908 | break; | 848 | break; | ||
909 | case OutputDeviceInterface::Transform::Rotated270: | 849 | case OutputDeviceInterface::Transform::Rotated270: | ||
910 | if (m_primaryPlane) { | 850 | if (m_primaryPlane) { | ||
911 | m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate270); | 851 | m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate270); | ||
912 | } | 852 | } | ||
913 | if (m_waylandOutput) { | 853 | if (wlOutput) { | ||
914 | m_waylandOutput->setTransform(OutputInterface::Transform::Rotated270); | 854 | wlOutput->setTransform(OutputInterface::Transform::Rotated270); | ||
915 | } | 855 | } | ||
916 | m_orientation = Qt::InvertedPortraitOrientation; | 856 | setOrientation(Qt::InvertedPortraitOrientation); | ||
917 | break; | 857 | break; | ||
918 | case OutputDeviceInterface::Transform::Flipped: | 858 | case OutputDeviceInterface::Transform::Flipped: | ||
919 | // TODO: what is this exactly? | 859 | // TODO: what is this exactly? | ||
920 | if (m_waylandOutput) { | 860 | if (wlOutput) { | ||
921 | m_waylandOutput->setTransform(OutputInterface::Transform::Flipped); | 861 | wlOutput->setTransform(OutputInterface::Transform::Flipped); | ||
922 | } | 862 | } | ||
923 | break; | 863 | break; | ||
924 | case OutputDeviceInterface::Transform::Flipped90: | 864 | case OutputDeviceInterface::Transform::Flipped90: | ||
925 | // TODO: what is this exactly? | 865 | // TODO: what is this exactly? | ||
926 | if (m_waylandOutput) { | 866 | if (wlOutput) { | ||
927 | m_waylandOutput->setTransform(OutputInterface::Transform::Flipped90); | 867 | wlOutput->setTransform(OutputInterface::Transform::Flipped90); | ||
928 | } | 868 | } | ||
929 | break; | 869 | break; | ||
930 | case OutputDeviceInterface::Transform::Flipped180: | 870 | case OutputDeviceInterface::Transform::Flipped180: | ||
931 | // TODO: what is this exactly? | 871 | // TODO: what is this exactly? | ||
932 | if (m_waylandOutput) { | 872 | if (wlOutput) { | ||
933 | m_waylandOutput->setTransform(OutputInterface::Transform::Flipped180); | 873 | wlOutput->setTransform(OutputInterface::Transform::Flipped180); | ||
934 | } | 874 | } | ||
935 | break; | 875 | break; | ||
936 | case OutputDeviceInterface::Transform::Flipped270: | 876 | case OutputDeviceInterface::Transform::Flipped270: | ||
937 | // TODO: what is this exactly? | 877 | // TODO: what is this exactly? | ||
938 | if (m_waylandOutput) { | 878 | if (wlOutput) { | ||
939 | m_waylandOutput->setTransform(OutputInterface::Transform::Flipped270); | 879 | wlOutput->setTransform(OutputInterface::Transform::Flipped270); | ||
940 | } | 880 | } | ||
941 | break; | 881 | break; | ||
942 | } | 882 | } | ||
943 | m_modesetRequested = true; | 883 | m_modesetRequested = true; | ||
944 | // the cursor might need to get rotated | 884 | // the cursor might need to get rotated | ||
945 | updateCursor(); | 885 | updateCursor(); | ||
946 | showCursor(); | 886 | showCursor(); | ||
947 | emit modeChanged(); | 887 | emit modeChanged(); | ||
▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Line(s) | 992 | { | |||
1065 | 1005 | | |||
1066 | if (!doAtomicCommit(AtomicCommitMode::Test)) { | 1006 | if (!doAtomicCommit(AtomicCommitMode::Test)) { | ||
1067 | //TODO: When we use planes for layered rendering, fallback to renderer instead. Also for direct scanout? | 1007 | //TODO: When we use planes for layered rendering, fallback to renderer instead. Also for direct scanout? | ||
1068 | //TODO: Probably should undo setNext and reset the flip list | 1008 | //TODO: Probably should undo setNext and reset the flip list | ||
1069 | qCDebug(KWIN_DRM) << "Atomic test commit failed. Aborting present."; | 1009 | qCDebug(KWIN_DRM) << "Atomic test commit failed. Aborting present."; | ||
1070 | // go back to previous state | 1010 | // go back to previous state | ||
1071 | if (m_lastWorkingState.valid) { | 1011 | if (m_lastWorkingState.valid) { | ||
1072 | m_mode = m_lastWorkingState.mode; | 1012 | m_mode = m_lastWorkingState.mode; | ||
1073 | m_orientation = m_lastWorkingState.orientation; | 1013 | setOrientation(m_lastWorkingState.orientation); | ||
1074 | setGlobalPos(m_lastWorkingState.globalPos); | 1014 | setGlobalPos(m_lastWorkingState.globalPos); | ||
1075 | if (m_primaryPlane) { | 1015 | if (m_primaryPlane) { | ||
1076 | m_primaryPlane->setTransformation(m_lastWorkingState.planeTransformations); | 1016 | m_primaryPlane->setTransformation(m_lastWorkingState.planeTransformations); | ||
1077 | } | 1017 | } | ||
1078 | m_modesetRequested = true; | 1018 | m_modesetRequested = true; | ||
1079 | // the cursor might need to get rotated | 1019 | // the cursor might need to get rotated | ||
1080 | updateCursor(); | 1020 | updateCursor(); | ||
1081 | showCursor(); | 1021 | showCursor(); | ||
1082 | // TODO: forward to OutputInterface and OutputDeviceInterface | 1022 | // TODO: forward to OutputInterface and OutputDeviceInterface | ||
1083 | emit modeChanged(); | 1023 | emit modeChanged(); | ||
1084 | emit screens()->changed(); | 1024 | emit screens()->changed(); | ||
1085 | } | 1025 | } | ||
1086 | return false; | 1026 | return false; | ||
1087 | } | 1027 | } | ||
1088 | const bool wasModeset = m_modesetRequested; | 1028 | const bool wasModeset = m_modesetRequested; | ||
1089 | if (!doAtomicCommit(AtomicCommitMode::Real)) { | 1029 | if (!doAtomicCommit(AtomicCommitMode::Real)) { | ||
1090 | qCDebug(KWIN_DRM) << "Atomic commit failed. This should have never happened! Aborting present."; | 1030 | qCDebug(KWIN_DRM) << "Atomic commit failed. This should have never happened! Aborting present."; | ||
1091 | //TODO: Probably should undo setNext and reset the flip list | 1031 | //TODO: Probably should undo setNext and reset the flip list | ||
1092 | return false; | 1032 | return false; | ||
1093 | } | 1033 | } | ||
1094 | if (wasModeset) { | 1034 | if (wasModeset) { | ||
1095 | // store current mode set as new good state | 1035 | // store current mode set as new good state | ||
1096 | m_lastWorkingState.mode = m_mode; | 1036 | m_lastWorkingState.mode = m_mode; | ||
1097 | m_lastWorkingState.orientation = m_orientation; | 1037 | m_lastWorkingState.orientation = orientation(); | ||
1098 | m_lastWorkingState.globalPos = m_globalPos; | 1038 | m_lastWorkingState.globalPos = globalPos(); | ||
1099 | if (m_primaryPlane) { | 1039 | if (m_primaryPlane) { | ||
1100 | m_lastWorkingState.planeTransformations = m_primaryPlane->transformation(); | 1040 | m_lastWorkingState.planeTransformations = m_primaryPlane->transformation(); | ||
1101 | } | 1041 | } | ||
1102 | m_lastWorkingState.valid = true; | 1042 | m_lastWorkingState.valid = true; | ||
1103 | } | 1043 | } | ||
1104 | m_pageFlipPending = true; | 1044 | m_pageFlipPending = true; | ||
1105 | return true; | 1045 | return true; | ||
1106 | } | 1046 | } | ||
▲ Show 20 Lines • Show All 239 Lines • Show Last 20 Lines |
Is it safe? Shouldn't you test the pointer for validity?
Also, it looks like DrmOutput deletes objects that it doesn't own. Is it a good idea?