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>
This commit is contained in:
parent
f381ad63a2
commit
a73cead0e0
@ -306,31 +306,47 @@ 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.
|
||||
// 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 {
|
||||
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_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 (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 {
|
||||
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);
|
||||
} 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(),
|
||||
@ -377,6 +393,7 @@ void QXcbConnection::initializeScreens()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (QPlatformScreen* s, siblings)
|
||||
((QXcbScreen*)s)->setVirtualSiblings(siblings);
|
||||
xcb_screen_next(&it);
|
||||
|
Loading…
Reference in New Issue
Block a user