From ad85513d4b38bdedac27a095bd3a988f1eda23a2 Mon Sep 17 00:00:00 2001 From: Sami Varanka Date: Wed, 2 Jun 2021 13:43:06 +0300 Subject: Fix direct rendering doesn't show anything MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rendering a graph directly to background didn't work in Qt 6 since it uses RHI and there is no way to not clear the color buffer before rendering. The graph uses direct OpenGL calls to render directly to background. Enabled direct rendering to qml3doscilloscope example. In addition, RenderDirectToBackground_NoClear got deprecated. When rendering directly to background, using non-transparent qml item as a background will hide the graph. This was already mentioned in the documentation but not clearly enough. Updated documentation for AbstractGraph3D. Pick-to: 6.1 Fixes: QTBUG-90665 Change-Id: I53081bac382ab89573359886e4f5c4b41be8e86d Reviewed-by: Tomi Korpipää --- .../doc/src/qml3doscilloscope.qdoc | 2 -- .../qml/qml3doscilloscope/main.qml | 1 + .../qmlaxisformatter/qml/qmlaxisformatter/main.qml | 2 +- .../datavisualization/qmlbars/qml/qmlbars/main.qml | 2 +- .../qmlcustominput/qml/qmlcustominput/main.qml | 2 +- .../qmllegend/qml/qmllegend/main.qml | 2 +- .../qmlmultigraph/qml/qmlmultigraph/main.qml | 5 ++- .../qmlscatter/doc/src/qmlscatter.qdoc | 4 +-- .../qmlscatter/qml/qmlscatter/main.qml | 2 +- ...tdatavisualization-qml-abstractdeclarative.qdoc | 23 +++++--------- src/datavisualizationqml2/abstractdeclarative.cpp | 37 +++++----------------- .../qmldynamicdata/qml/qmldynamicdata/main.qml | 2 +- tests/manual/qmlgradient/qml/qmlgradient/main.qml | 2 +- .../manual/qmlmultitest/qml/qmlmultitest/main.qml | 5 ++- tests/manual/qmlperf/qml/qmlperf/main.qml | 2 +- 15 files changed, 35 insertions(+), 58 deletions(-) diff --git a/examples/datavisualization/qml3doscilloscope/doc/src/qml3doscilloscope.qdoc b/examples/datavisualization/qml3doscilloscope/doc/src/qml3doscilloscope.qdoc index 3772df32..a3b2f3f3 100644 --- a/examples/datavisualization/qml3doscilloscope/doc/src/qml3doscilloscope.qdoc +++ b/examples/datavisualization/qml3doscilloscope/doc/src/qml3doscilloscope.qdoc @@ -110,7 +110,6 @@ \snippet qml3doscilloscope/qml/qml3doscilloscope/main.qml 3 - \omit \section1 Enabling Direct Rendering Since this application potentially deals with a lot of rapidly changing data, we use direct @@ -122,6 +121,5 @@ \snippet qml3doscilloscope/main.cpp 1 \dots 0 \snippet qml3doscilloscope/main.cpp 2 - \endomit */ diff --git a/examples/datavisualization/qml3doscilloscope/qml/qml3doscilloscope/main.qml b/examples/datavisualization/qml3doscilloscope/qml/qml3doscilloscope/main.qml index ba733c21..51eba416 100644 --- a/examples/datavisualization/qml3doscilloscope/qml/qml3doscilloscope/main.qml +++ b/examples/datavisualization/qml3doscilloscope/qml/qml3doscilloscope/main.qml @@ -74,6 +74,7 @@ Item { axisY.segmentCount: 4 axisZ.segmentCount: 4 measureFps: true + renderingMode: AbstractGraph3D.RenderDirectToBackground onCurrentFpsChanged: (fps)=> { if (fps > 10) diff --git a/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/main.qml b/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/main.qml index 7be207af..d7042535 100644 --- a/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/main.qml +++ b/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/main.qml @@ -34,7 +34,7 @@ import QtDataVisualization 1.2 import CustomFormatter import "." -Rectangle { +Item { id: mainView width: 1280 height: 1024 diff --git a/examples/datavisualization/qmlbars/qml/qmlbars/main.qml b/examples/datavisualization/qmlbars/qml/qmlbars/main.qml index ab855fd9..76eff0f2 100644 --- a/examples/datavisualization/qmlbars/qml/qmlbars/main.qml +++ b/examples/datavisualization/qmlbars/qml/qmlbars/main.qml @@ -35,7 +35,7 @@ import QtQuick.Window import Qt.labs.qmlmodels import "." -Rectangle { +Item { id: mainview width: 1280 height: 1024 diff --git a/examples/datavisualization/qmlcustominput/qml/qmlcustominput/main.qml b/examples/datavisualization/qmlcustominput/qml/qmlcustominput/main.qml index 23fb13ee..77576127 100644 --- a/examples/datavisualization/qmlcustominput/qml/qmlcustominput/main.qml +++ b/examples/datavisualization/qmlcustominput/qml/qmlcustominput/main.qml @@ -33,7 +33,7 @@ import QtQuick.Controls import QtDataVisualization 1.2 import "." -Rectangle { +Item { id: mainView width: 1280 height: 720 diff --git a/examples/datavisualization/qmllegend/qml/qmllegend/main.qml b/examples/datavisualization/qmllegend/qml/qmllegend/main.qml index 5100a378..5245fd67 100644 --- a/examples/datavisualization/qmllegend/qml/qmllegend/main.qml +++ b/examples/datavisualization/qmllegend/qml/qmllegend/main.qml @@ -33,7 +33,7 @@ import QtQuick.Layouts import QtDataVisualization 1.2 import "." -Rectangle { +Item { id: mainView width: 800 height: 600 diff --git a/examples/datavisualization/qmlmultigraph/qml/qmlmultigraph/main.qml b/examples/datavisualization/qmlmultigraph/qml/qmlmultigraph/main.qml index cbfeb9d8..f30b1739 100644 --- a/examples/datavisualization/qmlmultigraph/qml/qmlmultigraph/main.qml +++ b/examples/datavisualization/qmlmultigraph/qml/qmlmultigraph/main.qml @@ -33,7 +33,7 @@ import QtQuick.Controls import QtDataVisualization 1.2 import "." -Rectangle { +Item { id: mainView width: 800 height: 600 @@ -58,6 +58,7 @@ Rectangle { Layout.fillWidth: true border.color: surfaceGraph.theme.gridLineColor border.width: 2 + color: "#00000000" Surface3D { id: surfaceGraph @@ -134,6 +135,7 @@ Rectangle { Layout.fillWidth: true border.color: scatterGraph.theme.gridLineColor border.width: 2 + color: "#00000000" Scatter3D { id: scatterGraph @@ -163,6 +165,7 @@ Rectangle { Layout.fillWidth: true border.color: barGraph.theme.gridLineColor border.width: 2 + color: "#00000000" Bars3D { id: barGraph diff --git a/examples/datavisualization/qmlscatter/doc/src/qmlscatter.qdoc b/examples/datavisualization/qmlscatter/doc/src/qmlscatter.qdoc index 667aea49..95d2bc66 100644 --- a/examples/datavisualization/qmlscatter/doc/src/qmlscatter.qdoc +++ b/examples/datavisualization/qmlscatter/doc/src/qmlscatter.qdoc @@ -80,11 +80,11 @@ The last \c import just imports all the qml files in the same directory as our \c {main.qml}, because that's where \c Data.qml is. - Then we create our main \c Rectangle and call it \c mainView: + Then we create our main \c Item and call it \c mainView: \snippet qmlscatter/qml/qmlscatter/main.qml 1 - Then we'll add another \c Item inside the main \c Rectangle, and call it \c dataView. + Then we'll add another \c Item inside the main \c Item, and call it \c dataView. This will be the item to hold the Scatter3D graph. We'll anchor it to the parent bottom: \snippet qmlscatter/qml/qmlscatter/main.qml 9 diff --git a/examples/datavisualization/qmlscatter/qml/qmlscatter/main.qml b/examples/datavisualization/qmlscatter/qml/qmlscatter/main.qml index bafbfc57..89863d84 100644 --- a/examples/datavisualization/qmlscatter/qml/qmlscatter/main.qml +++ b/examples/datavisualization/qmlscatter/qml/qmlscatter/main.qml @@ -36,7 +36,7 @@ import "." //! [0] //! [1] -Rectangle { +Item { id: mainView //! [1] width: 500 diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc index bc68d2fb..df2143a3 100644 --- a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc @@ -89,26 +89,19 @@ How the graph will be rendered. Defaults to \c{RenderIndirect}. \value RenderDirectToBackground - Indicates that the graph will be rendered directly on the window background. + Indicates that the graph will be rendered directly on the window background and QML items are + rendered on top of it. Using non-transparent QML item as a background will hide the graph. Clears the whole window before rendering the graph, including the areas - outside the graph. - Since the graphs in this rendering mode are drawn on the window background under other QML - items, the regular QML window clearing before rendering is suppressed. The graphs handle the clearing - themselves instead. - If the surface format of the window supports antialiasing, it will be used (see - \c {qDefaultSurfaceFormat()}). + outside the graph. If the surface format of the window supports antialiasing, it will be used (see + \c {QtDataVisualization::qDefaultSurfaceFormat()}). This rendering mode offers the best performance at the expense of non-standard QML behavior. For example, the graphs do not obey the z ordering of QML items and the opacity value has no effect on them. + \value RenderDirectToBackground_NoClear - Similar to \c RenderDirectToBackground mode, except that the graph will not clear the whole - window before rendering the graph. This mode is better for windows where you have other custom items - besides the graphs that also draw on the window background. In that case you need to either take care - of the window clearing yourself or ensure that all areas of the window are fully covered with opaque - items. - If one graph in the window uses either of the direct rendering modes, then all other graphs in the - same window also drawn in direct modes should use the exact same direct rendering mode. - Otherwise some graphs may not show up, depending on the drawing order of the graphs. + \obsolete + \note This will work exactly the same way as \c RenderDirectToBackground does in Qt 6 + as not clearing the window is not supported anymore. \value RenderIndirect Indicates the graph will be first rendered to an offscreen surface that diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp index ccc03d19..dbbd803d 100644 --- a/src/datavisualizationqml2/abstractdeclarative.cpp +++ b/src/datavisualizationqml2/abstractdeclarative.cpp @@ -46,9 +46,7 @@ QT_BEGIN_NAMESPACE -static QList clearList; static QHash graphWindowList; -static QHash windowClearList; AbstractDeclarative::AbstractDeclarative(QQuickItem *parent) : QQuickItem(parent), @@ -106,7 +104,7 @@ void AbstractDeclarative::setRenderingMode(AbstractDeclarative::RenderingMode mo update(); setFlag(ItemHasContents, false); if (win) { - QObject::connect(win, &QQuickWindow::beforeRendering, this, + QObject::connect(win, &QQuickWindow::beforeRenderPassRecording, this, &AbstractDeclarative::render, Qt::DirectConnection); checkWindowList(win); setAntialiasing(m_windowSamples > 0); @@ -120,7 +118,7 @@ void AbstractDeclarative::setRenderingMode(AbstractDeclarative::RenderingMode mo setFlag(ItemHasContents, !m_runningInDesigner); update(); if (win) { - QObject::disconnect(win, &QQuickWindow::beforeRendering, this, + QObject::disconnect(win, &QQuickWindow::beforeRenderPassRecording, this, &AbstractDeclarative::render); checkWindowList(win); } @@ -407,9 +405,6 @@ void AbstractDeclarative::doneOpenGLContext(QQuickWindow *window) void AbstractDeclarative::synchDataToRenderer() { - if (m_renderMode == RenderDirectToBackground && clearList.size()) - clearList.clear(); - QQuickWindow *win = window(); activateOpenGLContext(win); m_controller->synchDataToRenderer(); @@ -444,7 +439,6 @@ void AbstractDeclarative::setMsaaSamples(int samples) void AbstractDeclarative::handleWindowChanged(QQuickWindow *window) { checkWindowList(window); - if (!window) return; @@ -473,7 +467,7 @@ void AbstractDeclarative::handleWindowChanged(QQuickWindow *window) if (m_renderMode == RenderDirectToBackground_NoClear || m_renderMode == RenderDirectToBackground) { - connect(window, &QQuickWindow::beforeRendering, this, &AbstractDeclarative::render, + connect(window, &QQuickWindow::beforeRenderPassRecording, this, &AbstractDeclarative::render, Qt::DirectConnection); setAntialiasing(m_windowSamples > 0); if (m_windowSamples != oldWindowSamples) @@ -580,14 +574,10 @@ void AbstractDeclarative::render() // Clear the background once per window as that is not done by default QQuickWindow *win = window(); + win->beginExternalCommands(); activateOpenGLContext(win); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - if (m_renderMode == RenderDirectToBackground && !clearList.contains(win)) { - clearList.append(win); - QColor clearColor = win->color(); - funcs->glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f); - funcs->glClear(GL_COLOR_BUFFER_BIT); - } if (isVisible()) { funcs->glDepthMask(GL_TRUE); @@ -601,7 +591,9 @@ void AbstractDeclarative::render() funcs->glEnable(GL_BLEND); } + doneOpenGLContext(win); + win->endExternalCommands(); } QAbstract3DInputHandler* AbstractDeclarative::inputHandler() const @@ -653,7 +645,6 @@ void AbstractDeclarative::wheelEvent(QWheelEvent *event) void AbstractDeclarative::checkWindowList(QQuickWindow *window) { QQuickWindow *oldWindow = graphWindowList.value(this); - graphWindowList[this] = window; if (oldWindow != window && oldWindow) { @@ -661,7 +652,7 @@ void AbstractDeclarative::checkWindowList(QQuickWindow *window) &AbstractDeclarative::windowDestroyed); QObject::disconnect(oldWindow, &QQuickWindow::beforeSynchronizing, this, &AbstractDeclarative::synchDataToRenderer); - QObject::disconnect(oldWindow, &QQuickWindow::beforeRendering, this, + QObject::disconnect(oldWindow, &QQuickWindow::beforeRenderPassRecording, this, &AbstractDeclarative::render); if (!m_controller.isNull()) { QObject::disconnect(m_controller.data(), &Abstract3DController::needRender, @@ -678,20 +669,10 @@ void AbstractDeclarative::checkWindowList(QQuickWindow *window) } } - if (oldWindow && !windowList.contains(oldWindow) - && windowClearList.contains(oldWindow)) { - windowClearList.remove(oldWindow); - } - if (!window) { graphWindowList.remove(this); return; } - - if ((m_renderMode == RenderDirectToBackground - || m_renderMode == RenderDirectToBackground_NoClear) - && !windowClearList.contains(window)) { - } } void AbstractDeclarative::setMeasureFps(bool enable) @@ -829,8 +810,6 @@ void AbstractDeclarative::windowDestroyed(QObject *obj) if (win == oldWindow) graphWindowList.remove(this); - - windowClearList.remove(win); } void AbstractDeclarative::destroyContext() diff --git a/tests/manual/qmldynamicdata/qml/qmldynamicdata/main.qml b/tests/manual/qmldynamicdata/qml/qmldynamicdata/main.qml index 25bf3486..74ec5cb9 100644 --- a/tests/manual/qmldynamicdata/qml/qmldynamicdata/main.qml +++ b/tests/manual/qmldynamicdata/qml/qmldynamicdata/main.qml @@ -32,7 +32,7 @@ import QtDataVisualization 1.2 import QtQuick.Controls import "." -Rectangle { +Item { id: mainView width: 1280 height: 720 diff --git a/tests/manual/qmlgradient/qml/qmlgradient/main.qml b/tests/manual/qmlgradient/qml/qmlgradient/main.qml index 7df90def..c692a72a 100644 --- a/tests/manual/qmlgradient/qml/qmlgradient/main.qml +++ b/tests/manual/qmlgradient/qml/qmlgradient/main.qml @@ -34,7 +34,7 @@ import QtQuick.Controls import QtDataVisualization 1.2 import "." -Rectangle { +Item { id: mainwindow function updateinfoLabels() diff --git a/tests/manual/qmlmultitest/qml/qmlmultitest/main.qml b/tests/manual/qmlmultitest/qml/qmlmultitest/main.qml index 890f9479..54c85e95 100644 --- a/tests/manual/qmlmultitest/qml/qmlmultitest/main.qml +++ b/tests/manual/qmlmultitest/qml/qmlmultitest/main.qml @@ -33,7 +33,7 @@ import QtQuick.Controls import QtDataVisualization 1.2 import "." -Rectangle { +Item { id: mainView width: 800 height: 600 @@ -57,6 +57,7 @@ Rectangle { Layout.fillWidth: true border.color: surfaceGraph.theme.gridLineColor border.width: 2 + color: "#00000000" Surface3D { id: surfaceGraph @@ -145,6 +146,7 @@ Rectangle { Layout.fillWidth: true border.color: scatterGraph.theme.gridLineColor border.width: 2 + color: "#00000000" Scatter3D { id: scatterGraph @@ -185,6 +187,7 @@ Rectangle { Layout.fillWidth: true border.color: barGraph.theme.gridLineColor border.width: 2 + color: "#00000000" Bars3D { id: barGraph diff --git a/tests/manual/qmlperf/qml/qmlperf/main.qml b/tests/manual/qmlperf/qml/qmlperf/main.qml index 1ff64ad5..60930606 100644 --- a/tests/manual/qmlperf/qml/qmlperf/main.qml +++ b/tests/manual/qmlperf/qml/qmlperf/main.qml @@ -33,7 +33,7 @@ import QtQuick.Controls import QtDataVisualization 1.2 import "." -Rectangle { +Item { id: mainview width: 1280 height: 1024 -- cgit v1.2.3