From 7eb24d68115619d8d78e6a427d5c723e5ffc15a5 Mon Sep 17 00:00:00 2001 From: Pasi Keranen Date: Mon, 17 Feb 2014 09:29:48 +0200 Subject: First step towards FXAA based antialiasing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I40e767373156cf3e7f89c05767846a4949df319c Reviewed-by: Tomi Korpipää Reviewed-by: Miikka Heikkinen --- src/datavisualizationqml2/abstractdeclarative.cpp | 114 +++++++++++++++++----- 1 file changed, 89 insertions(+), 25 deletions(-) (limited to 'src/datavisualizationqml2/abstractdeclarative.cpp') 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 #include @@ -33,7 +34,9 @@ static QHash 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(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(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); -- cgit v1.2.3