summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2017-02-15 16:18:23 +0200
committerPaolo Angelelli <paolo.angelelli@qt.io>2017-02-16 12:26:48 +0000
commite0c9c70b229e6b5dbe99e3cfb258206e4a5570b3 (patch)
tree2633b92386c56e0a9e6249f12586c6eb611be980
parent270d7a4d5ea707b331efdf05f94442145b1035cf (diff)
downloadqtlocation-e0c9c70b229e6b5dbe99e3cfb258206e4a5570b3.tar.gz
Optional support for QSGMapboxGLRenderNode
QSGMapboxGLRenderNode support is experimental: It doesn't support QQuickItem transforms nor stencil clipping. By default, QSGMapboxGLTextureNode is enabled. The user can select QSGMapboxGLRenderNode by setting 'mapboxgl.use_fbo' plugin parameter to 'false'. Change-Id: I3d5338990458f62fdbe7b8dc00317a85ee1ff188 Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io>
-rw-r--r--src/location/doc/src/plugins/mapboxgl.qdoc10
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp45
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h1
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp5
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h1
-rw-r--r--src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp60
-rw-r--r--src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h25
7 files changed, 124 insertions, 23 deletions
diff --git a/src/location/doc/src/plugins/mapboxgl.qdoc b/src/location/doc/src/plugins/mapboxgl.qdoc
index 9269bfdf..29a5cb20 100644
--- a/src/location/doc/src/plugins/mapboxgl.qdoc
+++ b/src/location/doc/src/plugins/mapboxgl.qdoc
@@ -101,5 +101,15 @@ The following table lists optional parameters that can be passed to the Mapbox p
\li Cache size for map resources in bytes.
The default size of this cache is 50 MiB.
Make sure to comply with Mapbox Terms of Service before increasing this value.
+\row
+ \li mapboxgl.use_fbo
+ \li Sets whether to use a framebuffer object to render Mapbox GL Native.
+ Valid values are \b true and \b false. The default value is \b true. When
+ set to \b false, the map is rendered issuing OpenGL commands directly,
+ through a QSGRenderNode, to improve the rendering performance. This mode is
+ experimental, and it does not support QQuickItem transformations nor stencil
+ clipping. It might be also produce rendering artifacts e.g. when adding it
+ inside a \l{QtQuick::Flipable}{Flipable} item.
+
\endtable
*/
diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
index b0987c73..eab7b88a 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
+++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
@@ -146,6 +146,7 @@ public:
Q_DECLARE_FLAGS(SyncStates, SyncState);
QMapboxGLSettings m_settings;
+ bool m_useFBO = true;
bool m_developmentMode = false;
QTimer m_refresh;
@@ -183,7 +184,7 @@ QGeoMapMapboxGLPrivate::~QGeoMapMapboxGLPrivate()
{
}
-QSGNode *QGeoMapMapboxGLPrivate::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window)
+QSGNode *QGeoMapMapboxGLPrivate::updateSceneGraph(QSGNode *node, QQuickWindow *window)
{
Q_Q(QGeoMapMapboxGL);
@@ -196,15 +197,25 @@ QSGNode *QGeoMapMapboxGLPrivate::updateSceneGraph(QSGNode *oldNode, QQuickWindow
m_warned = true;
}
- QSGMapboxGLNode *mbglNode = static_cast<QSGMapboxGLNode *>(oldNode);
- if (!mbglNode) {
- mbglNode = new QSGMapboxGLNode(m_settings, m_viewportSize, window->devicePixelRatio(), q);
- QObject::connect(mbglNode->map(), &QMapboxGL::mapChanged, q, &QGeoMapMapboxGL::onMapChanged);
- m_syncState = MapTypeSync | CameraDataSync | ViewportSync;
+ QMapboxGL *map = 0;
+ if (m_useFBO) {
+ if (!node) {
+ QSGMapboxGLTextureNode *mbglNode = new QSGMapboxGLTextureNode(m_settings, m_viewportSize, window->devicePixelRatio(), q);
+ QObject::connect(mbglNode->map(), &QMapboxGL::mapChanged, q, &QGeoMapMapboxGL::onMapChanged);
+ m_syncState = MapTypeSync | CameraDataSync | ViewportSync;
+ node = mbglNode;
+ }
+ map = static_cast<QSGMapboxGLTextureNode *>(node)->map();
+ } else {
+ if (!node) {
+ QSGMapboxGLRenderNode *mbglNode = new QSGMapboxGLRenderNode(m_settings, m_viewportSize, window->devicePixelRatio(), q);
+ QObject::connect(mbglNode->map(), &QMapboxGL::mapChanged, q, &QGeoMapMapboxGL::onMapChanged);
+ m_syncState = MapTypeSync | CameraDataSync | ViewportSync;
+ node = mbglNode;
+ }
+ map = static_cast<QSGMapboxGLRenderNode *>(node)->map();
}
- QMapboxGL *map = mbglNode->map();
-
if (m_syncState & MapTypeSync) {
m_developmentMode = m_activeMapType.name().startsWith("mapbox://")
&& m_settings.accessToken() == developmentToken;
@@ -319,14 +330,20 @@ QSGNode *QGeoMapMapboxGLPrivate::updateSceneGraph(QSGNode *oldNode, QQuickWindow
}
if (m_syncState & ViewportSync) {
- mbglNode->resize(m_viewportSize, window->devicePixelRatio());
+ if (m_useFBO) {
+ static_cast<QSGMapboxGLTextureNode *>(node)->resize(m_viewportSize, window->devicePixelRatio());
+ } else {
+ map->resize(m_viewportSize, m_viewportSize * window->devicePixelRatio());
+ }
}
- mbglNode->render();
+ if (m_useFBO) {
+ static_cast<QSGMapboxGLTextureNode *>(node)->render(window);
+ }
m_syncState = NoSync;
- return mbglNode;
+ return node;
}
QGeoMap::ItemTypes QGeoMapMapboxGLPrivate::supportedMapItemTypes() const
@@ -465,6 +482,12 @@ void QGeoMapMapboxGL::setMapboxGLSettings(const QMapboxGLSettings& settings)
}
}
+void QGeoMapMapboxGL::setUseFBO(bool useFBO)
+{
+ Q_D(QGeoMapMapboxGL);
+ d->m_useFBO = useFBO;
+}
+
QSGNode *QGeoMapMapboxGL::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window)
{
Q_D(QGeoMapMapboxGL);
diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h
index 8386ae44..c43a1e28 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h
+++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h
@@ -53,6 +53,7 @@ public:
QString copyrightsStyleSheet() const Q_DECL_OVERRIDE;
void setMapboxGLSettings(const QMapboxGLSettings &);
+ void setUseFBO(bool);
private Q_SLOTS:
// QMapboxGL
diff --git a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp
index 04a800aa..0196c703 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp
+++ b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp
@@ -133,6 +133,10 @@ QGeoMappingManagerEngineMapboxGL::QGeoMappingManagerEngineMapboxGL(const QVarian
m_settings.setCacheDatabaseMaximumSize(cacheSize);
}
+ if (parameters.contains(QStringLiteral("mapboxgl.use_fbo"))) {
+ m_useFBO = parameters.value(QStringLiteral("mapboxgl.use_fbo")).toBool();
+ }
+
engineInitialized();
}
@@ -144,6 +148,7 @@ QGeoMap *QGeoMappingManagerEngineMapboxGL::createMap()
{
QGeoMapMapboxGL* map = new QGeoMapMapboxGL(this, 0);
map->setMapboxGLSettings(m_settings);
+ map->setUseFBO(m_useFBO);
return map;
}
diff --git a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h
index 1bf44064..c5923cda 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h
+++ b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h
@@ -58,6 +58,7 @@ public:
private:
QMapboxGLSettings m_settings;
+ bool m_useFBO = true;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp
index 4e331afb..4a76ac29 100644
--- a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp
+++ b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp
@@ -35,16 +35,19 @@
**
****************************************************************************/
-#include <qsgmapboxglnode.h>
-#include <qgeomapmapboxgl.h>
+#include "qsgmapboxglnode.h"
+#include "qgeomapmapboxgl.h"
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
-QSGMapboxGLNode::QSGMapboxGLNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap)
+// QSGMapboxGLTextureNode
+
+QSGMapboxGLTextureNode::QSGMapboxGLTextureNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap)
: QSGSimpleTextureNode()
{
setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
+ setFiltering(QSGTexture::Linear);
m_map.reset(new QMapboxGL(nullptr, settings, size, pixelRatio));
@@ -53,7 +56,7 @@ QSGMapboxGLNode::QSGMapboxGLNode(const QMapboxGLSettings &settings, const QSize
static_cast<void (QGeoMap::*)(const QString &)>(&QGeoMapMapboxGL::copyrightsChanged));
}
-void QSGMapboxGLNode::resize(const QSize &size, qreal pixelRatio)
+void QSGMapboxGLTextureNode::resize(const QSize &size, qreal pixelRatio)
{
const QSize fbSize = size * pixelRatio;
m_map->resize(size, fbSize);
@@ -76,20 +79,61 @@ void QSGMapboxGLNode::resize(const QSize &size, qreal pixelRatio)
markDirty(QSGNode::DirtyGeometry);
}
-void QSGMapboxGLNode::render()
+void QSGMapboxGLTextureNode::render(QQuickWindow *window)
{
- QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ window->setClearBeforeRendering(false);
+
+ QOpenGLFunctions *f = window->openglContext()->functions();
f->glViewport(0, 0, m_fbo->width(), m_fbo->height());
m_fbo->bind();
- m_map->render(m_fbo.data());
+ m_map->render();
m_fbo->release();
+ window->resetOpenGLState();
markDirty(QSGNode::DirtyMaterial);
}
-QMapboxGL* QSGMapboxGLNode::map() const
+QMapboxGL* QSGMapboxGLTextureNode::map() const
{
return m_map.data();
}
+// QSGMapboxGLRenderNode
+
+QSGMapboxGLRenderNode::QSGMapboxGLRenderNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap)
+ : QSGRenderNode()
+{
+ m_map.reset(new QMapboxGL(nullptr, settings, size, pixelRatio));
+ QObject::connect(m_map.data(), &QMapboxGL::needsRendering, geoMap, &QGeoMap::sgNodeChanged);
+ QObject::connect(m_map.data(), &QMapboxGL::copyrightsChanged, geoMap,
+ static_cast<void (QGeoMap::*)(const QString &)>(&QGeoMapMapboxGL::copyrightsChanged));
+}
+
+QMapboxGL* QSGMapboxGLRenderNode::map() const
+{
+ return m_map.data();
+}
+
+void QSGMapboxGLRenderNode::render(const RenderState *state)
+{
+ // QMapboxGL assumes we've prepared the viewport prior to render().
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ f->glViewport(state->scissorRect().x(), state->scissorRect().y(), state->scissorRect().width(), state->scissorRect().height());
+ f->glScissor(state->scissorRect().x(), state->scissorRect().y(), state->scissorRect().width(), state->scissorRect().height());
+ f->glEnable(GL_SCISSOR_TEST);
+
+ m_map->render();
+}
+
+QSGRenderNode::StateFlags QSGMapboxGLRenderNode::changedStates() const
+{
+ return QSGRenderNode::DepthState
+ | QSGRenderNode::StencilState
+ | QSGRenderNode::ScissorState
+ | QSGRenderNode::ColorState
+ | QSGRenderNode::BlendState
+ | QSGRenderNode::ViewportState
+ | QSGRenderNode::RenderTargetState;
+}
+
diff --git a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h
index bd7cc4b3..5805a76c 100644
--- a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h
+++ b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h
@@ -38,6 +38,8 @@
#ifndef QSGMAPBOXGLNODE_H
#define QSGMAPBOXGLNODE_H
+#include <QtQuick/QQuickWindow>
+#include <QtQuick/QSGRenderNode>
#include <QtQuick/QSGSimpleTextureNode>
#include <QtQuick/private/qsgtexture_p.h>
#include <QtGui/QOpenGLFramebufferObject>
@@ -46,19 +48,34 @@
class QGeoMapMapboxGL;
-class QSGMapboxGLNode : public QSGSimpleTextureNode
+class QSGMapboxGLTextureNode : public QSGSimpleTextureNode
{
public:
- QSGMapboxGLNode(const QMapboxGLSettings &, const QSize &, qreal pixelRatio, QGeoMapMapboxGL *geoMap);
+ QSGMapboxGLTextureNode(const QMapboxGLSettings &, const QSize &, qreal pixelRatio, QGeoMapMapboxGL *geoMap);
+
+ QMapboxGL* map() const;
void resize(const QSize &size, qreal pixelRatio);
- void render();
+ void render(QQuickWindow *);
+
+private:
+ QScopedPointer<QMapboxGL> m_map;
+ QScopedPointer<QOpenGLFramebufferObject> m_fbo;
+};
+
+class QSGMapboxGLRenderNode : public QSGRenderNode
+{
+public:
+ QSGMapboxGLRenderNode(const QMapboxGLSettings &, const QSize &, qreal pixelRatio, QGeoMapMapboxGL *geoMap);
QMapboxGL* map() const;
+ // QSGRenderNode
+ void render(const RenderState *state) Q_DECL_OVERRIDE;
+ StateFlags changedStates() const Q_DECL_OVERRIDE;
+
private:
QScopedPointer<QMapboxGL> m_map;
- QScopedPointer<QOpenGLFramebufferObject> m_fbo;
};
#endif // QSGMAPBOXGLNODE_H