summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPasi Keranen <pasi.keranen@digia.com>2014-02-17 09:29:48 +0200
committerPasi Keränen <pasi.keranen@digia.com>2014-02-17 13:48:21 +0200
commit7eb24d68115619d8d78e6a427d5c723e5ffc15a5 (patch)
treef66ef63a5b6894377413fadd212405cae63082e6
parent4f32a3e71e90c314e0a2f9f2bb19cc2eeb97292d (diff)
First step towards FXAA based antialiasing.
Change-Id: I40e767373156cf3e7f89c05767846a4949df319c Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc50
-rw-r--r--src/datavisualizationqml2/abstractdeclarative.cpp114
-rw-r--r--src/datavisualizationqml2/abstractdeclarative_p.h24
-rw-r--r--src/datavisualizationqml2/datavisualizationqml2.pro6
-rw-r--r--src/datavisualizationqml2/declarativerendernode.cpp83
-rw-r--r--src/datavisualizationqml2/declarativerendernode_p.h64
6 files changed, 295 insertions, 46 deletions
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
index df503eb4..116b63e0 100644
--- a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
@@ -66,20 +66,44 @@
*/
/*!
- \qmlproperty bool AbstractGraph3D::clearWindowBeforeRendering
-
- Indicates if the graph should also clear the whole window before rendering the graph,
- including the areas outside the graph.
- Since the graphs are drawn first under other QML items, the regular QML window clearing
- before rendering is suppressed when there are any graphs in the window; the graphs
- handle the clearing themselves instead.
+ \qmlproperty AbstractGraph3D.RenderingMode AbstractGraph3D::renderingMode
+
+ Defaults to DirectToBackground.
+
+ \table
+ \header
+ \li Render Mode
+ \li Description
+ \row
+ \li DirectToBackground
+ \li Indicates that the graph should also clear the whole window before
+ rendering the graph, including the areas outside the graph.
+ Since the graphs in this rendering mode are drawn first under other QML items, the
+ regular QML window clearing before rendering is suppressed when there are any graphs
+ in the window; the graphs handle the clearing themselves instead.
If you have any other items besides graphs that do similar
- custom drawing under other QML items, you need to set this property to false on all graphs
- drawn to same window with the other custom items, or it is likely that the
- other custom items do not render properly.
- Defaults to true.
-
- \note This property should be set to the same value for all graphs in the same window.
+ custom drawing under other QML items, you need to set this property to DirectToBackground_NoClear
+ on all graphs drawn to same window with the other custom items, or it is likely that the
+ other custom items do not render properly. If the graphics hardware and current configuration
+ supports antialiasing that will be used to provide a higher quality rendering with good performance.
+ See \c {QtDataVisualization::qDefaultSurfaceFormat}.
+ \row
+ \li DirectToBackground_NoClear
+ \li Indicates the graph will not clear the whole window before rendering
+ the graph. The graphs in this renderind mode are drawn first under other QML items.
+ If the graphics hardware and current configuration supports antialiasing that will be
+ used to provide a higher quality rendering with good performance.
+ See \c {QtDataVisualization::qDefaultSurfaceFormat}.
+ \row
+ \li Indirect_NoAA
+ \li Indicates the graph will be first rendered to an offscreen surface that
+ is then drawn during normal QML item rendering to the correct Z order. No antialiasing
+ post processing is done on the graph, meaning the quality will be lower but performance
+ should be better.
+ \endtable
+
+ \note If one graph in the window uses either DirectToBackground or DirectToBackground_NoClear, then all
+ other graphs in the window drawn in direct mode should use the same rendering mode in that window.
Otherwise some graphs may not show.
\note If window clearing before rendering is suppressed, any areas of the window not fully
diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp
index 2dc600c2..7415df9b 100644
--- a/src/datavisualizationqml2/abstractdeclarative.cpp
+++ b/src/datavisualizationqml2/abstractdeclarative.cpp
@@ -19,6 +19,7 @@
#include "abstractdeclarative_p.h"
#include "qvalue3daxis.h"
#include "declarativetheme_p.h"
+#include "declarativerendernode_p.h"
#include <QThread>
#include <QGuiApplication>
@@ -33,7 +34,9 @@ static QHash<QQuickWindow *, bool> windowClearList;
AbstractDeclarative::AbstractDeclarative(QQuickItem *parent) :
QQuickItem(parent),
m_controller(0),
- m_clearWindowBeforeRendering(true)
+ m_renderMode(DirectToBackground),
+ m_node(0),
+ m_initialisedSize(0, 0)
{
connect(this, &QQuickItem::windowChanged, this, &AbstractDeclarative::handleWindowChanged);
setAntialiasing(true);
@@ -45,6 +48,68 @@ AbstractDeclarative::~AbstractDeclarative()
checkWindowList(0);
}
+void AbstractDeclarative::setRenderingMode(AbstractDeclarative::RenderingMode mode)
+{
+ if (mode == m_renderMode)
+ return;
+
+ m_renderMode = mode;
+
+ switch (mode) {
+ case DirectToBackground:
+ // Intentional flowthrough
+ case DirectToBackground_NoClear:
+ // Delete render node
+ delete m_node;
+ m_node = 0;
+ m_initialisedSize = QSize(0, 0);
+ setAntialiasing(true);
+ setFlag(QQuickItem::ItemHasContents, false);
+ break;
+ case Indirect_NoAA:
+ // Force recreation of render node by resetting the initialized size
+ setAntialiasing(false);
+ m_initialisedSize = QSize(0, 0);
+ setFlag(QQuickItem::ItemHasContents, true);
+ break;
+ }
+
+ updateWindowParameters();
+
+ emit renderingModeChanged(mode);
+}
+
+AbstractDeclarative::RenderingMode AbstractDeclarative::renderingMode() const
+{
+ return m_renderMode;
+}
+
+QSGNode *AbstractDeclarative::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ // If old node exists and has right size, reuse it.
+ if (oldNode && m_initialisedSize == boundingRect().size().toSize()) {
+ // Update bounding rectangle (that has same size as before).
+ DeclarativeRenderNode *renderNode = static_cast<DeclarativeRenderNode *>(oldNode);
+ renderNode->setRect(boundingRect());
+ return oldNode;
+ }
+
+ // Create a new render node when size changes or if there is no node yet
+ m_initialisedSize = boundingRect().size().toSize();
+
+ // Delete old node
+ if (oldNode) {
+ m_node = 0;
+ delete oldNode;
+ }
+
+ // Create a new one and set its bounding rectangle
+ DeclarativeRenderNode *node = new DeclarativeRenderNode(window(), m_controller, m_renderMode, this);
+ node->setRect(boundingRect());
+ m_node = node;
+ return node;
+}
+
Declarative3DScene* AbstractDeclarative::scene() const
{
return static_cast<Declarative3DScene *>(m_controller->scene());
@@ -65,19 +130,6 @@ void AbstractDeclarative::clearSelection()
m_controller->clearSelection();
}
-void AbstractDeclarative::setClearWindowBeforeRendering(bool enable)
-{
- if (m_clearWindowBeforeRendering != enable) {
- m_clearWindowBeforeRendering = enable;
- emit clearWindowBeforeRenderingChanged(enable);
- }
-}
-
-bool AbstractDeclarative::clearWindowBeforeRendering() const
-{
- return m_clearWindowBeforeRendering;
-}
-
void AbstractDeclarative::setSelectionMode(SelectionFlags mode)
{
int intmode = int(mode);
@@ -130,7 +182,7 @@ void AbstractDeclarative::setSharedController(Abstract3DController *controller)
void AbstractDeclarative::synchDataToRenderer()
{
- if (m_clearWindowBeforeRendering && clearList.size())
+ if (m_renderMode == DirectToBackground && clearList.size())
clearList.clear();
m_controller->initializeOpenGL();
m_controller->synchDataToRenderer();
@@ -143,12 +195,14 @@ void AbstractDeclarative::handleWindowChanged(QQuickWindow *window)
if (!window)
return;
- connect(window, &QQuickWindow::beforeSynchronizing, this,
- &AbstractDeclarative::synchDataToRenderer, Qt::DirectConnection);
- connect(window, &QQuickWindow::beforeRendering, this,
- &AbstractDeclarative::render, Qt::DirectConnection);
- connect(m_controller.data(), &Abstract3DController::needRender, window,
- &QQuickWindow::update);
+ connect(window, &QQuickWindow::beforeSynchronizing,
+ this, &AbstractDeclarative::synchDataToRenderer,
+ Qt::DirectConnection);
+ connect(window, &QQuickWindow::beforeRendering,
+ this, &AbstractDeclarative::render,
+ Qt::DirectConnection);
+ connect(m_controller.data(), &Abstract3DController::needRender,
+ window, &QQuickWindow::update);
updateWindowParameters();
}
@@ -184,9 +238,15 @@ void AbstractDeclarative::updateWindowParameters()
win->update();
}
- QPointF point = QQuickItem::mapToScene(QPointF(0.0f, 0.0f));
- scene->d_ptr->setViewport(QRect(point.x(), point.y(), m_cachedGeometry.width(),
- m_cachedGeometry.height()));
+ if (m_renderMode == DirectToBackground || m_renderMode == DirectToBackground_NoClear) {
+ // Origo mapping is needed when rendering directly to background
+ QPointF point = QQuickItem::mapToScene(QPointF(0.0f, 0.0f));
+ scene->d_ptr->setViewport(QRect(point.x(), point.y(), m_cachedGeometry.width(),
+ m_cachedGeometry.height()));
+ } else {
+ // No translation needed when rendering to FBO
+ scene->d_ptr->setViewport(m_cachedGeometry.toRect());
+ }
}
}
@@ -205,9 +265,13 @@ void AbstractDeclarative::render()
{
updateWindowParameters();
+ // If we're not rendering directly to the background, return
+ if (m_renderMode != DirectToBackground && m_renderMode != DirectToBackground_NoClear)
+ return;
+
// Clear the background once per window as that is not done by default
const QQuickWindow *win = window();
- if (m_clearWindowBeforeRendering && !clearList.contains(win)) {
+ if (m_renderMode == DirectToBackground && !clearList.contains(win)) {
clearList.append(win);
QColor clearColor = win->color();
glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f);
diff --git a/src/datavisualizationqml2/abstractdeclarative_p.h b/src/datavisualizationqml2/abstractdeclarative_p.h
index 16effca0..83a1bbdb 100644
--- a/src/datavisualizationqml2/abstractdeclarative_p.h
+++ b/src/datavisualizationqml2/abstractdeclarative_p.h
@@ -42,17 +42,20 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+class DeclarativeRenderNode;
+
class AbstractDeclarative : public QQuickItem
{
Q_OBJECT
Q_ENUMS(ShadowQuality)
+ Q_ENUMS(RenderingMode)
Q_FLAGS(SelectionFlag SelectionFlags)
Q_PROPERTY(SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged)
Q_PROPERTY(ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged)
Q_PROPERTY(Declarative3DScene* scene READ scene NOTIFY sceneChanged)
Q_PROPERTY(QAbstract3DInputHandler* inputHandler READ inputHandler WRITE setInputHandler NOTIFY inputHandlerChanged)
Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged)
- Q_PROPERTY(bool clearWindowBeforeRendering READ clearWindowBeforeRendering WRITE setClearWindowBeforeRendering NOTIFY clearWindowBeforeRenderingChanged)
+ Q_PROPERTY(RenderingMode renderingMode READ renderingMode WRITE setRenderingMode NOTIFY renderingModeChanged)
public:
enum SelectionFlag {
@@ -79,10 +82,19 @@ public:
ShadowQualitySoftHigh
};
+ enum RenderingMode {
+ DirectToBackground = 0,
+ DirectToBackground_NoClear,
+ Indirect_NoAA
+ };
+
public:
explicit AbstractDeclarative(QQuickItem *parent = 0);
virtual ~AbstractDeclarative();
+ virtual void setRenderingMode(RenderingMode mode);
+ virtual AbstractDeclarative::RenderingMode renderingMode() const;
+
virtual void setSelectionMode(SelectionFlags mode);
virtual AbstractDeclarative::SelectionFlags selectionMode() const;
@@ -99,9 +111,6 @@ public:
Q_INVOKABLE virtual void clearSelection();
- virtual void setClearWindowBeforeRendering(bool enable);
- virtual bool clearWindowBeforeRendering() const;
-
virtual void geometryChanged(const QRectF & newGeometry, const QRectF & oldGeometry);
void setSharedController(Abstract3DController *controller);
@@ -128,6 +137,7 @@ protected:
virtual void updateWindowParameters();
virtual void handleSelectionModeChange(QAbstract3DGraph::SelectionFlags mode);
virtual void handleShadowQualityChange(QAbstract3DGraph::ShadowQuality quality);
+ virtual QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
signals:
void selectionModeChanged(SelectionFlags mode);
@@ -135,12 +145,14 @@ signals:
void sceneChanged(Q3DScene *scene);
void inputHandlerChanged(QAbstract3DInputHandler *inputHandler);
void themeChanged(Q3DTheme *theme);
- void clearWindowBeforeRenderingChanged(bool enable);
+ void renderingModeChanged(RenderingMode mode);
private:
QPointer<Abstract3DController> m_controller;
QRectF m_cachedGeometry;
- bool m_clearWindowBeforeRendering;
+ AbstractDeclarative::RenderingMode m_renderMode;
+ DeclarativeRenderNode *m_node;
+ QSize m_initialisedSize;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractDeclarative::SelectionFlags)
diff --git a/src/datavisualizationqml2/datavisualizationqml2.pro b/src/datavisualizationqml2/datavisualizationqml2.pro
index d6e8570c..254fefde 100644
--- a/src/datavisualizationqml2/datavisualizationqml2.pro
+++ b/src/datavisualizationqml2/datavisualizationqml2.pro
@@ -25,7 +25,8 @@ SOURCES += \
declarativeseries.cpp \
declarativetheme.cpp \
declarativecolor.cpp \
- declarativescene.cpp
+ declarativescene.cpp \
+ declarativerendernode.cpp
HEADERS += \
datavisualizationqml2_plugin.h \
@@ -37,7 +38,8 @@ HEADERS += \
declarativeseries_p.h \
declarativetheme_p.h \
declarativecolor_p.h \
- declarativescene_p.h
+ declarativescene_p.h \
+ declarativerendernode_p.h
OTHER_FILES = qmldir
diff --git a/src/datavisualizationqml2/declarativerendernode.cpp b/src/datavisualizationqml2/declarativerendernode.cpp
new file mode 100644
index 00000000..612d11df
--- /dev/null
+++ b/src/datavisualizationqml2/declarativerendernode.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativerendernode_p.h"
+#include <QtQuick/QQuickWindow>
+#include <QtGui/QOpenGLFramebufferObject>
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+DeclarativeRenderNode::DeclarativeRenderNode(QQuickWindow *window, Abstract3DController *controller, AbstractDeclarative::RenderingMode mode, QObject *parent)
+ : QObject(parent),
+ m_fbo(0),
+ m_texture(0),
+ m_window(window),
+ m_controller(controller),
+ m_mode(mode)
+{
+ connect(window, &QQuickWindow::beforeRendering,
+ this, &DeclarativeRenderNode::renderFBO,
+ Qt::DirectConnection);
+}
+
+DeclarativeRenderNode::~DeclarativeRenderNode()
+{
+ delete m_texture;
+ delete m_fbo;
+}
+
+void DeclarativeRenderNode::renderFBO()
+{
+ QSize size = rect().size().toSize();
+
+ // Create FBO
+ if (!m_fbo) {
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::Depth);
+ m_fbo = new QOpenGLFramebufferObject(size, format);
+ m_texture = m_window->createTextureFromId(m_fbo->texture(), size);
+
+ setTexture(m_texture);
+
+ // Flip texture
+ QSize ts = m_texture->textureSize();
+ QRectF sourceRect(0, 0, ts.width(), ts.height());
+ float tmp = sourceRect.top();
+ sourceRect.setTop(sourceRect.bottom());
+ sourceRect.setBottom(tmp);
+ QSGGeometry *geometry = this->geometry();
+ QSGGeometry::updateTexturedRectGeometry(geometry, rect(),
+ m_texture->convertToNormalizedSourceRect(sourceRect));
+ markDirty(DirtyMaterial);
+ }
+
+ // Call the shared rendering function
+ m_fbo->bind();
+ glDisable(GL_BLEND);
+
+ m_controller->render(m_fbo->handle());
+
+ glEnable(GL_BLEND);
+
+ m_fbo->release();
+
+ // New view is in the FBO, request repaint of scene graph
+ m_window->update();
+}
+
+QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualizationqml2/declarativerendernode_p.h b/src/datavisualizationqml2/declarativerendernode_p.h
new file mode 100644
index 00000000..b8250512
--- /dev/null
+++ b/src/datavisualizationqml2/declarativerendernode_p.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef DECLARATIVERENDERNODE_P_H
+#define DECLARATIVERENDERNODE_P_H
+
+#include <QObject>
+#include "datavisualizationglobal_p.h"
+#include "abstract3dcontroller_p.h"
+#include "abstractdeclarative_p.h"
+#include <qsgsimpletexturenode.h>
+
+class QOpenGLFramebufferObject;
+class QSGTexture;
+class QQuickWindow;
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class DeclarativeRenderNode : public QObject, public QSGSimpleTextureNode
+{
+ Q_OBJECT
+public:
+ explicit DeclarativeRenderNode(QQuickWindow *window, Abstract3DController *controller, AbstractDeclarative::RenderingMode mode, QObject *parent = 0);
+ virtual ~DeclarativeRenderNode();
+
+ // Renders view to FBO before render cycle starts.
+ void renderFBO();
+
+private:
+ QOpenGLFramebufferObject *m_fbo;
+ QSGTexture *m_texture;
+ QQuickWindow *m_window;
+ QPointer<Abstract3DController> m_controller;
+ AbstractDeclarative::RenderingMode m_mode;
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif // DECLARATIVERENDERNODE_P_H