diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2017-02-15 16:18:23 +0200 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2017-02-16 12:26:48 +0000 |
commit | e0c9c70b229e6b5dbe99e3cfb258206e4a5570b3 (patch) | |
tree | 2633b92386c56e0a9e6249f12586c6eb611be980 /src/plugins/geoservices/mapboxgl | |
parent | 270d7a4d5ea707b331efdf05f94442145b1035cf (diff) | |
download | qtlocation-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>
Diffstat (limited to 'src/plugins/geoservices/mapboxgl')
6 files changed, 114 insertions, 23 deletions
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 |