Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.12.5, 5.12.6
-
Snapdragon 820A development board running Linux and Wayland
Description
The problem may be reproducible on other versions of Qt as well, but I can't confirm at this time.
Original Use-case
Originally this issue was reproduced in a larger application. In this application we implemented our own gesture handler, one of the "gestures" detected being Longpress. The implementation is pretty basic:
- Catch TouchBegin.
- If within 500ms there is no TouchUpdate outside a ~10pixel radius around TouchBegin coordinates => we have a Longpress.
- After a Longpress is detected, all TouchUpdate events are ignored.
If a TouchEnd is received immediately after LongPress is detected, there's no issue. But the following steps trigger the issue:
- LongPress was detected but user does not lift his finger off the screen, instead, performs further movements
- TouchUpdate events are received and ignored
- TouchUpdate apparently also results in QEvent::UpdateRequest being sent by Qt Framework
- Application is hanging for ~980ms in the handling of UpdateRequest
Identifying the problem
The way I observed that the app hangs in UpdateRequest handling is by overriding the "notify()" function in the QApplication sub-class, something like this:
bool notify(QObject* receiver, QEvent* event) override { if (event->type() == 77) // print a trace for QEvent::UpdateRequest { qDebug << "EVENT UpdateRequest received"; } static QElapsedTimer t; t.start(); bool ret = QApplication::notify(receiver, event); if(t.elapsed() > 10) qDebug << "EVENT Processing event type" << event->type() << "for object" << receiver->objectName() << "took" << t.elapsed(); return ret; }
Test Application
I also managed to reproduce the issue in a test application. See the attached tarball QtExampleApp.tar.gz. It's basically the QtExampleApp textureinsgnode with some modifications, mainly in Application.hpp.
Reproduction of the issue however does not depend on TouchUpdate in this case. What I did was to comment out the Renderer::update() call in Renderer::render(), and replaced it with a timer.
I added the timer in Application.hpp, and it calls QQuickItem::update() every 45ms (on the FBO object). It's visible that the animation steps are rendered with huge delays, definitely not once every 45ms.
Reducing the timeout to 5ms makes the test application behave differently. For the first 3 to 4 seconds I see the same huge render delays, and the traces that indicate QEvent::UpdateRequest took too much time. After that the frame rate becomes smooth, no delays observed anymore.
This leads me to believe there is some sort of race condition between UpdateRequest and an actual update() call, either on Renderer:: or QQUickItem::.
Reproduction Hardware
I mentioned that the hang duration I see logged in traces is about ~980ms. However this happens only on our development board. Based on Snapdragon 820A, running Linux and Wayland.
If I run the same software on x86 I don't see the huge hang. However I do see that in some cases the handling of QEvent::UpdateRequest take less than 10ms, and in other about 20ms. Maybe for x86 those 20ms occurrences are the same as the 980ms on slower hardware? This would imply that processing power dictates the length of the hang, which I can't explain.
The traces attached to the ticket (traces.txt) are taken from the TestApplication running on the development board.
Attachments
Issue Links
- relates to
-
QTBUG-72828 Add screens in reverse order
- Closed