From e14b1548b7d1211201b138bc077353cdbc0d0bed Mon Sep 17 00:00:00 2001 From: =?utf8?q?Samuel=20R=C3=B8dal?= Date: Fri, 4 May 2012 16:31:52 +0200 Subject: [PATCH] Implemented refresh rate support. Implements QWaylandScreen::refreshRate() based on the wl_output mode information we get from the compositor. In the compositor, adds API to override the refresh rate, with the default set to whatever QScreen reports on the compositor-side. Change-Id: I5f5175f2498940875c6ec68d29d25cf5993a1e65 Reviewed-by: Laszlo Agocs --- src/compositor/compositor_api/waylandcompositor.cpp | 10 ++++++++++ src/compositor/compositor_api/waylandcompositor.h | 3 +++ src/compositor/wayland_wrapper/wlcompositor.cpp | 10 ++++++++++ src/compositor/wayland_wrapper/wlcompositor.h | 2 ++ src/compositor/wayland_wrapper/wloutput.cpp | 8 +++++++- src/compositor/wayland_wrapper/wloutput.h | 4 ++++ src/plugins/platforms/wayland/qwaylanddisplay.cpp | 15 ++++++++------- src/plugins/platforms/wayland/qwaylandscreen.cpp | 19 +++++++++++++++++++ src/plugins/platforms/wayland/qwaylandscreen.h | 4 ++++ tests/auto/client/mockoutput.cpp | 3 ++- 10 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/compositor/compositor_api/waylandcompositor.cpp b/src/compositor/compositor_api/waylandcompositor.cpp index 8fa7bb2..3605497 100644 --- a/src/compositor/compositor_api/waylandcompositor.cpp +++ b/src/compositor/compositor_api/waylandcompositor.cpp @@ -212,6 +212,16 @@ QRect WaylandCompositor::outputGeometry() const return m_compositor->outputGeometry(); } +void WaylandCompositor::setOutputRefreshRate(int rate) +{ + m_compositor->setOutputRefreshRate(rate); +} + +int WaylandCompositor::outputRefreshRate() const +{ + return m_compositor->outputRefreshRate(); +} + WaylandInputDevice *WaylandCompositor::defaultInputDevice() const { return m_compositor->defaultInputDevice()->handle(); diff --git a/src/compositor/compositor_api/waylandcompositor.h b/src/compositor/compositor_api/waylandcompositor.h index 456c66a..989ece4 100644 --- a/src/compositor/compositor_api/waylandcompositor.h +++ b/src/compositor/compositor_api/waylandcompositor.h @@ -98,6 +98,9 @@ public: void setOutputGeometry(const QRect &outputGeometry); QRect outputGeometry() const; + void setOutputRefreshRate(int refreshRate); + int outputRefreshRate() const; + WaylandInputDevice *defaultInputDevice() const; bool isDragging() const; diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp index f8aaaf7..d43b402 100644 --- a/src/compositor/wayland_wrapper/wlcompositor.cpp +++ b/src/compositor/wayland_wrapper/wlcompositor.cpp @@ -392,6 +392,16 @@ QRect Compositor::outputGeometry() const return m_output_global.geometry(); } +void Compositor::setOutputRefreshRate(int rate) +{ + m_output_global.setRefreshRate(rate); +} + +int Compositor::outputRefreshRate() const +{ + return m_output_global.refreshRate(); +} + void Compositor::setClientFullScreenHint(bool value) { m_windowManagerIntegration->setShowIsFullScreen(value); diff --git a/src/compositor/wayland_wrapper/wlcompositor.h b/src/compositor/wayland_wrapper/wlcompositor.h index e83cb9a..7712485 100644 --- a/src/compositor/wayland_wrapper/wlcompositor.h +++ b/src/compositor/wayland_wrapper/wlcompositor.h @@ -125,6 +125,8 @@ public: Qt::ScreenOrientation screenOrientation() const; void setOutputGeometry(const QRect &geometry); QRect outputGeometry() const; + void setOutputRefreshRate(int rate); + int outputRefreshRate() const; void setClientFullScreenHint(bool value); diff --git a/src/compositor/wayland_wrapper/wloutput.cpp b/src/compositor/wayland_wrapper/wloutput.cpp index c1c91ed..e00d8b8 100644 --- a/src/compositor/wayland_wrapper/wloutput.cpp +++ b/src/compositor/wayland_wrapper/wloutput.cpp @@ -52,6 +52,7 @@ OutputGlobal::OutputGlobal() { QScreen *screen = QGuiApplication::primaryScreen(); m_geometry = QRect(QPoint(0, 0), screen->availableGeometry().size()); + m_refreshRate = qRound(screen->refreshRate()); } OutputGlobal::~OutputGlobal() @@ -64,6 +65,11 @@ void OutputGlobal::setGeometry(const QRect &geometry) m_geometry = geometry; } +void OutputGlobal::setRefreshRate(int rate) +{ + m_refreshRate = rate; +} + Output *OutputGlobal::outputForClient(wl_client *client) const { return static_cast(resourceForClient(client)->data); @@ -92,7 +98,7 @@ Output::Output(OutputGlobal *outputGlobal, wl_client *client, uint32_t version, m_output_global->size().width(), m_output_global->size().height(),0,"",""); wl_output_send_mode(m_output_resource, WL_OUTPUT_MODE_CURRENT|WL_OUTPUT_MODE_PREFERRED, - m_output_global->size().width(),m_output_global->size().height(), 60); + m_output_global->size().width(), m_output_global->size().height(), m_output_global->refreshRate()); } diff --git a/src/compositor/wayland_wrapper/wloutput.h b/src/compositor/wayland_wrapper/wloutput.h index df7534f..0a28b02 100644 --- a/src/compositor/wayland_wrapper/wloutput.h +++ b/src/compositor/wayland_wrapper/wloutput.h @@ -64,12 +64,16 @@ public: int y() const { return m_geometry.y(); } QSize size() const { return m_geometry.size(); } + void setRefreshRate(int rate); + int refreshRate() const { return m_refreshRate; } + Output *outputForClient(struct wl_client *client) const; static void output_bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id); private: QRect m_geometry; + int m_refreshRate; int m_displayId; int m_numQueued; QList m_outputs; diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index be8a096..d0ae002 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -234,18 +234,19 @@ void QWaylandDisplay::outputHandleGeometry(void *data, } void QWaylandDisplay::mode(void *data, - struct wl_output *wl_output, + struct wl_output *output, uint32_t flags, int width, int height, int refresh) { - Q_UNUSED(data); - Q_UNUSED(wl_output); - Q_UNUSED(flags); - Q_UNUSED(width); - Q_UNUSED(height); - Q_UNUSED(refresh); + QWaylandDisplay *waylandDisplay = static_cast(data); + + if (flags & WL_OUTPUT_MODE_CURRENT) { + QWaylandScreen *screen = waylandDisplay->screenForOutput(output); + if (screen) + screen->handleMode(QSize(width, height), refresh); + } } const struct wl_output_listener QWaylandDisplay::outputListener = { diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp index e81d5bc..0373239 100644 --- a/src/plugins/platforms/wayland/qwaylandscreen.cpp +++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp @@ -54,6 +54,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output , mExtendedOutput(0) , mGeometry(geometry) , mDepth(32) + , mRefreshRate(60) , mFormat(QImage::Format_ARGB32_Premultiplied) , mWaylandCursor(new QWaylandCursor(this)) { @@ -95,6 +96,11 @@ Qt::ScreenOrientation QWaylandScreen::orientation() const return QPlatformScreen::orientation(); } +qreal QWaylandScreen::refreshRate() const +{ + return mRefreshRate; +} + QPlatformCursor *QWaylandScreen::cursor() const { return mWaylandCursor; @@ -116,3 +122,16 @@ QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window) QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(window); return static_cast(platformScreen); } + +void QWaylandScreen::handleMode(const QSize &size, int refreshRate) +{ + if (size != mGeometry.size()) { + mGeometry.setSize(size); + QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); + } + + if (refreshRate != mRefreshRate) { + mRefreshRate = refreshRate; + QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate); + } +} diff --git a/src/plugins/platforms/wayland/qwaylandscreen.h b/src/plugins/platforms/wayland/qwaylandscreen.h index 02f341d..b76b0ed 100644 --- a/src/plugins/platforms/wayland/qwaylandscreen.h +++ b/src/plugins/platforms/wayland/qwaylandscreen.h @@ -61,6 +61,7 @@ public: QImage::Format format() const; Qt::ScreenOrientation orientation() const; + qreal refreshRate() const; QPlatformCursor *cursor() const; @@ -71,12 +72,15 @@ public: static QWaylandScreen *waylandScreenFromWindow(QWindow *window); + void handleMode(const QSize &size, int refreshRate); + private: QWaylandDisplay *mWaylandDisplay; struct wl_output *mOutput; QWaylandExtendedOutput *mExtendedOutput; QRect mGeometry; int mDepth; + int mRefreshRate; QImage::Format mFormat; QSize mPhysicalSize; diff --git a/tests/auto/client/mockoutput.cpp b/tests/auto/client/mockoutput.cpp index 18773f0..8066c21 100644 --- a/tests/auto/client/mockoutput.cpp +++ b/tests/auto/client/mockoutput.cpp @@ -64,7 +64,8 @@ void Compositor::sendOutputGeometry(wl_resource *resource) void Compositor::sendOutputMode(wl_resource *resource) { - wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED, 640, 480, 60); + const QRect &r = m_outputGeometry; + wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED, r.width(), r.height(), 60); } void Compositor::setOutputGeometry(void *c, const QList ¶meters) -- 2.7.4