Changeset View
Changeset View
Standalone View
Standalone View
plugins/platforms/drm/drm_backend.cpp
Show All 32 Lines | |||||
33 | #include "wayland_server.h" | 33 | #include "wayland_server.h" | ||
34 | #if HAVE_GBM | 34 | #if HAVE_GBM | ||
35 | #include "egl_gbm_backend.h" | 35 | #include "egl_gbm_backend.h" | ||
36 | #include <gbm.h> | 36 | #include <gbm.h> | ||
37 | #endif | 37 | #endif | ||
38 | // KWayland | 38 | // KWayland | ||
39 | #include <KWayland/Server/seat_interface.h> | 39 | #include <KWayland/Server/seat_interface.h> | ||
40 | #include <KWayland/Server/outputconfiguration_interface.h> | 40 | #include <KWayland/Server/outputconfiguration_interface.h> | ||
41 | #include <KWayland/Server/buffer_interface.h> | ||||
41 | // KF5 | 42 | // KF5 | ||
42 | #include <KConfigGroup> | 43 | #include <KConfigGroup> | ||
43 | #include <KLocalizedString> | 44 | #include <KLocalizedString> | ||
44 | #include <KSharedConfig> | 45 | #include <KSharedConfig> | ||
45 | // Qt | 46 | // Qt | ||
46 | #include <QCryptographicHash> | 47 | #include <QCryptographicHash> | ||
47 | #include <QSocketNotifier> | 48 | #include <QSocketNotifier> | ||
48 | #include <QPainter> | 49 | #include <QPainter> | ||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Line(s) | |||||
158 | 159 | | |||
159 | void DrmBackend::reactivate() | 160 | void DrmBackend::reactivate() | ||
160 | { | 161 | { | ||
161 | if (m_active) { | 162 | if (m_active) { | ||
162 | return; | 163 | return; | ||
163 | } | 164 | } | ||
164 | m_active = true; | 165 | m_active = true; | ||
165 | if (!usesSoftwareCursor()) { | 166 | if (!usesSoftwareCursor()) { | ||
166 | DrmBuffer *c = m_cursor[(m_cursorIndex + 1) % 2]; | 167 | DrmDumbBuffer *c = m_cursor[(m_cursorIndex + 1) % 2]; | ||
167 | const QPoint cp = Cursor::pos() - softwareCursorHotspot(); | 168 | const QPoint cp = Cursor::pos() - softwareCursorHotspot(); | ||
168 | for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { | 169 | for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { | ||
169 | DrmOutput *o = *it; | 170 | DrmOutput *o = *it; | ||
170 | o->pageFlipped(); | 171 | o->pageFlipped(); | ||
171 | o->blank(); | 172 | o->blank(); | ||
172 | o->showCursor(c); | 173 | o->showCursor(c); | ||
173 | o->moveCursor(cp); | 174 | o->moveCursor(cp); | ||
174 | } | 175 | } | ||
Show All 31 Lines | 204 | { | |||
206 | Q_UNUSED(sec) | 207 | Q_UNUSED(sec) | ||
207 | Q_UNUSED(usec) | 208 | Q_UNUSED(usec) | ||
208 | auto output = reinterpret_cast<DrmOutput*>(data); | 209 | auto output = reinterpret_cast<DrmOutput*>(data); | ||
209 | output->pageFlipped(); | 210 | output->pageFlipped(); | ||
210 | output->m_backend->m_pageFlipsPending--; | 211 | output->m_backend->m_pageFlipsPending--; | ||
211 | if (output->m_backend->m_pageFlipsPending == 0) { | 212 | if (output->m_backend->m_pageFlipsPending == 0) { | ||
212 | // TODO: improve, this currently means we wait for all page flips or all outputs. | 213 | // TODO: improve, this currently means we wait for all page flips or all outputs. | ||
213 | // It would be better to driver the repaint per output | 214 | // It would be better to driver the repaint per output | ||
215 | | ||||
216 | if (output->m_backend->m_atomicModeSetting && | ||||
217 | output->m_dpmsMode == DrmOutput::DpmsMode::On && | ||||
218 | output->m_dpmsMode != output->m_dpmsModePending) { | ||||
219 | output->dpmsOffAtomically(); | ||||
220 | } | ||||
221 | | ||||
214 | if (Compositor::self()) { | 222 | if (Compositor::self()) { | ||
215 | Compositor::self()->bufferSwapComplete(); | 223 | Compositor::self()->bufferSwapComplete(); | ||
216 | } | 224 | } | ||
217 | } | 225 | } | ||
218 | } | 226 | } | ||
219 | 227 | | |||
220 | void DrmBackend::openDrm() | 228 | void DrmBackend::openDrm() | ||
221 | { | 229 | { | ||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Line(s) | 270 | if (m_atomicModeSetting) { | |||
263 | qCDebug(KWIN_DRM) << "Number of planes:" << planeResources->count_planes; | 271 | qCDebug(KWIN_DRM) << "Number of planes:" << planeResources->count_planes; | ||
264 | 272 | | |||
265 | // create the plane objects | 273 | // create the plane objects | ||
266 | for (unsigned int i = 0; i < planeResources->count_planes; ++i) { | 274 | for (unsigned int i = 0; i < planeResources->count_planes; ++i) { | ||
267 | drmModePlane *kplane = drmModeGetPlane(m_fd, planeResources->planes[i]); | 275 | drmModePlane *kplane = drmModeGetPlane(m_fd, planeResources->planes[i]); | ||
268 | DrmPlane *p = new DrmPlane(kplane->plane_id, m_fd); | 276 | DrmPlane *p = new DrmPlane(kplane->plane_id, m_fd); | ||
269 | 277 | | |||
270 | if (p->init()) { | 278 | if (p->init()) { | ||
271 | p->setPossibleCrtcs(kplane->possible_crtcs); | | |||
272 | p->setFormats(kplane->formats, kplane->count_formats); | | |||
273 | m_planes << p; | 279 | m_planes << p; | ||
280 | if (p->type() == DrmPlane::TypeIndex::Overlay) { | ||||
281 | m_overlayPlanes << p; | ||||
282 | } | ||||
274 | } else { | 283 | } else { | ||
275 | delete p; | 284 | delete p; | ||
276 | } | 285 | } | ||
277 | } | 286 | } | ||
278 | 287 | | |||
279 | if (m_planes.isEmpty()) { | 288 | if (m_planes.isEmpty()) { | ||
280 | qCWarning(KWIN_DRM) << "Failed to create any plane. Falling back to legacy mode"; | 289 | qCWarning(KWIN_DRM) << "Failed to create any plane. Falling back to legacy mode"; | ||
281 | m_atomicModeSetting = false; | 290 | m_atomicModeSetting = false; | ||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Line(s) | 337 | { | |||
329 | if (m_fd < 0) { | 338 | if (m_fd < 0) { | ||
330 | return; | 339 | return; | ||
331 | } | 340 | } | ||
332 | ScopedDrmPointer<_drmModeRes, &drmModeFreeResources> resources(drmModeGetResources(m_fd)); | 341 | ScopedDrmPointer<_drmModeRes, &drmModeFreeResources> resources(drmModeGetResources(m_fd)); | ||
333 | if (!resources) { | 342 | if (!resources) { | ||
334 | qCWarning(KWIN_DRM) << "drmModeGetResources failed"; | 343 | qCWarning(KWIN_DRM) << "drmModeGetResources failed"; | ||
335 | return; | 344 | return; | ||
336 | } | 345 | } | ||
346 | // TODO: Query min and max values to gate gbm buffer sizes (later for overlay planes)! | ||||
337 | 347 | | |||
338 | QVector<DrmOutput*> connectedOutputs; | 348 | QVector<DrmOutput*> connectedOutputs; | ||
339 | for (int i = 0; i < resources->count_connectors; ++i) { | 349 | for (int i = 0; i < resources->count_connectors; ++i) { | ||
340 | const auto id = resources->connectors[i]; | 350 | const auto id = resources->connectors[i]; | ||
341 | ScopedDrmPointer<_drmModeConnector, &drmModeFreeConnector> connector(drmModeGetConnector(m_fd, id)); | 351 | ScopedDrmPointer<_drmModeConnector, &drmModeFreeConnector> connector(drmModeGetConnector(m_fd, id)); | ||
342 | if (!connector) { | 352 | if (!connector) { | ||
343 | continue; | 353 | continue; | ||
344 | } | 354 | } | ||
345 | if (connector->connection != DRM_MODE_CONNECTED) { | 355 | if (connector->connection != DRM_MODE_CONNECTED) { | ||
346 | continue; | 356 | continue; | ||
347 | } | 357 | } | ||
348 | if (connector->count_modes == 0) { | 358 | if (connector->count_modes == 0) { | ||
349 | continue; | 359 | continue; | ||
350 | } | 360 | } | ||
351 | if (DrmOutput *o = findOutput(connector->connector_id)) { | 361 | if (DrmOutput *o = findOutput(connector->connector_id)) { | ||
352 | connectedOutputs << o; | 362 | connectedOutputs << o; | ||
353 | continue; | 363 | continue; | ||
354 | } | 364 | } | ||
365 | | ||||
366 | DrmCrtc *crtc = nullptr; | ||||
367 | { | ||||
368 | // let's iterate over all encoders to find a suitable crtc | ||||
369 | drmModeRes *res = resources.data(); | ||||
370 | drmModeConnector *con = connector.data(); | ||||
371 | QVector<DrmOutput *> outputs = connectedOutputs + m_outputs; | ||||
372 | for (int i = 0; i < con->count_encoders; ++i) { | ||||
355 | bool crtcFound = false; | 373 | bool crtcFound = false; | ||
356 | const quint32 crtcId = findCrtc(resources.data(), connector.data(), &crtcFound); | 374 | ScopedDrmPointer<_drmModeEncoder, &drmModeFreeEncoder> encoder(drmModeGetEncoder(m_fd, con->encoders[i])); | ||
357 | if (!crtcFound) { | 375 | if (!encoder) { | ||
376 | continue; | ||||
377 | } | ||||
378 | for (int j = 0; j < res->count_crtcs; ++j) { | ||||
379 | if (!(encoder->possible_crtcs & (1 << j))) { | ||||
380 | continue; | ||||
381 | } | ||||
382 | | ||||
383 | // check if crtc isn't used yet | ||||
384 | auto it = std::find_if(outputs.constBegin(), outputs.constEnd(), | ||||
385 | [res, j] (DrmOutput *o) { | ||||
386 | return o->m_crtc->id() == res->crtcs[j]; | ||||
387 | } | ||||
388 | ); | ||||
389 | if (it != outputs.constEnd()) { | ||||
358 | continue; | 390 | continue; | ||
359 | } | 391 | } | ||
360 | ScopedDrmPointer<_drmModeCrtc, &drmModeFreeCrtc> crtc(drmModeGetCrtc(m_fd, crtcId)); | 392 | | ||
393 | crtc = new DrmCrtc(res->crtcs[j], m_fd, j); | ||||
394 | crtcFound = true; | ||||
395 | break; | ||||
396 | } | ||||
397 | if (crtcFound) { | ||||
398 | break; | ||||
399 | } | ||||
400 | } | ||||
401 | } | ||||
402 | | ||||
361 | if (!crtc) { | 403 | if (!crtc) { | ||
362 | continue; | 404 | continue; | ||
363 | } | 405 | } | ||
406 | | ||||
407 | ScopedDrmPointer<_drmModeCrtc, &drmModeFreeCrtc> modeCrtc(drmModeGetCrtc(m_fd, crtc->id())); | ||||
408 | if (!modeCrtc) { | ||||
409 | delete crtc; | ||||
410 | continue; | ||||
411 | } | ||||
364 | DrmOutput *drmOutput = new DrmOutput(this); | 412 | DrmOutput *drmOutput = new DrmOutput(this); | ||
365 | connect(drmOutput, &DrmOutput::dpmsChanged, this, &DrmBackend::outputDpmsChanged); | 413 | connect(drmOutput, &DrmOutput::dpmsChanged, this, &DrmBackend::outputDpmsChanged); | ||
366 | drmOutput->m_crtcId = crtcId; | 414 | drmOutput->m_crtc = crtc; | ||
367 | drmOutput->m_connector = connector->connector_id; | 415 | drmOutput->m_crtc->setOutput(drmOutput); | ||
416 | drmOutput->m_conn = new DrmConnector(connector->connector_id, m_fd); | ||||
417 | drmOutput->m_conn->setOutput(drmOutput); | ||||
368 | 418 | | |||
369 | if (m_atomicModeSetting) { | 419 | if (m_atomicModeSetting) { | ||
370 | drmOutput->m_crtc = new DrmCrtc(crtcId, m_fd); | 420 | if (!drmOutput->m_crtc->init()) { | ||
371 | if (drmOutput->m_crtc->init()) { | | |||
372 | drmOutput->m_crtc->setOutput(drmOutput); | | |||
373 | } else { | | |||
374 | qCWarning(KWIN_DRM) << "Crtc object failed, skipping output on connector" << connector->connector_id; | 421 | qCWarning(KWIN_DRM) << "Crtc object failed, skipping output on connector" << connector->connector_id; | ||
375 | delete drmOutput->m_crtc; | | |||
376 | delete drmOutput; | 422 | delete drmOutput; | ||
377 | continue; | 423 | continue; | ||
378 | } | 424 | } | ||
379 | 425 | | |||
380 | drmOutput->m_conn = new DrmConnector(connector->connector_id, m_fd); | 426 | if (!drmOutput->m_conn->init()) { | ||
381 | if (drmOutput->m_conn->init()) { | | |||
382 | drmOutput->m_conn->setOutput(drmOutput); | | |||
383 | } else { | | |||
384 | qCWarning(KWIN_DRM) << "Connector object failed, skipping output on connector" << connector->connector_id; | 427 | qCWarning(KWIN_DRM) << "Connector object failed, skipping output on connector" << connector->connector_id; | ||
385 | delete drmOutput->m_conn; | | |||
386 | delete drmOutput; | 428 | delete drmOutput; | ||
387 | continue; | 429 | continue; | ||
388 | } | 430 | } | ||
389 | } | 431 | } | ||
390 | 432 | | |||
391 | if (crtc->mode_valid) { | 433 | if (modeCrtc->mode_valid) { | ||
392 | drmOutput->m_mode = crtc->mode; | 434 | drmOutput->m_mode = modeCrtc->mode; | ||
393 | } else { | 435 | } else { | ||
394 | drmOutput->m_mode = connector->modes[0]; | 436 | drmOutput->m_mode = connector->modes[0]; | ||
395 | } | 437 | } | ||
396 | qCDebug(KWIN_DRM) << "For new output use mode " << drmOutput->m_mode.name; | 438 | qCDebug(KWIN_DRM) << "For new output use mode " << drmOutput->m_mode.name; | ||
397 | 439 | | |||
398 | if (!drmOutput->init(connector.data())) { | 440 | if (!drmOutput->init(connector.data())) { | ||
399 | qCWarning(KWIN_DRM) << "Failed to create output for connector " << connector->connector_id; | 441 | qCWarning(KWIN_DRM) << "Failed to create output for connector " << connector->connector_id; | ||
400 | delete drmOutput; | 442 | delete drmOutput; | ||
401 | continue; | 443 | continue; | ||
402 | } | 444 | } | ||
403 | qCDebug(KWIN_DRM) << "Found new output with uuid" << drmOutput->uuid(); | 445 | qCDebug(KWIN_DRM) << "Found new output with uuid" << drmOutput->uuid(); | ||
404 | connectedOutputs << drmOutput; | 446 | connectedOutputs << drmOutput; | ||
405 | } | 447 | } | ||
406 | std::sort(connectedOutputs.begin(), connectedOutputs.end(), [] (DrmOutput *a, DrmOutput *b) { return a->m_connector < b->m_connector; }); | 448 | std::sort(connectedOutputs.begin(), connectedOutputs.end(), [] (DrmOutput *a, DrmOutput *b) { return a->m_conn->id() < b->m_conn->id(); }); | ||
407 | // check for outputs which got removed | 449 | // check for outputs which got removed | ||
408 | auto it = m_outputs.begin(); | 450 | auto it = m_outputs.begin(); | ||
409 | while (it != m_outputs.end()) { | 451 | while (it != m_outputs.end()) { | ||
410 | if (connectedOutputs.contains(*it)) { | 452 | if (connectedOutputs.contains(*it)) { | ||
411 | it++; | 453 | it++; | ||
412 | continue; | 454 | continue; | ||
413 | } | 455 | } | ||
414 | DrmOutput *removed = *it; | 456 | DrmOutput *removed = *it; | ||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Line(s) | 509 | for (auto it = changes.begin(); it != changes.end(); it++) { | |||
476 | drmoutput->setChanges(changeset); | 518 | drmoutput->setChanges(changeset); | ||
477 | } | 519 | } | ||
478 | emit screens()->changed(); | 520 | emit screens()->changed(); | ||
479 | } | 521 | } | ||
480 | 522 | | |||
481 | DrmOutput *DrmBackend::findOutput(quint32 connector) | 523 | DrmOutput *DrmBackend::findOutput(quint32 connector) | ||
482 | { | 524 | { | ||
483 | auto it = std::find_if(m_outputs.constBegin(), m_outputs.constEnd(), [connector] (DrmOutput *o) { | 525 | auto it = std::find_if(m_outputs.constBegin(), m_outputs.constEnd(), [connector] (DrmOutput *o) { | ||
484 | return o->m_connector == connector; | 526 | return o->m_conn->id() == connector; | ||
485 | }); | 527 | }); | ||
486 | if (it != m_outputs.constEnd()) { | 528 | if (it != m_outputs.constEnd()) { | ||
487 | return *it; | 529 | return *it; | ||
488 | } | 530 | } | ||
489 | return nullptr; | 531 | return nullptr; | ||
490 | } | 532 | } | ||
491 | 533 | | |||
492 | DrmOutput *DrmBackend::findOutput(const QByteArray &uuid) | 534 | DrmOutput *DrmBackend::findOutput(const QByteArray &uuid) | ||
493 | { | 535 | { | ||
494 | auto it = std::find_if(m_outputs.constBegin(), m_outputs.constEnd(), [uuid] (DrmOutput *o) { | 536 | auto it = std::find_if(m_outputs.constBegin(), m_outputs.constEnd(), [uuid] (DrmOutput *o) { | ||
495 | return o->m_uuid == uuid; | 537 | return o->m_uuid == uuid; | ||
496 | }); | 538 | }); | ||
497 | if (it != m_outputs.constEnd()) { | 539 | if (it != m_outputs.constEnd()) { | ||
498 | return *it; | 540 | return *it; | ||
499 | } | 541 | } | ||
500 | return nullptr; | 542 | return nullptr; | ||
501 | } | 543 | } | ||
502 | 544 | | |||
503 | quint32 DrmBackend::findCrtc(drmModeRes *res, drmModeConnector *connector, bool *ok) | 545 | bool DrmBackend::present(DrmBuffer *buffer, DrmOutput *output) | ||
504 | { | | |||
505 | if (ok) { | | |||
506 | *ok = false; | | |||
507 | } | | |||
508 | ScopedDrmPointer<_drmModeEncoder, &drmModeFreeEncoder> encoder(drmModeGetEncoder(m_fd, connector->encoder_id)); | | |||
509 | if (encoder) { | | |||
510 | if (!crtcIsUsed(encoder->crtc_id)) { | | |||
511 | if (ok) { | | |||
512 | *ok = true; | | |||
513 | } | | |||
514 | return encoder->crtc_id; | | |||
515 | } | | |||
516 | } | | |||
517 | // let's iterate over all encoders to find a suitable crtc | | |||
518 | for (int i = 0; i < connector->count_encoders; ++i) { | | |||
519 | ScopedDrmPointer<_drmModeEncoder, &drmModeFreeEncoder> encoder(drmModeGetEncoder(m_fd, connector->encoders[i])); | | |||
520 | if (!encoder) { | | |||
521 | continue; | | |||
522 | } | | |||
523 | for (int j = 0; j < res->count_crtcs; ++j) { | | |||
524 | if (!(encoder->possible_crtcs & (1 << j))) { | | |||
525 | continue; | | |||
526 | } | | |||
527 | if (!crtcIsUsed(res->crtcs[j])) { | | |||
528 | if (ok) { | | |||
529 | *ok = true; | | |||
530 | } | | |||
531 | return res->crtcs[j]; | | |||
532 | } | | |||
533 | } | | |||
534 | } | | |||
535 | return 0; | | |||
536 | } | | |||
537 | | ||||
538 | bool DrmBackend::crtcIsUsed(quint32 crtc) | | |||
539 | { | | |||
540 | auto it = std::find_if(m_outputs.constBegin(), m_outputs.constEnd(), | | |||
541 | [crtc] (DrmOutput *o) { | | |||
542 | return o->m_crtcId == crtc; | | |||
543 | } | | |||
544 | ); | | |||
545 | return it != m_outputs.constEnd(); | | |||
546 | } | | |||
547 | | ||||
548 | void DrmBackend::present(DrmBuffer *buffer, DrmOutput *output) | | |||
549 | { | 546 | { | ||
550 | if (output->present(buffer)) { | 547 | if (output->present(buffer)) { | ||
551 | m_pageFlipsPending++; | 548 | m_pageFlipsPending++; | ||
552 | if (m_pageFlipsPending == 1 && Compositor::self()) { | 549 | if (m_pageFlipsPending == 1 && Compositor::self()) { | ||
553 | Compositor::self()->aboutToSwapBuffers(); | 550 | Compositor::self()->aboutToSwapBuffers(); | ||
554 | } | 551 | } | ||
552 | return true; | ||||
553 | } else { | ||||
554 | return false; | ||||
555 | } | 555 | } | ||
556 | } | 556 | } | ||
557 | 557 | | |||
558 | void DrmBackend::initCursor() | 558 | void DrmBackend::initCursor() | ||
559 | { | 559 | { | ||
560 | m_cursorEnabled = waylandServer()->seat()->hasPointer(); | 560 | m_cursorEnabled = waylandServer()->seat()->hasPointer(); | ||
561 | connect(waylandServer()->seat(), &KWayland::Server::SeatInterface::hasPointerChanged, this, | 561 | connect(waylandServer()->seat(), &KWayland::Server::SeatInterface::hasPointerChanged, this, | ||
562 | [this] { | 562 | [this] { | ||
Show All 36 Lines | |||||
599 | } | 599 | } | ||
600 | // now we have screens and can set cursors, so start tracking | 600 | // now we have screens and can set cursors, so start tracking | ||
601 | connect(this, &DrmBackend::cursorChanged, this, &DrmBackend::updateCursor); | 601 | connect(this, &DrmBackend::cursorChanged, this, &DrmBackend::updateCursor); | ||
602 | connect(Cursor::self(), &Cursor::posChanged, this, &DrmBackend::moveCursor); | 602 | connect(Cursor::self(), &Cursor::posChanged, this, &DrmBackend::moveCursor); | ||
603 | } | 603 | } | ||
604 | 604 | | |||
605 | void DrmBackend::setCursor() | 605 | void DrmBackend::setCursor() | ||
606 | { | 606 | { | ||
607 | DrmBuffer *c = m_cursor[m_cursorIndex]; | 607 | DrmDumbBuffer *c = m_cursor[m_cursorIndex]; | ||
608 | m_cursorIndex = (m_cursorIndex + 1) % 2; | 608 | m_cursorIndex = (m_cursorIndex + 1) % 2; | ||
609 | if (m_cursorEnabled) { | 609 | if (m_cursorEnabled) { | ||
610 | for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { | 610 | for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { | ||
611 | (*it)->showCursor(c); | 611 | (*it)->showCursor(c); | ||
612 | } | 612 | } | ||
613 | } | 613 | } | ||
614 | markCursorAsRendered(); | 614 | markCursorAsRendered(); | ||
615 | } | 615 | } | ||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Line(s) | |||||
666 | 666 | | |||
667 | Screens *DrmBackend::createScreens(QObject *parent) | 667 | Screens *DrmBackend::createScreens(QObject *parent) | ||
668 | { | 668 | { | ||
669 | return new DrmScreens(this, parent); | 669 | return new DrmScreens(this, parent); | ||
670 | } | 670 | } | ||
671 | 671 | | |||
672 | QPainterBackend *DrmBackend::createQPainterBackend() | 672 | QPainterBackend *DrmBackend::createQPainterBackend() | ||
673 | { | 673 | { | ||
674 | m_deleteBufferAfterPageFlip = false; | ||||
674 | return new DrmQPainterBackend(this); | 675 | return new DrmQPainterBackend(this); | ||
675 | } | 676 | } | ||
676 | 677 | | |||
677 | OpenGLBackend *DrmBackend::createOpenGLBackend() | 678 | OpenGLBackend *DrmBackend::createOpenGLBackend() | ||
678 | { | 679 | { | ||
680 | m_deleteBufferAfterPageFlip = true; | ||||
679 | #if HAVE_GBM | 681 | #if HAVE_GBM | ||
680 | return new EglGbmBackend(this); | 682 | return new EglGbmBackend(this); | ||
681 | #else | 683 | #else | ||
682 | return Platform::createOpenGLBackend(); | 684 | return Platform::createOpenGLBackend(); | ||
683 | #endif | 685 | #endif | ||
684 | } | 686 | } | ||
685 | 687 | | |||
686 | DrmBuffer *DrmBackend::createBuffer(const QSize &size) | 688 | DrmDumbBuffer *DrmBackend::createBuffer(const QSize &size) | ||
687 | { | 689 | { | ||
688 | DrmBuffer *b = new DrmBuffer(this, size); | 690 | DrmDumbBuffer *b = new DrmDumbBuffer(this, size); | ||
689 | m_buffers << b; | | |||
690 | return b; | 691 | return b; | ||
691 | } | 692 | } | ||
692 | 693 | | |||
693 | DrmBuffer *DrmBackend::createBuffer(gbm_surface *surface) | 694 | DrmSurfaceBuffer *DrmBackend::createBuffer(gbm_surface *surface) | ||
694 | { | 695 | { | ||
695 | #if HAVE_GBM | 696 | #if HAVE_GBM | ||
696 | DrmBuffer *b = new DrmBuffer(this, surface); | 697 | DrmSurfaceBuffer *b = new DrmSurfaceBuffer(this, surface); | ||
697 | b->m_deleteAfterPageFlip = true; | | |||
698 | m_buffers << b; | | |||
699 | return b; | 698 | return b; | ||
700 | #else | 699 | #else | ||
701 | return nullptr; | 700 | return nullptr; | ||
702 | #endif | 701 | #endif | ||
703 | } | 702 | } | ||
704 | 703 | | |||
705 | void DrmBackend::bufferDestroyed(DrmBuffer *b) | 704 | DrmImportBuffer *DrmBackend::createDirectScanoutBuffer(KWayland::Server::BufferInterface *buffer) | ||
706 | { | 705 | { | ||
707 | m_buffers.removeAll(b); | 706 | #if HAVE_GBM | ||
707 | DrmImportBuffer *b = new DrmImportBuffer(this, buffer); | ||||
708 | return b; | ||||
709 | #else | ||||
710 | return nullptr; | ||||
711 | #endif | ||||
708 | } | 712 | } | ||
709 | 713 | | |||
710 | void DrmBackend::outputDpmsChanged() | 714 | void DrmBackend::outputDpmsChanged() | ||
711 | { | 715 | { | ||
712 | if (m_outputs.isEmpty()) { | 716 | if (m_outputs.isEmpty()) { | ||
713 | return; | 717 | return; | ||
714 | } | 718 | } | ||
715 | bool enabled = false; | 719 | bool enabled = false; | ||
716 | for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { | 720 | for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { | ||
717 | enabled = enabled || (*it)->isDpmsEnabled(); | 721 | enabled = enabled || (*it)->isDpmsEnabled(); | ||
718 | } | 722 | } | ||
719 | setOutputsEnabled(enabled); | 723 | setOutputsEnabled(enabled); | ||
720 | } | 724 | } | ||
721 | 725 | | |||
722 | | ||||
723 | } | 726 | } |