Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Quick SG engine renders twice.
Forum Updated to NodeBB v4.3 + New Features

Quick SG engine renders twice.

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
2 Posts 1 Posters 682 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Kurapikov
    wrote on last edited by Kurapikov
    #1

    Hi there,

    I'm developing something with QT binding BGFX. I'd like to paint something OpenGL under QML things. So I tried to connect the main window signals such as beforeRenderPassRecording and beforeSynchronizing.

    While the code runs, I see my OpenGL draws, then QML things, and OpenGL draws again. So the QML things is overlaid by OpenGL rendering.

    My QML is as following:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    Window {
        id : kcad_main_window
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
        Text {
            id: text1
            x: 22
            y: 15
            color: "#ff0000"
            text: qsTr("Text")
            font.pixelSize: 12
        }
        Text {
            id: text2
            x: 601
            y: 15
            color: "#ff0000"
            text: qsTr("Text")
            font.pixelSize: 12
        }
        Text {
            id: text3
            x: 22
            y: 454
            color: "#ff0000"
            text: qsTr("Text")
            font.pixelSize: 12
        }
        Text {
            id: text4
            x: 601
            y: 454
            color: "#ff0000"
            text: qsTr("Text")
            font.pixelSize: 12
        }
    }
    

    I get native window handle with this method:

    QQuickWindow *p_main_win = qobject_cast<QQuickWindow*>( engine.rootObjects().at(0) );
    p_bgfx_bridge_inst->set_wid(p_main_win -> winId());
    

    I connected all 16 signals according to this document and output debug information within all 16 slots to trace:
    https://doc.qt.io/qt-6/qquickwindow.html
    Then I maxmized my window, log as below:

    MY_DEBUG_HERE: Signal: afterAnimating
    MY_DEBUG_HERE: Signal: beforeFrameBegin
    MY_DEBUG_HERE: Signal: beforeSynchronizing
    MY_DEBUG_HERE: Signal: afterSynchronizing
    MY_DEBUG_HERE: Signal: beforeRendering
    MY_DEBUG_HERE: Signal: beforeRenderPassRecording
    MY_DEBUG_HERE: Signal: afterRenderPassRecording
    MY_DEBUG_HERE: Signal: afterRendering
    MY_DEBUG_HERE: Signal: frameSwapped
    MY_DEBUG_HERE: Signal: afterFrameEnd
    MY_DEBUG_HERE: Signal: afterAnimating
    MY_DEBUG_HERE: Signal: beforeFrameBegin
    MY_DEBUG_HERE: Signal: beforeSynchronizing
    MY_DEBUG_HERE: Signal: afterSynchronizing
    MY_DEBUG_HERE: Signal: beforeRendering
    MY_DEBUG_HERE: Signal: beforeRenderPassRecording
    MY_DEBUG_HERE: Signal: afterRenderPassRecording
    MY_DEBUG_HERE: Signal: afterRendering
    MY_DEBUG_HERE: Signal: frameSwapped
    MY_DEBUG_HERE: Signal: afterFrameEnd
    

    If I enable log with following code:

    QLoggingCategory::setFilterRules(QStringLiteral("qt.scenegraph.*=true")); 
    qSetMessagePattern("%{category}: %{message}");
    

    The overall output is as following:

    qt.scenegraph.renderloop: update from item QQuickWindowQmlImpl(0x555555a1ea30 active exposed, visibility=QWindow::Maximized, flags=QFlags<Qt::WindowType>(Window), title="Hello World", geometry=70,64 2288x1296)
    qt.scenegraph.renderloop: update from item QQuickWindowQmlImpl(0x555555a1ea30 active exposed, visibility=QWindow::Maximized, flags=QFlags<Qt::WindowType>(Window), title="Hello World", geometry=70,64 2288x1296)
    qt.scenegraph.renderloop: reisze() QQuickWindowQmlImpl(0x555555a1ea30 active exposed, visibility=QWindow::Maximized, flags=QFlags<Qt::WindowType>(Window), title="Hello World", geometry=70,64 2288x1296)
    qt.scenegraph.renderloop: exposureChanged() QQuickWindowQmlImpl(0x555555a1ea30 active exposed, visibility=QWindow::Maximized, flags=QFlags<Qt::WindowType>(Window), title="Hello World", geometry=70,64 2288x1296)
    qt.scenegraph.renderloop: handleExposure() QQuickWindowQmlImpl(0x555555a1ea30 active exposed, visibility=QWindow::Maximized, flags=QFlags<Qt::WindowType>(Window), title="Hello World", geometry=70,64 2288x1296)
    qt.scenegraph.renderloop: - render thread already running
    qt.scenegraph.renderloop: polishAndSync (in expose) QQuickWindowQmlImpl(0x555555a1ea30 active exposed, visibility=QWindow::Maximized, flags=QFlags<Qt::WindowType>(Window), title="Hello World", geometry=70,64 2288x1296)
    qt.scenegraph.time.renderloop: [window 0x555555a1ea30][gui thread] polishAndSync: start, elapsed since last call: 9174 ms
    default: MY_DEBUG_HERE: Signal: afterAnimating
    qt.scenegraph.renderloop: - lock for sync
    qt.scenegraph.renderloop: - wait for sync
    qt.scenegraph.renderloop:                     (RT) WM_RequestSync
    qt.scenegraph.renderloop:                     (RT) - triggered from expose
    qt.scenegraph.renderloop:                     (RT) --- done processEventsAndWaitForMore()
    qt.scenegraph.renderloop:                     (RT) syncAndRender()
    qt.scenegraph.time.renderloop: [window 0x555555a1ea30][render thread 0x5555558eb050] syncAndRender: start, elapsed since last call: 9173 ms
    qt.scenegraph.renderloop: rhi swapchain size QSize(2288, 1296)
    default: MY_DEBUG_HERE: Signal: beforeFrameBegin
    qt.scenegraph.renderloop:                     (RT) - updatePending, doing sync
    qt.scenegraph.renderloop:                     (RT) sync()
    default: MY_DEBUG_HERE: Signal: beforeSynchronizing
    default: MY_DEBUG_HERE: Signal: afterSynchronizing
    qt.scenegraph.renderloop:                     (RT) - rendering started
    default: MY_DEBUG_HERE: Signal: beforeRendering
    default: MY_DEBUG_HERE: Signal: beforeRenderPassRecording
    default: MY_DEBUG_HERE: Signal: afterRenderPassRecording
    qt.scenegraph.time.renderer: time in renderer: total=5ms, preprocess=0, updates=0, rendering=5
    default: MY_DEBUG_HERE: Signal: afterRendering
    default: MY_DEBUG_HERE: Signal: frameSwapped
    qt.scenegraph.renderloop:                     (RT) - rendering done
    default: MY_DEBUG_HERE: Signal: afterFrameEnd
    qt.scenegraph.renderloop:                     (RT) - wake Gui after expose
    qt.scenegraph.time.renderloop: [window 0x555555a1ea30][render thread 0x5555558eb050] syncAndRender: frame rendered in 12ms, sync=0, render=5, swap=7
    qt.scenegraph.renderloop:                     (RT) --- begin processEvents()
    qt.scenegraph.renderloop:                     (RT) --- done processEvents()
    qt.scenegraph.renderloop:                     (RT) done drawing, sleep...
    qt.scenegraph.renderloop:                     (RT) --- begin processEventsAndWaitForMore()
    qt.scenegraph.renderloop: - unlock after sync
    qt.scenegraph.time.renderloop: [window 0x555555a1ea30][gui thread] Frame prepared, polish=0 ms, lock=0 ms, blockedForSync=13 ms, animations=0 ms
    qt.scenegraph.renderloop: - done with handleExposure()
    qt.scenegraph.renderloop: - update request QQuickWindowQmlImpl(0x555555a1ea30 active exposed, visibility=QWindow::Maximized, flags=QFlags<Qt::WindowType>(Window), title="Hello World", geometry=70,64 2288x1296)
    qt.scenegraph.renderloop: polishAndSync (normal) QQuickWindowQmlImpl(0x555555a1ea30 active exposed, visibility=QWindow::Maximized, flags=QFlags<Qt::WindowType>(Window), title="Hello World", geometry=70,64 2288x1296)
    qt.scenegraph.time.renderloop: [window 0x555555a1ea30][gui thread] polishAndSync: start, elapsed since last call: 13 ms
    default: MY_DEBUG_HERE: Signal: afterAnimating
    qt.scenegraph.renderloop: - lock for sync
    qt.scenegraph.renderloop: - wait for sync
    qt.scenegraph.renderloop:                     (RT) WM_RequestSync
    qt.scenegraph.renderloop:                     (RT) --- done processEventsAndWaitForMore()
    qt.scenegraph.renderloop:                     (RT) syncAndRender()
    qt.scenegraph.time.renderloop: [window 0x555555a1ea30][render thread 0x5555558eb050] syncAndRender: start, elapsed since last call: 14 ms
    default: MY_DEBUG_HERE: Signal: beforeFrameBegin
    qt.scenegraph.renderloop:                     (RT) - updatePending, doing sync
    qt.scenegraph.renderloop:                     (RT) sync()
    default: MY_DEBUG_HERE: Signal: beforeSynchronizing
    default: MY_DEBUG_HERE: Signal: afterSynchronizing
    qt.scenegraph.renderloop:                     (RT) - sync complete, waking Gui
    qt.scenegraph.renderloop:                     (RT) - rendering started
    default: MY_DEBUG_HERE: Signal: beforeRendering
    default: MY_DEBUG_HERE: Signal: beforeRenderPassRecording
    qt.scenegraph.renderloop: - unlock after sync
    qt.scenegraph.time.renderloop: [window 0x555555a1ea30][gui thread] Frame prepared, polish=0 ms, lock=0 ms, blockedForSync=1 ms, animations=0 ms
    default: MY_DEBUG_HERE: Signal: afterRenderPassRecording
    qt.scenegraph.time.renderer: time in renderer: total=31ms, preprocess=0, updates=0, rendering=31
    default: MY_DEBUG_HERE: Signal: afterRendering
    default: MY_DEBUG_HERE: Signal: frameSwapped
    qt.scenegraph.renderloop:                     (RT) - rendering done
    default: MY_DEBUG_HERE: Signal: afterFrameEnd
    qt.scenegraph.time.renderloop: [window 0x555555a1ea30][render thread 0x5555558eb050] syncAndRender: frame rendered in 40ms, sync=0, render=32, swap=8
    qt.scenegraph.renderloop:                     (RT) --- begin processEvents()
    qt.scenegraph.renderloop:                     (RT) --- done processEvents()
    qt.scenegraph.renderloop:                     (RT) done drawing, sleep...
    qt.scenegraph.renderloop:                     (RT) --- begin processEventsAndWaitForMore()
    

    You can see all the signals are emitted twice. The log of 2 passes is slightly different. You can make a diff and see the difference. It's rather strange.

    My env is QT 6.5.3, Ubuntu 23.04 with X Window (not wayland).

    Waiting for any suggestion. Thanks.

    1 Reply Last reply
    0
    • K Offline
      K Offline
      Kurapikov
      wrote on last edited by
      #2

      I found that 2 problems exists.

      The first problem is: there's an issue with threading. While I debug my program step by step, the render sequence is: "bgfx -> QML -> bgfx ->QML". Every render is executed twice but the sequence is right. The expected behavior should be "bgfx -> QML" but 2 passes is all right. But while the program is free running, the sequence is strange and the last QML rendering seems not performed.

      The second problem is: when QML is rendered and the signal "frameSwapped" is emitted, the BGFX rendered contents are cleared. Only QML contents display on window. So there's no underlay under QML contents. The expected behavior should be QML contents overlaid above BGFX contents.

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved