Changeset View
Changeset View
Standalone View
Standalone View
composite.cpp
| Show First 20 Lines • Show All 779 Lines • ▼ Show 20 Line(s) | 774 | { | |||
|---|---|---|---|---|---|
| 780 | if (m_bufferSwapPending && m_composeAtSwapCompletion) | 780 | if (m_bufferSwapPending && m_composeAtSwapCompletion) | ||
| 781 | return; | 781 | return; | ||
| 782 | 782 | | |||
| 783 | // Don't start the timer if all outputs are disabled | 783 | // Don't start the timer if all outputs are disabled | ||
| 784 | if (!kwinApp()->platform()->areOutputsEnabled()) { | 784 | if (!kwinApp()->platform()->areOutputsEnabled()) { | ||
| 785 | return; | 785 | return; | ||
| 786 | } | 786 | } | ||
| 787 | 787 | | |||
| 788 | uint waitTime = 1; | 788 | uint waitTime = 1000 / refreshRate(); | ||
| 789 | | ||||
| 790 | if (m_scene->blocksForRetrace()) { | | |||
| 791 | | ||||
| 792 | // TODO: make vBlankTime dynamic?! | | |||
| 793 | // It's required because glXWaitVideoSync will *likely* block a full frame if one enters | | |||
| 794 | // a retrace pass which can last a variable amount of time, depending on the actual screen | | |||
| 795 | // Now, my ooold 19" CRT can do such retrace so that 2ms are entirely sufficient, | | |||
| 796 | // while another ooold 15" TFT requires about 6ms | | |||
| 797 | | ||||
| 798 | qint64 padding = m_timeSinceLastVBlank; | | |||
| 799 | if (padding > fpsInterval) { | | |||
| 800 | // We're at low repaints or spent more time in painting than the user wanted to wait | | |||
| 801 | // for that frame. Align to next vblank: | | |||
| 802 | padding = vBlankInterval - (padding % vBlankInterval); | | |||
| 803 | } else { | | |||
| 804 | // Align to the next maxFps tick: | | |||
| 805 | // "remaining time of the first vsync" + "time for the other vsyncs of the frame" | | |||
| 806 | padding = ((vBlankInterval - padding % vBlankInterval) + | | |||
| 807 | (fpsInterval / vBlankInterval - 1) * vBlankInterval); | | |||
| 808 | } | | |||
| 809 | | ||||
| 810 | if (padding < options->vBlankTime()) { | | |||
| 811 | // We'll likely miss this frame so we add one: | | |||
| 812 | waitTime = nanoToMilli(padding + vBlankInterval - options->vBlankTime()); | | |||
| 813 | } else { | | |||
| 814 | waitTime = nanoToMilli(padding - options->vBlankTime()); | | |||
| 815 | } | | |||
zzag: I think we still need some of this code. Syncing to vblank will be a problem though. | |||||
| 816 | } | | |||
| 817 | else { // w/o blocking vsync we just jump to the next demanded tick | | |||
| 818 | if (fpsInterval > m_timeSinceLastVBlank) { | | |||
| 819 | waitTime = nanoToMilli(fpsInterval - m_timeSinceLastVBlank); | | |||
| 820 | if (!waitTime) { | | |||
| 821 | // Will ensure we don't block out the eventloop - the system's just not faster ... | | |||
| 822 | waitTime = 1; | | |||
| 823 | } | | |||
| 824 | } | | |||
| 825 | /* else if (m_timeSinceLastVBlank - fpsInterval < (vBlankInterval<<1)) { | | |||
| 826 | // NOTICE - "for later" ------------------------------------------------------------------ | | |||
| 827 | // It can happen that we push two frames within one refresh cycle. | | |||
| 828 | // Swapping will then block even with triple buffering when the GPU does not discard but | | |||
| 829 | // queues frames | | |||
| 830 | // now here's the mean part: if we take that as "OMG, we're late - next frame ASAP", | | |||
| 831 | // there'll immediately be 2 frames in the pipe, swapping will block, we think we're | | |||
| 832 | // late ... ewww | | |||
| 833 | // so instead we pad to the clock again and add 2ms safety to ensure the pipe is really | | |||
| 834 | // free | | |||
| 835 | // NOTICE: obviously m_timeSinceLastVBlank can be too big because we're too slow as well | | |||
| 836 | // So if this code was enabled, we'd needlessly half the framerate once more (15 instead of 30) | | |||
| 837 | waitTime = nanoToMilli(vBlankInterval - (m_timeSinceLastVBlank - fpsInterval)%vBlankInterval) + 2; | | |||
| 838 | }*/ | | |||
| 839 | else { | | |||
| 840 | // "0" would be sufficient here, but the compositor isn't the WMs only task. | | |||
| 841 | waitTime = 1; | | |||
| 842 | } | | |||
| 843 | } | | |||
| 844 | // Force 4fps minimum: | 789 | // Force 4fps minimum: | ||
| 845 | compositeTimer.start(qMin(waitTime, 250u), this); | 790 | compositeTimer.start(qMin(waitTime, 250u), this); | ||
| 846 | } | 791 | } | ||
| 847 | 792 | | |||
| 848 | bool Compositor::isActive() | 793 | bool Compositor::isActive() | ||
| 849 | { | 794 | { | ||
| 850 | return m_state == State::On; | 795 | return m_state == State::On; | ||
| 851 | } | 796 | } | ||
| Show All 12 Lines | |||||
| 864 | 809 | | |||
| 865 | void WaylandCompositor::start() | 810 | void WaylandCompositor::start() | ||
| 866 | { | 811 | { | ||
| 867 | if (!Compositor::setupStart()) { | 812 | if (!Compositor::setupStart()) { | ||
| 868 | // Internal setup failed, abort. | 813 | // Internal setup failed, abort. | ||
| 869 | return; | 814 | return; | ||
| 870 | } | 815 | } | ||
| 871 | 816 | | |||
| 817 | // TODO: This is problematic on Wayland. We should get the highest refresh rate | ||||
| 818 | // and not the one of the first output. Also on hotplug reevaluate. | ||||
| 819 | // On X11 do it also like this? | ||||
| 820 | m_refreshRate = KWin::currentRefreshRate(); | ||||
| 821 | | ||||
| 872 | if (Workspace::self()) { | 822 | if (Workspace::self()) { | ||
| 873 | startupWithWorkspace(); | 823 | startupWithWorkspace(); | ||
| 874 | } else { | 824 | } else { | ||
| 875 | connect(kwinApp(), &Application::workspaceCreated, | 825 | connect(kwinApp(), &Application::workspaceCreated, | ||
| 876 | this, &WaylandCompositor::startupWithWorkspace); | 826 | this, &WaylandCompositor::startupWithWorkspace); | ||
| 877 | } | 827 | } | ||
| 878 | } | 828 | } | ||
| 879 | 829 | | |||
| 880 | bool WaylandCompositor::checkForOverlayWindow(WId w) const | 830 | bool WaylandCompositor::checkForOverlayWindow(WId w) const | ||
| 881 | { | 831 | { | ||
| 882 | Q_UNUSED(w) | 832 | Q_UNUSED(w) | ||
| 883 | // There is no overlay window in Wayland/XWayland. | 833 | // There is no overlay window in Wayland/XWayland. | ||
| 884 | return false; | 834 | return false; | ||
| 885 | } | 835 | } | ||
| 886 | 836 | | |||
| 887 | int WaylandCompositor::refreshRate() const | 837 | int WaylandCompositor::refreshRate() const | ||
| 888 | { | 838 | { | ||
| 889 | // TODO: This makes no sense on Wayland. First step would be to atleast | 839 | return m_refreshRate; | ||
| 890 | // set the refresh rate to the highest available one. Second step | | |||
| 891 | // would be to not use a uniform value at all but per screen. | | |||
| 892 | return KWin::currentRefreshRate(); | | |||
| 893 | } | 840 | } | ||
| 894 | 841 | | |||
| 895 | void WaylandCompositor::updateCompositeBlocking() | 842 | void WaylandCompositor::updateCompositeBlocking() | ||
| 896 | { | 843 | { | ||
| 897 | // Composite blocking not possible on Wayland. | 844 | // Composite blocking not possible on Wayland. | ||
| 898 | } | 845 | } | ||
| 899 | 846 | | |||
| 900 | void WaylandCompositor::updateClientCompositeBlocking(Client *c) | 847 | void WaylandCompositor::updateClientCompositeBlocking(Client *c) | ||
| ▲ Show 20 Lines • Show All 171 Lines • Show Last 20 Lines | |||||
I think we still need some of this code. Syncing to vblank will be a problem though.