19

I'm developing a simple QML application right now and I noticed that resizing and moving a QML window generates an ugly flicker compared to a QtWidgets window, for instance.

So I created 2 test applications to show the difference:

QWidgets:

enter image description here

QML:

enter image description here

As you can see the QML version of the application flickers pretty ugly while the QtWidgets one is clean. Now this gets pretty ugly when your UI grows in complexity.

Do you have any knowledge about this? Is this a bug? Is there any fix/workaround for this issue?

BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
Jacob Krieg
  • 2,834
  • 15
  • 68
  • 140
  • Which video card you use? – synacker Jun 13 '15 at 13:19
  • @Milovidov I'm using the integrated Intel HD Graphics 4000 which is integrated in an Intel's Core i5-3360M. – Jacob Krieg Jun 13 '15 at 14:02
  • 3
    Intel have problem with OpenGL implementation. Try to get or compile qt without OpenGL. In this case, Qt Quick will paint as native widgets, such as qt widgets solution. – synacker Jun 13 '15 at 14:19
  • Also, you can try update your graphics driver. – synacker Jun 13 '15 at 14:21
  • I wish I had your problems. How often are users of your app resizing the window? – Andrej Repiský Feb 15 '16 at 10:29
  • No matter how well you calculate the window size, people have different preferences. It is sort of an issue that the first thing users often do with your app is to resize the window to their liking. Bad first impression... – jpnurmi Jun 24 '16 at 21:04

4 Answers4

10

You can try this:

int main(int argc, char* argv[]) {
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
or
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);

The first option uses OpenGl2DirecX angle library (like Google Chrome)

The second one uses OpenGL emulation by software... for small programs work very good and is 100% compatible with old OS like Windows XP.

Note: You can try with Qt 5.7 and new Qtquick.Controls 2.0 ...performs much better... https://blog.qt.io/blog/2016/06/10/qt-quick-controls-2-0-a-new-beginning/

  • Tried on my Windows 7 PC with Qt 5.6.2 and Intel Graphics 4000. With Qt::AA_UseOpenGLES performs much better! Thank you! – mrAlmond Dec 20 '16 at 08:24
3

The issue with resizing of QML apps is about updating a window with outdated geometry. The fix would be to sync the updates and resizing.

Since there might be sudden updates from update timer to render scene graph, which can update the window at any time, it causes drawing of the content with outdated geometry. https://bugreports.qt.io/browse/QTBUG-46074

Either Basic or Extended synchronization should be used to synchronize resizing and the window updates. Currently Basic sync is used and implemented in Qt, but still need to synchronize the window updates (from timer) with resizing events from Windows Manager.

But, as always, there is a list of issues:

The problem is observed when the window is being resizing too fast. Since sync events (from WM) should be sent consistently, next after previous:

  1. <= _NET_WM_SYNC_REQUEST is sent from WM, the size is changing now.

  2. _NET_WM_SYNC_REQUEST is received and handled by app.

  3. <= some other events received, like new geometry.

  4. .. update the content, swapBuffers.

  5. => Sent _NET_WM_SYNC_REQUEST_COUNTER back to WM.

  6. <= _NET_WM_SYNC_REQUEST is sent again from WM, the size is changing.

  7. .. swapBuffers // here is the problem, the update is performed when the window is being changing its geometry.

  8. _NET_WM_SYNC_REQUEST received and handled again.

So the issue happens when (7) swapBuffers appears after _NET_WM_SYNC_REQUEST is sent but not received/processed yet.

And finally conclusion:

  • Actual resizing of the window is started right after _NET_WM_SYNC_REQUEST is sent by The Window Manager. And not when the app receives it. The window could be even updated at this time, when sync request is sent, but not handled by the app yet. Which will draw the content with outdated geometry.
  • _NET_WM_FRAME_DRAWN could help to sync between resizing and updates, but also might not be supported (and guess it is not) by The Window Manager.

In other words, either basic or extended synchronization does not help, (at least without _NET_WM_FRAME_DRAWN), because there is no way to know when actual resizing is done.

Extended sync protocol is a try to handle this, but since actual changing of geometry is done without syncing with the client, as I can see, without _NET_WM_FRAME_DRAWN there is always a chance to update the window with outdated geometry.

https://lists.freedesktop.org/archives/xcb/2019-February/011280.html

valbok
  • 321
  • 2
  • 5
1

In my case, i solved this by adding the next flag:

QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);

But this will add other rendering problems. Or not.

User9123
  • 19
  • 1
1

In golang therecipe/qt this help me :

func main() {
    var format = gui.NewQSurfaceFormat()
    format.SetVersion(4, 5)
    format.SetProfile(gui.QSurfaceFormat__CoreProfile)
    format.SetRenderableType(gui.QSurfaceFormat__OpenGL)
    format.SetSwapInterval(0)
    format.SetDefaultFormat(format)
    os.Setenv("QT_SCALE_FACTOR", "1")
    ap := widgets.NewQApplication(len(os.Args), os.Args)
    ap.SetApplicationName("APP 1.1")

System: Linux debian 10 gpu: Radeon 570

but the animations are faster because not all frames are rendered...

Kamil Sala
  • 11
  • 2