diff options
author | Daniel Vrátil <dvratil@redhat.com> | 2015-02-23 20:27:37 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@digia.com> | 2015-03-11 07:15:28 +0000 |
commit | 3b30a8215e98f6164a1650ce7c7e2a42a3d8746f (patch) | |
tree | 9d2795005b22534bca74cd06d294edf474cd1c3b /src/plugins/platforms/xcb/qxcbscreen.h | |
parent | d3f6249de30ade8e75fe01bd61f5e7416790c032 (diff) |
Improve handling of XRandR events in XCB backend
Querying X server for data can be very expensive, especially when there
are multiple processes querying it at the same time (which is exactly what
happens when screen configuration changes and all Qt applications receive
XRandR change notifications). This patch is aiming to reduce the number of
queries to X server as much as possible by making use of detailed information
available in the RRCrtcChangeNotify and RROutputChangeNotify events.
Firstly, the backend now does not rebuild all QXcbScreens on any change (which
involved the very expensive xcb_randr_get_screen_resources() call), but only
builds the full set of QXcbScreens once in initializeScreens(), and then just
incrementally updates it.
Secondly, it avoids querying X server for all screens geometry as much as
possible, and only does so when CRTC/Output change notification for a particular
screen is delivered.
As a result, handling of all XRandR events on screen change is reduced from tens
of seconds to less then a seconds and applications are better responsive after
that, because we don't block the event loop for long. The X server is also more
responsive after the screen change, since we are not overloading it with requests.
Change-Id: I9b8308341cada71dfc9590030909b1e68a335a1f
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbscreen.h')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.h | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 53ad413541..3f228465f2 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -58,7 +58,8 @@ class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen { public: QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, - xcb_randr_get_output_info_reply_t *output, const QString &outputName, int number); + xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output, + QString outputName, int number); ~QXcbScreen(); QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE; @@ -80,11 +81,19 @@ public: Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_orientation; } QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; } void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; } + void removeVirtualSibling(QPlatformScreen *s) { m_siblings.removeOne(s); } + void addVirtualSibling(QPlatformScreen *s) { ((QXcbScreen *) s)->isPrimary() ? m_siblings.prepend(s) : m_siblings.append(s); } + + void setPrimary(bool primary) { m_primary = primary; } + bool isPrimary() const { return m_primary; } int screenNumber() const { return m_number; } xcb_screen_t *screen() const { return m_screen; } xcb_window_t root() const { return m_screen->root; } + xcb_randr_output_t output() const { return m_output; } + xcb_randr_crtc_t crtc() const { return m_crtc; } + xcb_randr_mode_t mode() const { return m_mode; } xcb_window_t clientLeader() const { return m_clientLeader; } @@ -98,8 +107,9 @@ public: QString name() const Q_DECL_OVERRIDE { return m_outputName; } void handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event); - void updateGeometry(xcb_timestamp_t timestamp); - void updateRefreshRate(); + void updateGeometry(const QRect &geom, uint8_t rotation); + void updateGeometry(xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME); + void updateRefreshRate(xcb_randr_mode_t mode); void readXResources(); @@ -117,7 +127,12 @@ private: void sendStartupMessage(const QByteArray &message) const; xcb_screen_t *m_screen; + xcb_randr_output_t m_output; xcb_randr_crtc_t m_crtc; + xcb_randr_mode_t m_mode; + bool m_primary; + uint8_t m_rotation; + QString m_outputName; QSizeF m_outputSizeMillimeters; QSizeF m_sizeMillimeters; |