Changeset View
Changeset View
Standalone View
Standalone View
plugins/platforms/drm/drm_output.cpp
Show First 20 Lines • Show All 464 Lines • ▼ Show 20 Line(s) | 461 | for (int i = 0; i < connector->count_props; ++i) { | |||
---|---|---|---|---|---|
465 | } | 465 | } | ||
466 | if (qstrcmp(property->name, "DPMS") == 0) { | 466 | if (qstrcmp(property->name, "DPMS") == 0) { | ||
467 | m_dpms.swap(property); | 467 | m_dpms.swap(property); | ||
468 | break; | 468 | break; | ||
469 | } | 469 | } | ||
470 | } | 470 | } | ||
471 | } | 471 | } | ||
472 | 472 | | |||
473 | void DrmOutput::updateEnablement(bool enable) | ||||
474 | { | ||||
475 | if (enable) { | ||||
476 | m_dpmsModePending = DpmsMode::On; | ||||
477 | if (m_backend->atomicModeSetting()) { | ||||
478 | atomicEnable(); | ||||
479 | } else { | ||||
480 | if (dpmsLegacyApply()) { | ||||
481 | m_backend->enableOutput(this, true); | ||||
482 | } | ||||
483 | } | ||||
484 | | ||||
485 | } else { | ||||
486 | m_dpmsModePending = DpmsMode::Off; | ||||
487 | if (m_backend->atomicModeSetting()) { | ||||
488 | atomicDisable(); | ||||
489 | } else { | ||||
490 | if (dpmsLegacyApply()) { | ||||
491 | m_backend->enableOutput(this, false); | ||||
492 | } | ||||
493 | } | ||||
494 | } | ||||
495 | } | ||||
496 | | ||||
497 | void DrmOutput::atomicEnable() | ||||
498 | { | ||||
499 | m_modesetRequested = true; | ||||
500 | | ||||
501 | if (m_atomicOffPending) { | ||||
502 | Q_ASSERT(m_pageFlipPending); | ||||
503 | m_atomicOffPending = false; | ||||
504 | } | ||||
505 | m_backend->enableOutput(this, true); | ||||
506 | | ||||
507 | if (Compositor *compositor = Compositor::self()) { | ||||
508 | compositor->addRepaintFull(); | ||||
509 | } | ||||
510 | } | ||||
511 | | ||||
512 | void DrmOutput::atomicDisable() | ||||
513 | { | ||||
514 | m_modesetRequested = true; | ||||
515 | | ||||
516 | m_backend->enableOutput(this, false); | ||||
517 | m_atomicOffPending = true; | ||||
518 | if (!m_pageFlipPending) { | ||||
519 | dpmsAtomicOff(); | ||||
520 | } | ||||
521 | } | ||||
522 | | ||||
473 | static DrmOutput::DpmsMode fromWaylandDpmsMode(KWayland::Server::OutputInterface::DpmsMode wlMode) | 523 | static DrmOutput::DpmsMode fromWaylandDpmsMode(KWayland::Server::OutputInterface::DpmsMode wlMode) | ||
474 | { | 524 | { | ||
475 | using namespace KWayland::Server; | 525 | using namespace KWayland::Server; | ||
476 | switch (wlMode) { | 526 | switch (wlMode) { | ||
477 | case OutputInterface::DpmsMode::On: | 527 | case OutputInterface::DpmsMode::On: | ||
478 | return DrmOutput::DpmsMode::On; | 528 | return DrmOutput::DpmsMode::On; | ||
479 | case OutputInterface::DpmsMode::Standby: | 529 | case OutputInterface::DpmsMode::Standby: | ||
480 | return DrmOutput::DpmsMode::Standby; | 530 | return DrmOutput::DpmsMode::Standby; | ||
Show All 20 Lines | 550 | case DrmOutput::DpmsMode::Off: | |||
501 | return OutputInterface::DpmsMode::Off; | 551 | return OutputInterface::DpmsMode::Off; | ||
502 | default: | 552 | default: | ||
503 | Q_UNREACHABLE(); | 553 | Q_UNREACHABLE(); | ||
504 | } | 554 | } | ||
505 | } | 555 | } | ||
506 | 556 | | |||
507 | void DrmOutput::updateDpms(KWayland::Server::OutputInterface::DpmsMode mode) | 557 | void DrmOutput::updateDpms(KWayland::Server::OutputInterface::DpmsMode mode) | ||
508 | { | 558 | { | ||
509 | if (m_dpms.isNull()) { | 559 | if (m_dpms.isNull() || !isEnabled()) { | ||
510 | return; | 560 | return; | ||
511 | } | 561 | } | ||
512 | 562 | | |||
513 | const auto drmMode = fromWaylandDpmsMode(mode); | 563 | const auto drmMode = fromWaylandDpmsMode(mode); | ||
564 | | ||||
514 | if (drmMode == m_dpmsModePending) { | 565 | if (drmMode == m_dpmsModePending) { | ||
515 | qCDebug(KWIN_DRM) << "New DPMS mode equals old mode. DPMS unchanged."; | 566 | qCDebug(KWIN_DRM) << "New DPMS mode equals old mode. DPMS unchanged."; | ||
516 | return; | 567 | return; | ||
517 | } | 568 | } | ||
518 | 569 | | |||
519 | m_dpmsModePending = drmMode; | 570 | m_dpmsModePending = drmMode; | ||
520 | 571 | | |||
521 | if (m_backend->atomicModeSetting()) { | 572 | if (m_backend->atomicModeSetting()) { | ||
522 | m_modesetRequested = true; | 573 | m_modesetRequested = true; | ||
523 | if (drmMode == DpmsMode::On) { | 574 | if (drmMode == DpmsMode::On) { | ||
524 | if (m_pageFlipPending) { | 575 | if (m_atomicOffPending) { | ||
525 | m_pageFlipPending = false; | 576 | Q_ASSERT(m_pageFlipPending); | ||
526 | Compositor::self()->bufferSwapComplete(); | 577 | m_atomicOffPending = false; | ||
527 | } | 578 | } | ||
528 | dpmsOnHandler(); | 579 | dpmsFinishOn(); | ||
529 | } else { | 580 | } else { | ||
530 | m_dpmsAtomicOffPending = true; | 581 | m_atomicOffPending = true; | ||
531 | if (!m_pageFlipPending) { | 582 | if (!m_pageFlipPending) { | ||
532 | dpmsAtomicOff(); | 583 | dpmsAtomicOff(); | ||
533 | } | 584 | } | ||
534 | } | 585 | } | ||
535 | } else { | 586 | } else { | ||
536 | if (drmModeConnectorSetProperty(m_backend->fd(), m_conn->id(), m_dpms->prop_id, uint64_t(drmMode)) < 0) { | 587 | dpmsLegacyApply(); | ||
537 | m_dpmsModePending = m_dpmsMode; | | |||
538 | qCWarning(KWIN_DRM) << "Setting DPMS failed"; | | |||
539 | return; | | |||
540 | } | | |||
541 | if (drmMode == DpmsMode::On) { | | |||
542 | dpmsOnHandler(); | | |||
543 | } else { | | |||
544 | dpmsOffHandler(); | | |||
545 | } | | |||
546 | m_dpmsMode = m_dpmsModePending; | | |||
547 | } | 588 | } | ||
548 | } | 589 | } | ||
549 | 590 | | |||
550 | void DrmOutput::dpmsOnHandler() | 591 | void DrmOutput::dpmsFinishOn() | ||
551 | { | 592 | { | ||
552 | qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to On."; | 593 | qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to On."; | ||
553 | 594 | | |||
554 | auto wlOutput = waylandOutput(); | 595 | auto wlOutput = waylandOutput(); | ||
555 | if (wlOutput) { | 596 | if (wlOutput) { | ||
556 | wlOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); | 597 | wlOutput->setDpmsMode(toWaylandDpmsMode(DpmsMode::On)); | ||
557 | } | 598 | } | ||
558 | emit dpmsChanged(); | | |||
559 | 599 | | |||
560 | m_backend->checkOutputsAreOn(); | 600 | m_backend->checkOutputsAreOn(); | ||
561 | if (!m_backend->atomicModeSetting()) { | 601 | if (!m_backend->atomicModeSetting()) { | ||
562 | m_crtc->blank(); | 602 | m_crtc->blank(); | ||
563 | } | 603 | } | ||
564 | if (Compositor *compositor = Compositor::self()) { | 604 | if (Compositor *compositor = Compositor::self()) { | ||
565 | compositor->addRepaintFull(); | 605 | compositor->addRepaintFull(); | ||
566 | } | 606 | } | ||
567 | } | 607 | } | ||
568 | 608 | | |||
569 | void DrmOutput::dpmsOffHandler() | 609 | void DrmOutput::dpmsFinishOff() | ||
570 | { | 610 | { | ||
571 | qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to Off."; | 611 | qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to Off."; | ||
572 | 612 | | |||
573 | auto wlOutput = waylandOutput(); | 613 | if (isEnabled()) { | ||
574 | if (wlOutput) { | 614 | waylandOutput()->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); | ||
575 | wlOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); | 615 | m_backend->createDpmsFilter(); | ||
616 | } | ||||
576 | } | 617 | } | ||
577 | emit dpmsChanged(); | | |||
578 | 618 | | |||
579 | m_backend->outputWentOff(); | 619 | bool DrmOutput::dpmsLegacyApply() | ||
620 | { | ||||
621 | if (drmModeConnectorSetProperty(m_backend->fd(), m_conn->id(), | ||||
622 | m_dpms->prop_id, uint64_t(m_dpmsModePending)) < 0) { | ||||
623 | m_dpmsModePending = m_dpmsMode; | ||||
624 | qCWarning(KWIN_DRM) << "Setting DPMS failed"; | ||||
625 | return false; | ||||
626 | } | ||||
627 | if (m_dpmsModePending == DpmsMode::On) { | ||||
628 | dpmsFinishOn(); | ||||
629 | } else { | ||||
630 | dpmsFinishOff(); | ||||
631 | } | ||||
632 | m_dpmsMode = m_dpmsModePending; | ||||
633 | return true; | ||||
580 | } | 634 | } | ||
581 | 635 | | |||
582 | void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform transform) | 636 | void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform transform) | ||
583 | { | 637 | { | ||
584 | waylandOutputDevice()->setTransform(transform); | 638 | waylandOutputDevice()->setTransform(transform); | ||
585 | using KWayland::Server::OutputDeviceInterface; | 639 | using KWayland::Server::OutputDeviceInterface; | ||
586 | using KWayland::Server::OutputInterface; | 640 | using KWayland::Server::OutputInterface; | ||
587 | auto wlOutput = waylandOutput(); | 641 | auto wlOutput = waylandOutput(); | ||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Line(s) | |||||
677 | void DrmOutput::setWaylandMode() | 731 | void DrmOutput::setWaylandMode() | ||
678 | { | 732 | { | ||
679 | AbstractWaylandOutput::setWaylandMode(QSize(m_mode.hdisplay, m_mode.vdisplay), | 733 | AbstractWaylandOutput::setWaylandMode(QSize(m_mode.hdisplay, m_mode.vdisplay), | ||
680 | refreshRateForMode(&m_mode)); | 734 | refreshRateForMode(&m_mode)); | ||
681 | } | 735 | } | ||
682 | 736 | | |||
683 | void DrmOutput::pageFlipped() | 737 | void DrmOutput::pageFlipped() | ||
684 | { | 738 | { | ||
739 | Q_ASSERT(m_pageFlipPending); | ||||
685 | m_pageFlipPending = false; | 740 | m_pageFlipPending = false; | ||
686 | if (m_deleted) { | 741 | if (m_deleted) { | ||
687 | deleteLater(); | 742 | deleteLater(); | ||
688 | return; | 743 | return; | ||
689 | } | 744 | } | ||
690 | 745 | | |||
691 | if (!m_crtc) { | 746 | if (!m_crtc) { | ||
692 | return; | 747 | return; | ||
Show All 31 Lines | 778 | for (DrmPlane *p : m_nextPlanesFlipList) { | |||
724 | p->flipBuffer(); | 779 | p->flipBuffer(); | ||
725 | } | 780 | } | ||
726 | m_nextPlanesFlipList.clear(); | 781 | m_nextPlanesFlipList.clear(); | ||
727 | } else { | 782 | } else { | ||
728 | m_crtc->flipBuffer(); | 783 | m_crtc->flipBuffer(); | ||
729 | } | 784 | } | ||
730 | m_crtc->flipBuffer(); | 785 | m_crtc->flipBuffer(); | ||
731 | } | 786 | } | ||
787 | | ||||
788 | if (m_atomicOffPending) { | ||||
789 | dpmsAtomicOff(); | ||||
790 | } | ||||
732 | } | 791 | } | ||
733 | 792 | | |||
734 | bool DrmOutput::present(DrmBuffer *buffer) | 793 | bool DrmOutput::present(DrmBuffer *buffer) | ||
735 | { | 794 | { | ||
795 | if (m_dpmsModePending != DpmsMode::On) { | ||||
796 | return false; | ||||
797 | } | ||||
736 | if (m_backend->atomicModeSetting()) { | 798 | if (m_backend->atomicModeSetting()) { | ||
737 | return presentAtomically(buffer); | 799 | return presentAtomically(buffer); | ||
738 | } else { | 800 | } else { | ||
739 | return presentLegacy(buffer); | 801 | return presentLegacy(buffer); | ||
740 | } | 802 | } | ||
741 | } | 803 | } | ||
742 | 804 | | |||
743 | bool DrmOutput::dpmsAtomicOff() | 805 | bool DrmOutput::dpmsAtomicOff() | ||
744 | { | 806 | { | ||
745 | m_dpmsAtomicOffPending = false; | 807 | m_atomicOffPending = false; | ||
746 | 808 | | |||
747 | // TODO: With multiple planes: deactivate all of them here | 809 | // TODO: With multiple planes: deactivate all of them here | ||
748 | delete m_primaryPlane->next(); | 810 | delete m_primaryPlane->next(); | ||
749 | m_primaryPlane->setNext(nullptr); | 811 | m_primaryPlane->setNext(nullptr); | ||
750 | m_nextPlanesFlipList << m_primaryPlane; | 812 | m_nextPlanesFlipList << m_primaryPlane; | ||
751 | 813 | | |||
752 | if (!doAtomicCommit(AtomicCommitMode::Test)) { | 814 | if (!doAtomicCommit(AtomicCommitMode::Test)) { | ||
753 | qCDebug(KWIN_DRM) << "Atomic test commit to Dpms Off failed. Aborting."; | 815 | qCDebug(KWIN_DRM) << "Atomic test commit to Dpms Off failed. Aborting."; | ||
754 | return false; | 816 | return false; | ||
755 | } | 817 | } | ||
756 | if (!doAtomicCommit(AtomicCommitMode::Real)) { | 818 | if (!doAtomicCommit(AtomicCommitMode::Real)) { | ||
757 | qCDebug(KWIN_DRM) << "Atomic commit to Dpms Off failed. This should have never happened! Aborting."; | 819 | qCDebug(KWIN_DRM) << "Atomic commit to Dpms Off failed. This should have never happened! Aborting."; | ||
758 | return false; | 820 | return false; | ||
759 | } | 821 | } | ||
760 | m_nextPlanesFlipList.clear(); | 822 | m_nextPlanesFlipList.clear(); | ||
761 | dpmsOffHandler(); | 823 | dpmsFinishOff(); | ||
762 | 824 | | |||
763 | return true; | 825 | return true; | ||
764 | | ||||
765 | } | 826 | } | ||
766 | 827 | | |||
767 | bool DrmOutput::presentAtomically(DrmBuffer *buffer) | 828 | bool DrmOutput::presentAtomically(DrmBuffer *buffer) | ||
768 | { | 829 | { | ||
769 | if (!LogindIntegration::self()->isActiveSession()) { | 830 | if (!LogindIntegration::self()->isActiveSession()) { | ||
770 | qCWarning(KWIN_DRM) << "Logind session not active."; | 831 | qCWarning(KWIN_DRM) << "Logind session not active."; | ||
771 | return false; | 832 | return false; | ||
772 | } | 833 | } | ||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Line(s) | |||||
834 | { | 895 | { | ||
835 | if (m_crtc->next()) { | 896 | if (m_crtc->next()) { | ||
836 | return false; | 897 | return false; | ||
837 | } | 898 | } | ||
838 | if (!LogindIntegration::self()->isActiveSession()) { | 899 | if (!LogindIntegration::self()->isActiveSession()) { | ||
839 | m_crtc->setNext(buffer); | 900 | m_crtc->setNext(buffer); | ||
840 | return false; | 901 | return false; | ||
841 | } | 902 | } | ||
842 | if (m_dpmsMode != DpmsMode::On) { | | |||
843 | return false; | | |||
844 | } | | |||
845 | 903 | | |||
846 | // Do we need to set a new mode first? | 904 | // Do we need to set a new mode first? | ||
847 | if (!m_crtc->current() || m_crtc->current()->needsModeChange(buffer)) { | 905 | if (!m_crtc->current() || m_crtc->current()->needsModeChange(buffer)) { | ||
848 | if (!setModeLegacy(buffer)) { | 906 | if (!setModeLegacy(buffer)) { | ||
849 | return false; | 907 | return false; | ||
850 | } | 908 | } | ||
851 | } | 909 | } | ||
852 | const bool ok = drmModePageFlip(m_backend->fd(), m_crtc->id(), buffer->bufferId(), DRM_MODE_PAGE_FLIP_EVENT, this) == 0; | 910 | const bool ok = drmModePageFlip(m_backend->fd(), m_crtc->id(), buffer->bufferId(), DRM_MODE_PAGE_FLIP_EVENT, this) == 0; | ||
Show All 27 Lines | 934 | auto errorHandler = [this, mode, req] () { | |||
880 | if (req) { | 938 | if (req) { | ||
881 | drmModeAtomicFree(req); | 939 | drmModeAtomicFree(req); | ||
882 | } | 940 | } | ||
883 | 941 | | |||
884 | if (m_dpmsMode != m_dpmsModePending) { | 942 | if (m_dpmsMode != m_dpmsModePending) { | ||
885 | qCWarning(KWIN_DRM) << "Setting DPMS failed"; | 943 | qCWarning(KWIN_DRM) << "Setting DPMS failed"; | ||
886 | m_dpmsModePending = m_dpmsMode; | 944 | m_dpmsModePending = m_dpmsMode; | ||
887 | if (m_dpmsMode != DpmsMode::On) { | 945 | if (m_dpmsMode != DpmsMode::On) { | ||
888 | dpmsOffHandler(); | 946 | dpmsFinishOff(); | ||
889 | } | 947 | } | ||
890 | } | 948 | } | ||
891 | 949 | | |||
892 | // TODO: see above, rework later for overlay planes! | 950 | // TODO: see above, rework later for overlay planes! | ||
893 | for (DrmPlane *p : m_nextPlanesFlipList) { | 951 | for (DrmPlane *p : m_nextPlanesFlipList) { | ||
894 | p->setNext(nullptr); | 952 | p->setNext(nullptr); | ||
895 | } | 953 | } | ||
896 | m_nextPlanesFlipList.clear(); | 954 | m_nextPlanesFlipList.clear(); | ||
▲ Show 20 Lines • Show All 175 Lines • Show Last 20 Lines |