diff --git a/backends/hwcomposer/egl_hwcomposer_backend.cpp b/backends/hwcomposer/egl_hwcomposer_backend.cpp index 8ea4314df1..52aa46fba1 100644 --- a/backends/hwcomposer/egl_hwcomposer_backend.cpp +++ b/backends/hwcomposer/egl_hwcomposer_backend.cpp @@ -36,6 +36,7 @@ EglHwcomposerBackend::EglHwcomposerBackend(HwcomposerBackend *backend) // EGL is always direct rendering setIsDirectRendering(true); setSyncsToVBlank(true); + setBlocksForRetrace(true); } EglHwcomposerBackend::~EglHwcomposerBackend() diff --git a/backends/hwcomposer/hwcomposer_backend.cpp b/backends/hwcomposer/hwcomposer_backend.cpp index f9b2cc8368..fa6fbb1f01 100644 --- a/backends/hwcomposer/hwcomposer_backend.cpp +++ b/backends/hwcomposer/hwcomposer_backend.cpp @@ -28,8 +28,6 @@ along with this program. If not, see . #include #include #include -// Qt -#include // hybris/android #include #include @@ -43,12 +41,8 @@ namespace KWin HwcomposerBackend::HwcomposerBackend(QObject *parent) : AbstractBackend(parent) - , m_vsyncFailSafeTimer(new QTimer(this)) { handleOutputs(); - m_vsyncFailSafeTimer->setSingleShot(true); - m_vsyncFailSafeTimer->setInterval(1000); - connect(m_vsyncFailSafeTimer, &QTimer::timeout, this, &HwcomposerBackend::vsync); } HwcomposerBackend::~HwcomposerBackend() @@ -127,9 +121,7 @@ void HwcomposerBackend::init() if (disp != 0) { return; } - QMetaObject::invokeMethod(dynamic_cast(waylandServer()->backend()), - "vsync", - Qt::QueuedConnection); + dynamic_cast(waylandServer()->backend())->wakeVSync(); }; procs->hotplug = [] (const struct hwc_procs* procs, int disp, int connected) { Q_UNUSED(procs) @@ -148,6 +140,9 @@ void HwcomposerBackend::init() } m_displaySize = output->pixelSize(); m_refreshRate = output->refreshRate(); + if (m_refreshRate != 0) { + m_vsyncInterval = 1000000/m_refreshRate; + } qCDebug(KWIN_HWCOMPOSER) << "Display size:" << m_displaySize; qCDebug(KWIN_HWCOMPOSER) << "Refresh rate:" << m_refreshRate; @@ -201,27 +196,18 @@ OpenGLBackend *HwcomposerBackend::createOpenGLBackend() return new EglHwcomposerBackend(this); } -void HwcomposerBackend::present() +void HwcomposerBackend::waitVSync() { - if (m_pageFlipPending) { - return; - } - m_pageFlipPending = true; - if (Compositor::self()) { - m_vsyncFailSafeTimer->start(); - Compositor::self()->aboutToSwapBuffers(); - } + m_vsyncMutex.lock(); + m_vsyncWaitCondition.wait(&m_vsyncMutex, m_vsyncInterval); + m_vsyncMutex.unlock(); } -void HwcomposerBackend::vsync() +void HwcomposerBackend::wakeVSync() { - m_vsyncFailSafeTimer->stop(); - if (m_pageFlipPending) { - m_pageFlipPending = false; - if (Compositor::self()) { - Compositor::self()->bufferSwapComplete(); - } - } + m_vsyncMutex.lock(); + m_vsyncWaitCondition.wakeAll(); + m_vsyncMutex.unlock(); } static void initLayer(hwc_layer_1_t *layer, const hwc_rect_t &rect) @@ -279,7 +265,7 @@ HwcomposerWindow::~HwcomposerWindow() void HwcomposerWindow::present(HWComposerNativeWindowBuffer *buffer) { - m_backend->present(); + m_backend->waitVSync(); hwc_composer_device_1_t *device = m_backend->device(); auto fblayer = &m_list[0]->hwLayers[1]; diff --git a/backends/hwcomposer/hwcomposer_backend.h b/backends/hwcomposer/hwcomposer_backend.h index 54b1bfa430..a6d85ea35f 100644 --- a/backends/hwcomposer/hwcomposer_backend.h +++ b/backends/hwcomposer/hwcomposer_backend.h @@ -21,6 +21,9 @@ along with this program. If not, see . #define KWIN_HWCOMPOSER_BACKEND_H #include "abstract_backend.h" +#include +#include + // libhybris #include // needed as hwcomposer_window.h includes EGL which on non-arm includes Xlib @@ -32,8 +35,6 @@ typedef struct hwc_composer_device_1 hwc_composer_device_1_t; class HWComposerNativeWindowBuffer; -class QTimer; - namespace KWin { @@ -61,14 +62,12 @@ public: hwc_composer_device_1_t *device() const { return m_device; } - void present(); int refreshRate() const { return m_refreshRate; } void enableVSync(bool enable); - -public Q_SLOTS: - void vsync(); + void waitVSync(); + void wakeVSync(); private Q_SLOTS: void toggleBlankOutput(); @@ -77,10 +76,11 @@ private: QSize m_displaySize; hwc_composer_device_1_t *m_device = nullptr; bool m_outputBlank = true; - bool m_pageFlipPending = false; int m_refreshRate = 60000; - QTimer *m_vsyncFailSafeTimer; + int m_vsyncInterval = 16; bool m_hasVsync = false; + QMutex m_vsyncMutex; + QWaitCondition m_vsyncWaitCondition; }; class HwcomposerWindow : public HWComposerNativeWindow