summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbconnection.cpp
diff options
context:
space:
mode:
authorAlexander Volkov <a.volkov@rusbitech.ru>2015-03-18 18:42:01 +0300
committerShawn Rutledge <shawn.rutledge@digia.com>2015-03-27 10:03:02 +0000
commita73cead0e0ffe674d0c873a726d2535ba60d9614 (patch)
tree21343ba88cd4d32e839ae72c34fa02bbb1eee2f3 /src/plugins/platforms/xcb/qxcbconnection.cpp
parentf381ad63a2d51033272c72f3a816fcfe9de000e7 (diff)
xcb: Speed up screens' initialization
Use RRGetScreenResourcesCurrent to get the screen's outputs. It is fast but it may return nothing if the configuration is not initialized wrt to the hardware. Call RRGetScreenResources in this case to get the up-to-date configuration. Task-number: QTBUG-40207 Change-Id: I84dc8a45b89d0bf8881a72b02e81f701637cdb6a Reviewed-by: Uli Schlachter <psychon@znc.in> Reviewed-by: Daniel Vrátil <dvratil@redhat.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp137
1 files changed, 77 insertions, 60 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 3b3fcd0b49..5b101e66bb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -306,71 +306,88 @@ void QXcbConnection::initializeScreens()
int connectedOutputCount = 0;
if (has_randr_extension) {
xcb_generic_error_t *error = NULL;
- xcb_randr_get_output_primary_cookie_t primaryCookie =
- xcb_randr_get_output_primary(xcb_connection(), xcbScreen->root);
- // TODO: RRGetScreenResources has to be called on each X display at least once before
- // RRGetScreenResourcesCurrent can be used - we can't know if we are the first application
- // to do so or not, so we always call the slower version here. Ideally we should share some
- // global flag (an atom on root window maybe) that at least other Qt apps would understand
- // and could call RRGetScreenResourcesCurrent here, speeding up start.
- xcb_randr_get_screen_resources_cookie_t resourcesCookie =
- xcb_randr_get_screen_resources(xcb_connection(), xcbScreen->root);
- QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary(
- xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error));
- if (!primary || error) {
- qWarning("failed to get the primary output of the screen");
+ // RRGetScreenResourcesCurrent is fast but it may return nothing if the
+ // configuration is not initialized wrt to the hardware. We should call
+ // RRGetScreenResources in this case.
+ QScopedPointer<xcb_randr_get_screen_resources_reply_t, QScopedPointerPodDeleter> resources;
+ xcb_randr_get_screen_resources_current_cookie_t resourcesCookie =
+ xcb_randr_get_screen_resources_current(xcb_connection(), xcbScreen->root);
+ QScopedPointer<xcb_randr_get_screen_resources_current_reply_t, QScopedPointerPodDeleter> resources_current(
+ xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, &error));
+ if (!resources_current || error) {
+ qWarning("failed to get the current screen resources");
free(error);
} else {
- QScopedPointer<xcb_randr_get_screen_resources_reply_t, QScopedPointerPodDeleter> resources(
- xcb_randr_get_screen_resources_reply(xcb_connection(), resourcesCookie, &error));
- if (!resources || error) {
- qWarning("failed to get the screen resources");
- free(error);
+ xcb_timestamp_t timestamp;
+ xcb_randr_output_t *outputs = Q_NULLPTR;
+ outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data());
+ if (outputCount) {
+ timestamp = resources_current->config_timestamp;
+ outputs = xcb_randr_get_screen_resources_current_outputs(resources_current.data());
} else {
- xcb_timestamp_t timestamp = resources->config_timestamp;
- outputCount = xcb_randr_get_screen_resources_outputs_length(resources.data());
- xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_outputs(resources.data());
-
- for (int i = 0; i < outputCount; i++) {
- QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> output(
- xcb_randr_get_output_info_reply(xcb_connection(),
- xcb_randr_get_output_info_unchecked(xcb_connection(), outputs[i], timestamp), NULL));
-
- // Invalid, disconnected or disabled output
- if (output == NULL)
- continue;
-
- if (output->connection != XCB_RANDR_CONNECTION_CONNECTED) {
- qCDebug(lcQpaScreen, "Output %s is not connected", qPrintable(
- QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()),
- xcb_randr_get_output_info_name_length(output.data()))));
- continue;
- }
+ xcb_randr_get_screen_resources_cookie_t resourcesCookie =
+ xcb_randr_get_screen_resources(xcb_connection(), xcbScreen->root);
+ resources.reset(xcb_randr_get_screen_resources_reply(xcb_connection(), resourcesCookie, &error));
+ if (!resources || error) {
+ qWarning("failed to get the screen resources");
+ free(error);
+ } else {
+ timestamp = resources->config_timestamp;
+ outputCount = xcb_randr_get_screen_resources_outputs_length(resources.data());
+ outputs = xcb_randr_get_screen_resources_outputs(resources.data());
+ }
+ }
- if (output->crtc == XCB_NONE) {
- qCDebug(lcQpaScreen, "Output %s is not enabled", qPrintable(
- QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()),
- xcb_randr_get_output_info_name_length(output.data()))));
- continue;
- }
+ if (outputCount) {
+ xcb_randr_get_output_primary_cookie_t primaryCookie =
+ xcb_randr_get_output_primary(xcb_connection(), xcbScreen->root);
+ QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary(
+ xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error));
+ if (!primary || error) {
+ qWarning("failed to get the primary output of the screen");
+ free(error);
+ } else {
+ for (int i = 0; i < outputCount; i++) {
+ QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> output(
+ xcb_randr_get_output_info_reply(xcb_connection(),
+ xcb_randr_get_output_info_unchecked(xcb_connection(), outputs[i], timestamp), NULL));
+
+ // Invalid, disconnected or disabled output
+ if (output == NULL)
+ continue;
+
+ if (output->connection != XCB_RANDR_CONNECTION_CONNECTED) {
+ qCDebug(lcQpaScreen, "Output %s is not connected", qPrintable(
+ QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()),
+ xcb_randr_get_output_info_name_length(output.data()))));
+ continue;
+ }
+
+ if (output->crtc == XCB_NONE) {
+ qCDebug(lcQpaScreen, "Output %s is not enabled", qPrintable(
+ QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()),
+ xcb_randr_get_output_info_name_length(output.data()))));
+ continue;
+ }
- QXcbScreen *screen = createScreen(xcbScreenNumber, xcbScreen, outputs[i], output.data());
- siblings << screen;
- ++connectedOutputCount;
- hasOutputs = true;
- m_screens << screen;
-
- // There can be multiple outputs per screen, use either
- // the first or an exact match. An exact match isn't
- // always available if primary->output is XCB_NONE
- // or currently disconnected output.
- if (m_primaryScreenNumber == xcbScreenNumber) {
- if (!primaryScreen || (primary && outputs[i] == primary->output)) {
- if (primaryScreen)
- primaryScreen->setPrimary(false);
- primaryScreen = screen;
- primaryScreen->setPrimary(true);
- siblings.prepend(siblings.takeLast());
+ QXcbScreen *screen = createScreen(xcbScreenNumber, xcbScreen, outputs[i], output.data());
+ siblings << screen;
+ ++connectedOutputCount;
+ hasOutputs = true;
+ m_screens << screen;
+
+ // There can be multiple outputs per screen, use either
+ // the first or an exact match. An exact match isn't
+ // always available if primary->output is XCB_NONE
+ // or currently disconnected output.
+ if (m_primaryScreenNumber == xcbScreenNumber) {
+ if (!primaryScreen || (primary && outputs[i] == primary->output)) {
+ if (primaryScreen)
+ primaryScreen->setPrimary(false);
+ primaryScreen = screen;
+ primaryScreen->setPrimary(true);
+ siblings.prepend(siblings.takeLast());
+ }
}
}
}