Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-134949

updateChildWindowStackingOrder can get quite costly

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.7, 6.8
    • Quick: SceneGraph
    • None
    • Windows

    Description

      Since the implementation of https://bugreports.qt.io/browse/QTBUG-102835 there exists a function updateChildWindowStackingOrder() in qquickwindow.cpp which iterates recursively over the complete QQuickItem tree of a window whenever somewhere in the window an item is marked as dirty with ChildrenStackingChanged.

      This happens also if the visibility of an item changes.

      If a GUI is very complex the polish time of a rendered frame can take several milliseconds if this is triggered. In our own application we disabled vsync to reach 200FPS and our GUI has a lot of changes that happen often including dynamic created elements or visibility changes. The FPS can drop significantly in these cases.
      Especially since we don't even use the feature of WindowContainer for which this loop was implemented.

      I implemented a minimal example in QML for running with qml.exe that creates 100.000 child elements and toggles the visibility of a rectangle very often.

      When you enable the logging category for the renderloop timing you can see that the polish time increases to several milliseconds when the visibility toggle is switched on (depending on your machine speed)

      qt.scenegraph.time.renderloop.debug=true 
      qt.scenegraph.time.renderloop: [window 0x2998af3d1c0][render thread 0x2998af97640] syncAndRender: frame rendered in 16ms, sync=0, render=0, swap=16
      qt.scenegraph.time.renderloop: [window 0x2998af3d1c0][render thread 0x2998af97640] syncAndRender: start, elapsed since last call: 16 ms
      qt.scenegraph.time.renderloop: [window 0x2998af3d1c0][gui thread] Frame prepared, polish=3 ms, lock=0 ms, blockedForSync=7 ms, animations=0 ms 

      In Qt 6.6 the polish time stays at 0ms

      qt.scenegraph.time.renderloop: [window 0x15003772c10][render thread 0x150037d3bb0] syncAndRender: frame rendered in 16ms, sync=0, render=5, swap=10
      qt.scenegraph.time.renderloop: [window 0x15003772c10][render thread 0x150037d3bb0] syncAndRender: start, elapsed since last call: 16 ms
      qt.scenegraph.time.renderloop: [window 0x15003772c10][gui thread] Frame prepared, polish=0 ms, lock=0 ms, blockedForSync=9 ms, animations=0 ms 

      As you can see in the attached flame graph a significant timeslot is spent in updateChildWindowStackingOrder and in there in qobject_cast since each QQuickItem* is tried to be cast to QQuickWindowContainer*

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            janichol Andy Nichols
            scheungrab@cipsoft.com Anton Scheungrab
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes