diff options
22 files changed, 246 insertions, 847 deletions
diff --git a/src/imports/location/location.pro b/src/imports/location/location.pro index 1538fe55..c04a16e0 100644 --- a/src/imports/location/location.pro +++ b/src/imports/location/location.pro @@ -1,4 +1,4 @@ -QT += quick-private network positioning-private location-private qml-private 3d core-private gui-private +QT += quick-private network positioning-private location-private qml-private core-private gui-private INCLUDEPATH += ../../location INCLUDEPATH += ../../location/maps @@ -27,7 +27,6 @@ HEADERS += \ qdeclarativegeomaptype_p.h \ qdeclarativegeomapitembase_p.h \ qdeclarativegeomapquickitem_p.h \ - mapnode_p.h \ qdeclarativecirclemapitem_p.h \ qdeclarativerectanglemapitem_p.h \ qdeclarativepolygonmapitem_p.h \ @@ -52,7 +51,6 @@ SOURCES += \ qdeclarativegeomaptype.cpp \ qdeclarativegeomapitembase.cpp \ qdeclarativegeomapquickitem.cpp \ - mapnode.cpp \ qdeclarativecirclemapitem.cpp \ qdeclarativerectanglemapitem.cpp \ qdeclarativepolygonmapitem.cpp \ diff --git a/src/imports/location/mapnode.cpp b/src/imports/location/mapnode.cpp deleted file mode 100644 index 3c557d35..00000000 --- a/src/imports/location/mapnode.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtLocation module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mapnode_p.h" -#include "qgeomap_p.h" -#include <Qt3D/qglpainter.h> -#include <Qt3D/QGLFramebufferObjectSurface> -#include <QtGui/QOpenGLFramebufferObject> -#include <QtQuick/private/qsgtexture_p.h> - -#ifndef GL_MULTISAMPLE -#define GL_MULTISAMPLE 0x809D -#endif - -MapNode::MapNode(QGeoMap *map): QSGGeometryNode(), - m_fbo(0), - m_fboSurface(0), - m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4), - m_texture(0), - m_map(map), - m_initialized(false), - m_dirtyFBO(false) -{ - setMaterial(&m_material); - setOpaqueMaterial(&m_opaqueMaterial); - setGeometry(&m_geometry); - // setFlag(UsePreprocess); -} - -MapNode::~MapNode() -{ - delete m_fboSurface; - delete m_fbo; -} - -void MapNode::saveRenderState() -{ - //TODO: implement me -} - -void MapNode::restoreRenderState() -{ - //TODO: implement me -} - -void -MapNode::preprocess() -{ - restoreRenderState(); - //TODO: implement me , texture update - saveRenderState(); -} - -void MapNode::update() -{ - restoreRenderState(); - - if (!m_initialized) - init(); - - if (m_dirtyFBO) - updateFBO(); - - saveRenderState(); -} - -void MapNode::updateFBO() -{ - QGLPainter painter; - - if (!painter.begin()) { - qWarning() << "GL graphics system is not active, can not update FBO for map"; - return; - } - - painter.pushSurface(m_fboSurface); - - glClearColor(0.9, 0.9, 0.9, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - painter.disableEffect(); -#ifdef GL_RESCALE_NORMAL - // Scale normals by a scale factor derived from modelview matrix. - // Note: normals need to be unit length. - glEnable(GL_RESCALE_NORMAL); -#endif - -#if !defined(QT_OPENGL_ES_2) - glShadeModel(GL_SMOOTH); - glEnable(GL_MULTISAMPLE); -#endif - - // Set the default effect for the scene. - painter.setStandardEffect(QGL::LitMaterial); - painter.setFaceColor(QGL::AllFaces, Qt::white); - -#if defined(QT_OPENGL_ES) - glClearDepthf(1); -#else - glClearDepth(1); -#endif - -#if defined(GL_LINE_SMOOTH) && defined(GL_LINE_SMOOTH_HINT) - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); -#endif - -#ifdef QSGSHADEREFFECTSOURCE_AVAILABLE - // Update any map objects that may have dirty textures - for (int i = 0; i < mapItems_.count(); ++i) { - mapItems_.at(i)->updateItem(); - } -#endif - - // No stereo rendering, set the eye as neutral - painter.setEye(QGL::NoEye); - // TODO this needs to be figured out (or confirmed as invalid thing). - // Currently applied transforms for this Map3D object - how to get/apply current transforms? - // QTransform transform = painter->combinedTransform(); - // Then we get the rectangle that is gotten by applying the QTransform on the rect - // --> this is the viewport for Map3D - // QRect viewport = transform.mapRect(boundingRect()).toRect(); - - // boundingRect is in local coordinates. We need to map it to the scene coordinates - // in order to render to correct area. - - if (m_map->glCamera()) { - painter.setCamera(m_map->glCamera()); - } else { - QGLCamera defCamera; - painter.setCamera(&defCamera); - } - m_map->paintGL(&painter); - - restoreDefaults(&painter); - - // Draw the children items - painter.popSurface(); - // QSG does not expect anyone to alter gl context state; restore defaults. - // Default heaps of things, because we cannot be sure what the Qt3D internally - // sets. - -#if defined(QT_OPENGL_ES) - glClearDepthf(0); -#else - glClearDepth(0); -#endif - - painter.end(); - - QSGGeometry::updateTexturedRectGeometry(&m_geometry, - QRectF(QPointF(0, m_fbo->size().height()), QPointF(m_fbo->size().width(), 0)), - QRectF(0, 0, 1, 1)); - delete m_texture; - m_texture = new QSGPlainTexture(); - m_texture->setOwnsTexture(false); - m_texture->setTextureSize(m_fbo->size()); - m_texture->setTextureId(m_fbo->texture()); - m_opaqueMaterial.setTexture(m_texture); - m_material.setTexture(m_texture); - - markDirty(DirtyMaterial); -} - -void MapNode::setSize(const QSize &size) -{ - if (size == m_size) - return; - m_size = size; - m_dirtyFBO = true; - m_initialized = false; - markDirty(DirtyGeometry); -} - -void MapNode::init() -{ - delete m_fboSurface; - delete m_fbo; - m_fbo = new QOpenGLFramebufferObject(m_size.width(), m_size.height()); - m_fboSurface = new QGLFramebufferObjectSurface(m_fbo); - m_initialized = true; -} - -void MapNode::restoreDefaults(QGLPainter *painter) -{ - // Disable the effect to return control to the GL paint engine. - painter->disableEffect(); - - // Try to restore the default options - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - // Set the default depth buffer options. - glDepthFunc(GL_LESS); - glDepthMask(GL_TRUE); -#if defined(QT_OPENGL_ES) - glDepthRangef(0.0f, 1.0f); -#else - glDepthRange(0.0f, 1.0f); -#endif - // Set the default blend options. - glDisable(GL_BLEND); - if (painter->hasOpenGLFeature(QOpenGLFunctions::BlendColor)) - painter->glBlendColor(0, 0, 0, 0); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if (painter->hasOpenGLFeature(QOpenGLFunctions::BlendEquation)) - painter->glBlendEquation(GL_FUNC_ADD); - else if (painter->hasOpenGLFeature(QOpenGLFunctions::BlendEquationSeparate)) - painter->glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); -} - diff --git a/src/imports/location/mapnode_p.h b/src/imports/location/mapnode_p.h deleted file mode 100644 index 911b8f77..00000000 --- a/src/imports/location/mapnode_p.h +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtLocation module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MAPNODE_H -#define MAPNODE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt 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. -// - -#include <QtQuick/QSGNode> -#include <QtQuick/QSGTextureMaterial> - -QT_BEGIN_NAMESPACE - -class QGeoMap; -class QOpenGLFramebufferObject; -class QGLFramebufferObjectSurface; -class QGLPainter; -class QSGPlainTexture; - -class MapNode : public QSGGeometryNode -{ -public: - explicit MapNode(QGeoMap *m_map); - ~MapNode(); - - void setSize(const QSize &size); - QSize size() const { return m_size; } - void update(); - void preprocess(); - -private: - void init(); - void updateFBO(); - void saveRenderState(); - void restoreRenderState(); - void restoreDefaults(QGLPainter *painter); - -private: - QOpenGLFramebufferObject *m_fbo; - QGLFramebufferObjectSurface *m_fboSurface; - QSGOpaqueTextureMaterial m_opaqueMaterial; - QSGTextureMaterial m_material; - QSGGeometry m_geometry; - QSGPlainTexture *m_texture; - QGeoMap *m_map; - QSize m_size; - bool m_initialized; - bool m_dirtyFBO; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp index 9e2e4ebb..59590309 100644 --- a/src/imports/location/qdeclarativegeomap.cpp +++ b/src/imports/location/qdeclarativegeomap.cpp @@ -53,7 +53,6 @@ #include "qgeocameradata_p.h" #include "qgeocameracapabilities_p.h" #include "qgeomapcontroller_p.h" -#include "mapnode_p.h" #include <cmath> #include <QtPositioning/QGeoCoordinate> @@ -68,6 +67,7 @@ #include <QtQml/qqmlinfo.h> #include <QModelIndex> #include <QtQuick/QQuickWindow> +#include <QtQuick/QSGSimpleRectNode> #include <QtGui/QGuiApplication> #include <QCoreApplication> @@ -191,7 +191,6 @@ QDeclarativeGeoMap::QDeclarativeGeoMap(QQuickItem *parent) activeMapType_(0), componentCompleted_(false), mappingManagerInitialized_(false), - window_(0), touchTimer_(-1), map_(0) { @@ -368,16 +367,6 @@ QDeclarativeGeoMapGestureArea *QDeclarativeGeoMap::gesture() /*! \internal */ -void QDeclarativeGeoMap::itemChange(ItemChange change, const ItemChangeData & data) -{ - QLOC_TRACE0; - if (change == ItemSceneChange) - window_ = data.window; -} - -/*! - \internal -*/ void QDeclarativeGeoMap::populateMap() { QObjectList kids = children(); @@ -407,29 +396,27 @@ void QDeclarativeGeoMap::setupMapView(QDeclarativeGeoMapItemView *view) } /*! - \internal -*/ -QSGNode *QDeclarativeGeoMap::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) + * \internal + */ +QSGNode *QDeclarativeGeoMap::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { - Q_UNUSED(data) - if (width() <= 0 || height() <= 0) { + if (!map_) { delete oldNode; return 0; } - MapNode *node = static_cast<MapNode *>(oldNode); - - if (!node) { - node = new MapNode(map_); - } - - if (!mappingManagerInitialized_) - return 0; + QSGSimpleRectNode *root = static_cast<QSGSimpleRectNode *>(oldNode); + if (!root) + root = new QSGSimpleRectNode(boundingRect(), QColor::fromRgbF(0.9, 0.9, 0.9)); + else + root->setRect(boundingRect()); - node->setSize(QSize(width(), height())); - node->update(); + QSGNode *content = root->childCount() ? root->firstChild() : 0; + content = map_->updateSceneGraph(content, window()); + if (content && root->childCount() == 0) + root->appendChildNode(content); - return node; + return root; } diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h index fb00e1b7..01fec865 100644 --- a/src/imports/location/qdeclarativegeomap_p.h +++ b/src/imports/location/qdeclarativegeomap_p.h @@ -75,7 +75,6 @@ QT_BEGIN_NAMESPACE -class QGLPainter; class QGLSceneNode; class QGeoTileCache; class Tile; @@ -120,8 +119,6 @@ public: virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); - void itemChange(ItemChange change, const ItemChangeData & data); - void setPlugin(QDeclarativeGeoServiceProvider *plugin); QDeclarativeGeoServiceProvider *plugin() const; @@ -210,11 +207,6 @@ private: QDeclarativeGeoMapGestureArea *gestureArea_; - void paintGL(QGLPainter *painter); - void earlyDraw(QGLPainter *painter); - void restoreDefaults(QGLPainter *painter); - - QQuickWindow *window_; int touchTimer_; QGeoMap *map_; diff --git a/src/location/maps/maps.pri b/src/location/maps/maps.pri index 3a43c5ea..4ad7f0d6 100644 --- a/src/location/maps/maps.pri +++ b/src/location/maps/maps.pri @@ -1,7 +1,7 @@ INCLUDEPATH += maps -QT_PRIVATE += gui 3d +QT += gui quick PUBLIC_HEADERS += \ maps/qgeocodereply.h \ diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp index f937c29b..a521f0a2 100644 --- a/src/location/maps/qgeomap.cpp +++ b/src/location/maps/qgeomap.cpp @@ -62,14 +62,7 @@ #include <qnumeric.h> -#include <Qt3D/qglscenenode.h> -#include <Qt3D/qgeometrydata.h> -#include <Qt3D/qglbuilder.h> -#include <Qt3D/qglpainter.h> -#include <Qt3D/qgeometrydata.h> -#include <Qt3D/qglbuilder.h> -#include <Qt3D/qglcamera.h> -#include <Qt3D/qglsubsurface.h> +#include <QtQuick/QSGNode> #include <cmath> @@ -95,14 +88,9 @@ QGeoMapController *QGeoMap::mapController() return mapData_->mapController(); } -QGLCamera *QGeoMap::glCamera() const +QSGNode *QGeoMap::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) { - return mapData_->glCamera(); -} - -void QGeoMap::paintGL(QGLPainter *painter) -{ - mapData_->paintGL(painter); + return mapData_->updateSceneGraph(oldNode, window); } void QGeoMap::resize(int width, int height) diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h index e956d886..4ade6931 100644 --- a/src/location/maps/qgeomap_p.h +++ b/src/location/maps/qgeomap_p.h @@ -64,14 +64,14 @@ class QGeoCoordinate; class QGeoMappingManager; -class MapItem; class QGeoMapController; class QGeoCameraCapabilities; -class QGLCamera; -class QGLPainter; class QGeoMapData; +class QSGNode; +class QQuickWindow; + class QPointF; class Q_LOCATION_EXPORT QGeoMap : public QObject @@ -87,8 +87,7 @@ public: QGeoMapController *mapController(); - QGLCamera *glCamera() const; - void paintGL(QGLPainter *painter); + QSGNode *updateSceneGraph(QSGNode *oldNode, QQuickWindow *window); void resize(int width, int height); int width() const; diff --git a/src/location/maps/qgeomapdata.cpp b/src/location/maps/qgeomapdata.cpp index e6d7b68f..ce5579ba 100644 --- a/src/location/maps/qgeomapdata.cpp +++ b/src/location/maps/qgeomapdata.cpp @@ -63,15 +63,6 @@ #include <qnumeric.h> -#include <Qt3D/qglscenenode.h> -#include <Qt3D/qgeometrydata.h> -#include <Qt3D/qglbuilder.h> -#include <Qt3D/qglpainter.h> -#include <Qt3D/qgeometrydata.h> -#include <Qt3D/qglbuilder.h> -#include <Qt3D/qglcamera.h> -#include <Qt3D/qglsubsurface.h> - #include <cmath> QT_BEGIN_NAMESPACE @@ -91,12 +82,6 @@ QGeoMapController *QGeoMapData::mapController() return d->mapController(); } -QGLCamera *QGeoMapData::glCamera() const -{ - Q_D(const QGeoMapData); - return d->glCamera(); -} - void QGeoMapData::resize(int width, int height) { Q_D(QGeoMapData); @@ -178,7 +163,6 @@ QGeoMapDataPrivate::QGeoMapDataPrivate(QGeoMappingManagerEngine *engine, QGeoMap : width_(0), height_(0), aspectRatio_(0.0), - camera_(new QGLCamera()), map_(parent), engine_(engine), controller_(0), @@ -191,7 +175,6 @@ QGeoMapDataPrivate::~QGeoMapDataPrivate() { // controller_ is a child of map_, don't need to delete it here - delete camera_; // TODO map items are not deallocated! // However: how to ensure this is done in rendering thread? } @@ -213,11 +196,6 @@ QGeoMapController *QGeoMapDataPrivate::mapController() return controller_; } -QGLCamera *QGeoMapDataPrivate::glCamera() const -{ - return camera_; -} - void QGeoMapDataPrivate::setCameraData(const QGeoCameraData &cameraData) { QGeoCameraData oldCameraData = cameraData_; diff --git a/src/location/maps/qgeomapdata_p.h b/src/location/maps/qgeomapdata_p.h index 35ed32c2..59140b73 100644 --- a/src/location/maps/qgeomapdata_p.h +++ b/src/location/maps/qgeomapdata_p.h @@ -68,8 +68,9 @@ class MapItem; class QGeoMapController; class QGeoCameraCapabilities; -class QGLCamera; -class QGLPainter; +class QSGNode; +class QQuickWindow; + class QGeoMap; class QPointF; @@ -83,8 +84,7 @@ public: QGeoMapController *mapController(); - QGLCamera *glCamera() const; - virtual void paintGL(QGLPainter *painter) = 0; + virtual QSGNode *updateSceneGraph(QSGNode *, QQuickWindow *window) = 0; void resize(int width, int height); int width() const; diff --git a/src/location/maps/qgeomapdata_p_p.h b/src/location/maps/qgeomapdata_p_p.h index 5e81d457..d11deee1 100644 --- a/src/location/maps/qgeomapdata_p_p.h +++ b/src/location/maps/qgeomapdata_p_p.h @@ -74,9 +74,6 @@ class QGeoMappingManagerEngine; class QGeoMapData; class QGeoMapController; -class QGLCamera; -class QGLPainter; - class QGeoMapDataPrivate { public: @@ -87,8 +84,6 @@ public: QGeoMapController *mapController(); - QGLCamera *glCamera() const; - void setCameraData(const QGeoCameraData &cameraData); QGeoCameraData cameraData() const; @@ -106,7 +101,6 @@ private: int height_; double aspectRatio_; - QGLCamera *camera_; QGeoMapData *map_; QGeoMappingManagerEngine *engine_; QString pluginString_; diff --git a/src/location/maps/qgeomapscene.cpp b/src/location/maps/qgeomapscene.cpp index cb24861f..3d256734 100644 --- a/src/location/maps/qgeomapscene.cpp +++ b/src/location/maps/qgeomapscene.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtLocation module of the Qt Toolkit. @@ -49,15 +50,8 @@ #include <QtPositioning/private/qdoublevector2d_p.h> #include <QtPositioning/private/qdoublevector3d_p.h> -#include <Qt3D/qglscenenode.h> -#include <Qt3D/qglbuilder.h> -#include <Qt3D/qglmaterial.h> -#include <Qt3D/qgltexture2d.h> -#include <Qt3D/qgeometrydata.h> -#include <Qt3D/qglcamera.h> -#include <Qt3D/qglpainter.h> -#include <Qt3D/QGLLightParameters> - +#include <QtQuick/QSGSimpleTextureNode> +#include <QtQuick/QQuickWindow> #include <QHash> @@ -78,9 +72,10 @@ public: QGeoCameraData cameraData_; QSet<QGeoTileSpec> visibleTiles_; - QGLCamera *camera_; - QGLSceneNode *sceneNode_; - QGLLightParameters* light_; + QDoubleVector3D cameraUp_; + QDoubleVector3D cameraEye_; + QDoubleVector3D cameraCenter_; + QMatrix4x4 projectionMatrix_; // scales up the tile geometry and the camera altitude, resulting in no visible effect // other than to control the accuracy of the render by keeping the values in a sensible range @@ -94,9 +89,7 @@ public: // it is 1<<zoomLevel int sideLength_; - QHash<QGeoTileSpec, QGLSceneNode *> nodes_; QHash<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > textures_; - QList<QSharedPointer<QGeoTileTexture> > newUploads_; // tilesToGrid transform int minTileX_; // the minimum tile index, i.e. 0 to sideLength which is 1<< zoomLevel @@ -130,14 +123,9 @@ public: void setVisibleTiles(const QSet<QGeoTileSpec> &tiles); void removeTiles(const QSet<QGeoTileSpec> &oldTiles); - void updateTiles(const QSet<QGeoTileSpec> &tiles); - QGeometryData buildGeometry(const QGeoTileSpec &spec); - QGLSceneNode *buildSceneNodeFromGeometry(const QGeometryData &geom); + bool buildGeometry(const QGeoTileSpec &spec, QSGGeometry::TexturedPoint2D *vertices); void setTileBounds(const QSet<QGeoTileSpec> &tiles); void setupCamera(); - void setScalingOnTextures(); - - void paintGL(QGLPainter *painter); private: QGeoMapScene *q_ptr; @@ -177,13 +165,7 @@ void QGeoMapScene::setCameraData(const QGeoCameraData &cameraData) d->cameraData_ = cameraData; d->intZoomLevel_ = static_cast<int>(std::floor(d->cameraData_.zoomLevel())); float delta = cameraData.zoomLevel() - d->intZoomLevel_; - if (qAbs(delta) < 0.05) { - d->linearScaling_ = false; - d->setScalingOnTextures(); - } else { - d->linearScaling_ = true; - d->setScalingOnTextures(); - } + d->linearScaling_ = qAbs(delta) > 0.05; d->sideLength_ = 1 << d->intZoomLevel_; } @@ -211,30 +193,12 @@ QDoubleVector2D QGeoMapScene::mercatorToScreenPosition(const QDoubleVector2D &me return d->mercatorToScreenPosition(mercator); } -QGLCamera *QGeoMapScene::camera() const -{ - Q_D(const QGeoMapScene); - return d->camera_; -} - -QGLSceneNode *QGeoMapScene::sceneNode() const -{ - Q_D(const QGeoMapScene); - return d->sceneNode_; -} - bool QGeoMapScene::verticalLock() const { Q_D(const QGeoMapScene); return d->verticalLock_; } -void QGeoMapScene::paintGL(QGLPainter *painter) -{ - Q_D(QGeoMapScene); - d->paintGL(painter); -} - QSet<QGeoTileSpec> QGeoMapScene::texturedTiles() { Q_D(QGeoMapScene); @@ -247,9 +211,6 @@ QSet<QGeoTileSpec> QGeoMapScene::texturedTiles() QGeoMapScenePrivate::QGeoMapScenePrivate(QGeoMapScene *scene) : tileSize_(0), - camera_(new QGLCamera()), - sceneNode_(new QGLSceneNode()), - light_(new QGLLightParameters()), scaleFactor_(10.0), intZoomLevel_(0), sideLength_(0), @@ -269,14 +230,11 @@ QGeoMapScenePrivate::QGeoMapScenePrivate(QGeoMapScene *scene) screenHeight_(0.0), useVerticalLock_(false), verticalLock_(false), - linearScaling_(true), + linearScaling_(false), q_ptr(scene) {} QGeoMapScenePrivate::~QGeoMapScenePrivate() { - delete sceneNode_; - delete camera_; - delete light_; } QDoubleVector2D QGeoMapScenePrivate::screenPositionToMercator(const QDoubleVector2D &pos) const @@ -340,7 +298,7 @@ QDoubleVector2D QGeoMapScenePrivate::mercatorToScreenPosition(const QDoubleVecto return QDoubleVector2D(x + screenOffsetX_, y + screenOffsetY_); } -QGeometryData QGeoMapScenePrivate::buildGeometry(const QGeoTileSpec &spec) +bool QGeoMapScenePrivate::buildGeometry(const QGeoTileSpec &spec, QSGGeometry::TexturedPoint2D *vertices) { int x = spec.x(); @@ -352,7 +310,7 @@ QGeometryData QGeoMapScenePrivate::buildGeometry(const QGeoTileSpec &spec) || (spec.y() < minTileY_) || (maxTileY_ < spec.y()) || (spec.zoom() != tileZ_)) { - return 0; + return false; } double edge = scaleFactor_ * tileSize_; @@ -368,102 +326,21 @@ QGeometryData QGeoMapScenePrivate::buildGeometry(const QGeoTileSpec &spec) y1 *= edge; y2 *= edge; - QGeometryData g; - - QDoubleVector3D n = QDoubleVector3D(0, 0, 1); - //Texture coordinate order for veritcal flip of texture - g.appendVertex(QVector3D(x1, y1, 0.0)); - g.appendNormal(n); - g.appendTexCoord(QVector2D(0.0, 0.0)); - - g.appendVertex(QVector3D(x1, y2, 0.0)); - g.appendNormal(n); - g.appendTexCoord(QVector2D(0.0, 1.0)); - - g.appendVertex(QVector3D(x2, y2, 0.0)); - g.appendNormal(n); - g.appendTexCoord(QVector2D(1.0, 1.0)); + vertices[0].set(x1, y1, 0, 0); + vertices[1].set(x1, y2, 0, 1); + vertices[2].set(x2, y1, 1, 0); + vertices[3].set(x2, y2, 1, 1); - g.appendVertex(QVector3D(x2, y1, 0.0)); - g.appendNormal(n); - g.appendTexCoord(QVector2D(1.0, 0.0)); - - return g; -} - -QGLSceneNode *QGeoMapScenePrivate::buildSceneNodeFromGeometry(const QGeometryData &geom) -{ - QGLBuilder builder; - builder.addQuads(geom); - return builder.finalizedSceneNode(); -} - - -void QGeoMapScenePrivate::setScalingOnTextures() -{ - if (!linearScaling_) { - foreach (const QSharedPointer<QGeoTileTexture> &tex, textures_.values()) { - tex->texture->setBindOptions(tex->texture->bindOptions() & - (~QGLTexture2D::LinearFilteringBindOption)); - } - } else { - foreach (const QSharedPointer<QGeoTileTexture> &tex, textures_.values()) { - tex->texture->setBindOptions(tex->texture->bindOptions() | - (QGLTexture2D::LinearFilteringBindOption)); - } - } + return true; } void QGeoMapScenePrivate::addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture) { if (!visibleTiles_.contains(spec)) // Don't add the geometry if it isn't visible return; - if (linearScaling_) { - texture->texture->setBindOptions(texture->texture->bindOptions() | - (QGLTexture2D::LinearFilteringBindOption)); - } else { - texture->texture->setBindOptions(texture->texture->bindOptions() & - (~QGLTexture2D::LinearFilteringBindOption)); - } - //Avoid expensive conversion of ARGB32_Premultiplied to ARGB32 - if (texture->texture->image().format() == QImage::Format_ARGB32_Premultiplied) { - texture->texture->setBindOptions(texture->texture->bindOptions() | - (QGLTexture2D::PremultipliedAlphaBindOption)); - } - - //There are tiles for different zoom levels, no need for mipmaps - texture->texture->setBindOptions(texture->texture->bindOptions() & (~QGLTexture2D::MipmapBindOption)); - - //We flip the texture coordinates instead of the texture - texture->texture->setBindOptions(texture->texture->bindOptions() & (~QGLTexture2D::InvertedYBindOption)); - - QGLSceneNode *node = nodes_.value(spec, 0); - if (!node) { - QGeometryData geom = buildGeometry(spec); - node = buildSceneNodeFromGeometry(geom); - if (!node) - return; - - QGLMaterial *mat = new QGLMaterial(node); - mat->setTexture(texture->texture); - node->setEffect(QGL::LitDecalTexture2D); - node->setMaterial(mat); - - sceneNode_->addNode(node); - nodes_.insert(spec, node); - textures_.insert(spec, texture); - newUploads_ << texture; - - } else { - // TODO handle texture updates when we make node removal more efficient - if (textures_[spec].data() != texture.data()) { - textures_.insert(spec, texture); - node->material()->setTexture(texture->texture); - newUploads_ << texture; - } - } + textures_.insert(spec, texture); } // return true if new tiles introduced in [tiles] @@ -485,51 +362,11 @@ void QGeoMapScenePrivate::setVisibleTiles(const QSet<QGeoTileSpec> &tiles) if (!toRemove.isEmpty()) removeTiles(toRemove); - // only need to update tiles when the bounds have changed, - if (visibleTiles_ != tiles && !toUpdate.isEmpty()) - updateTiles(toUpdate); - visibleTiles_ = tiles; if (newTilesIntroduced) emit q->newTilesVisible(visibleTiles_); } -void QGeoMapScenePrivate::updateTiles(const QSet<QGeoTileSpec> &tiles) -{ - typedef QSet<QGeoTileSpec>::const_iterator iter; - iter i = tiles.constBegin(); - iter end = tiles.constEnd(); - for (; i != end; ++i) { - QGeoTileSpec tile = *i; - QGLSceneNode *node = nodes_.value(tile, 0); - - if (node) { - QGeometryData geom = buildGeometry(tile); - // if the new geometry (after wrapping) is the same as the old one, - // it can be reused - if ( node->children().size() > 0) { - if (node->children().front()->geometry() == geom) - continue; - } - - sceneNode_->removeNode(node); - QGLSceneNode *newNode = buildSceneNodeFromGeometry(geom); - if (newNode) { - QGLMaterial *mat = new QGLMaterial(newNode); - mat->setTexture(textures_[tile]->texture); - newNode->setEffect(QGL::LitDecalTexture2D); - newNode->setMaterial(mat); - sceneNode_->addNode(newNode); - nodes_.insert(tile, newNode); - } else { - nodes_.remove(tile); - textures_.remove(tile); - } - delete node; - } - } -} - void QGeoMapScenePrivate::removeTiles(const QSet<QGeoTileSpec> &oldTiles) { typedef QSet<QGeoTileSpec>::const_iterator iter; @@ -538,14 +375,7 @@ void QGeoMapScenePrivate::removeTiles(const QSet<QGeoTileSpec> &oldTiles) for (; i != end; ++i) { QGeoTileSpec tile = *i; - QGLSceneNode *node = nodes_.value(tile, 0); - if (node) { - // TODO protect with mutex? - sceneNode_->removeNode(node); - nodes_.remove(tile); - textures_.remove(tile); - delete node; - } + textures_.remove(tile); } } @@ -629,7 +459,6 @@ void QGeoMapScenePrivate::setTileBounds(const QSet<QGeoTileSpec> &tiles) void QGeoMapScenePrivate::setupCamera() { - double f = 1.0 * qMin(screenSize_.width(), screenSize_.height()); // fraction of zoom level @@ -734,81 +563,204 @@ void QGeoMapScenePrivate::setupCamera() double nearPlane = 1.0; double farPlane = 4.0 * edge; - // TODO protect with mutex? - // set glcamera parameters - camera_->setCenter(center); - camera_->setEye(eye); - camera_->setUpVector(up); - camera_->setNearPlane(nearPlane); - camera_->setFarPlane(farPlane); + cameraUp_ = up; + cameraCenter_ = center; + cameraEye_ = eye; + + float halfWidth = 1; + float halfHeight = 1; + if (aspectRatio > 1.0) { + halfWidth *= aspectRatio; + } else if (aspectRatio > 0.0f && aspectRatio < 1.0f) { + halfHeight /= aspectRatio; + } + projectionMatrix_.setToIdentity(); + projectionMatrix_.frustum(-halfWidth, halfWidth, -halfHeight, halfHeight, nearPlane, farPlane); } -void QGeoMapScenePrivate::paintGL(QGLPainter *painter) +class QGeoMapTileContainerNode : public QSGTransformNode { - // TODO protect with mutex? - - // TODO add a shortcut here for when we don't need to repeat and clip the map - // NOTE- this is important as the repeat code below removes a lot of accuracy - // by converting to float and adding/removing large numbers when at high zoom - - // do any pending upload/releases - while (!newUploads_.isEmpty()) { - if (!newUploads_.front()->textureBound) { - newUploads_.front()->texture->bind(); - newUploads_.front()->texture->clearImage(); - newUploads_.front()->textureBound = true; - } - newUploads_.pop_front(); +public: + void addChild(const QGeoTileSpec &spec, QSGSimpleTextureNode *node) + { + tiles.insert(spec, node); + appendChildNode(node); } + QHash<QGeoTileSpec, QSGSimpleTextureNode *> tiles; +}; - glEnable(GL_SCISSOR_TEST); +class QGeoMapRootNode : public QSGClipNode +{ +public: + QGeoMapRootNode() + : isTextureLinear(false) + , geometry(QSGGeometry::defaultAttributes_Point2D(), 4) + , root(new QSGTransformNode()) + , tiles(new QGeoMapTileContainerNode()) + , wrapLeft(new QGeoMapTileContainerNode()) + , wrapRight(new QGeoMapTileContainerNode()) + { + setIsRectangular(true); + setGeometry(&geometry); + root->appendChildNode(tiles); + root->appendChildNode(wrapLeft); + root->appendChildNode(wrapRight); + appendChildNode(root); + } - painter->setScissor(QRect(screenOffsetX_, screenOffsetY_, screenWidth_, screenHeight_)); + ~QGeoMapRootNode() + { + qDeleteAll(textures.values()); + } - painter->setCamera(camera_); + void setClipRect(const QRect &rect) + { + if (rect != clipRect) { + QSGGeometry::updateRectGeometry(&geometry, rect); + QSGClipNode::setClipRect(rect); + clipRect = rect; + markDirty(DirtyGeometry); + } + } - painter->setMainLight(light_); + void updateTiles(QGeoMapTileContainerNode *root, QGeoMapScenePrivate *d, double camAdjust); - sceneNode_->draw(painter); + bool isTextureLinear; - QGLCamera *camera = camera_; + QSGGeometry geometry; + QRect clipRect; - bool old = camera->blockSignals(true); + QSGTransformNode *root; - glDisable(GL_DEPTH_TEST); + QGeoMapTileContainerNode *tiles; // The majority of the tiles + QGeoMapTileContainerNode *wrapLeft; // When zoomed out, the tiles that wrap around on the left. + QGeoMapTileContainerNode *wrapRight; // When zoomed out, the tiles that wrap around on the right - double sideLength = scaleFactor_ * tileSize_ * sideLength_; + QHash<QGeoTileSpec, QSGTexture *> textures; +}; - QDoubleVector3D c = QDoubleVector3D(camera->center()); - c.setX(c.x() + sideLength); - camera->setCenter(c); +static bool qgeomapscene_isTileInViewport(const QSGGeometry::TexturedPoint2D *tp, const QMatrix4x4 &matrix) { + QPolygonF polygon; polygon.reserve(4); + for (int i=0; i<4; ++i) + polygon << matrix * QPointF(tp[i].x, tp[i].y); + return QRectF(-1, -1, 2, 2).intersects(polygon.boundingRect()); +} - QDoubleVector3D e = QDoubleVector3D(camera->eye()); - e.setX(e.x() + sideLength); - camera->setEye(e); +void QGeoMapRootNode::updateTiles(QGeoMapTileContainerNode *root, + QGeoMapScenePrivate *d, + double camAdjust) +{ + // Set up the matrix... + QDoubleVector3D eye = d->cameraEye_; + eye.setX(eye.x() + camAdjust); + QDoubleVector3D center = d->cameraCenter_; + center.setX(center.x() + camAdjust); + QMatrix4x4 cameraMatrix; + cameraMatrix.lookAt(eye, center, d->cameraUp_); + root->setMatrix(d->projectionMatrix_ * cameraMatrix); + + QSet<QGeoTileSpec> tilesInSG = QSet<QGeoTileSpec>::fromList(root->tiles.keys()); + QSet<QGeoTileSpec> toRemove = tilesInSG - d->visibleTiles_; + QSet<QGeoTileSpec> toAdd = d->visibleTiles_ - tilesInSG; + + foreach (const QGeoTileSpec &s, toRemove) + delete root->tiles.take(s); + + for (QHash<QGeoTileSpec, QSGSimpleTextureNode *>::iterator it = root->tiles.begin(); + it != root->tiles.end(); ) { + QSGGeometry visualGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); + QSGGeometry::TexturedPoint2D *v = visualGeometry.vertexDataAsTexturedPoint2D(); + bool ok = d->buildGeometry(it.key(), v) && qgeomapscene_isTileInViewport(v, root->matrix()); + QSGSimpleTextureNode *node = it.value(); + QSGNode::DirtyState dirtyBits = 0; + + // Check and handle changes to vertex data. + if (ok && memcmp(node->geometry()->vertexData(), v, 4 * sizeof(QSGGeometry::TexturedPoint2D)) != 0) { + if (v[0].x == v[3].x || v[0].y == v[3].y) { // top-left == bottom-right => invalid => remove + ok = false; + } else { + memcpy(node->geometry()->vertexData(), v, 4 * sizeof(QSGGeometry::TexturedPoint2D)); + dirtyBits |= QSGNode::DirtyGeometry; + } + } - painter->setCamera(camera); - sceneNode_->draw(painter); + if (!ok) { + it = root->tiles.erase(it); + delete node; + } else { + if (isTextureLinear != d->linearScaling_) { + node->setFiltering(d->linearScaling_ ? QSGTexture::Linear : QSGTexture::Nearest); + dirtyBits |= QSGNode::DirtyMaterial; + } + if (dirtyBits != 0) + node->markDirty(dirtyBits); + it++; + } + } - c.setX(c.x() - 2 * sideLength); - camera->setCenter(c); - e.setX(e.x() - 2 * sideLength); - camera->setEye(e); + foreach (const QGeoTileSpec &s, toAdd) { + QGeoTileTexture *tileTexture = d->textures_.value(s).data(); + if (!tileTexture || tileTexture->image.isNull()) + continue; + QSGSimpleTextureNode *tileNode = new QSGSimpleTextureNode(); + // note: setTexture will update coordinates so do it here, before we buildGeometry + tileNode->setTexture(textures.value(s)); + Q_ASSERT(tileNode->geometry()); + Q_ASSERT(tileNode->geometry()->attributes() == QSGGeometry::defaultAttributes_TexturedPoint2D().attributes); + Q_ASSERT(tileNode->geometry()->vertexCount() == 4); + if (d->buildGeometry(s, tileNode->geometry()->vertexDataAsTexturedPoint2D()) + && qgeomapscene_isTileInViewport(tileNode->geometry()->vertexDataAsTexturedPoint2D(), root->matrix())) { + tileNode->setFiltering(d->linearScaling_ ? QSGTexture::Linear : QSGTexture::Nearest); + root->addChild(s, tileNode); + } else { + delete tileNode; + } + } +} - painter->setCamera(camera); - sceneNode_->draw(painter); +QSGNode *QGeoMapScene::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) +{ + Q_D(QGeoMapScene); + float w = d->screenSize_.width(); + float h = d->screenSize_.height(); + if (w <= 0 || h <= 0) { + delete oldNode; + return 0; + } - c.setX(c.x() + sideLength); - camera->setCenter(c); - e.setX(e.x() + sideLength); - camera->setEye(e); + QGeoMapRootNode *mapRoot = static_cast<QGeoMapRootNode *>(oldNode); + if (!mapRoot) + mapRoot = new QGeoMapRootNode(); + + mapRoot->setClipRect(QRect(d->screenOffsetX_, d->screenOffsetY_, d->screenWidth_, d->screenHeight_)); + + QMatrix4x4 itemSpaceMatrix; + itemSpaceMatrix.scale(w / 2, h / 2); + itemSpaceMatrix.translate(1, 1); + itemSpaceMatrix.scale(1, -1); + mapRoot->root->setMatrix(itemSpaceMatrix); + + QSet<QGeoTileSpec> textures = QSet<QGeoTileSpec>::fromList(mapRoot->textures.keys()); + QSet<QGeoTileSpec> toRemove = textures - d->visibleTiles_; + QSet<QGeoTileSpec> toAdd = d->visibleTiles_ - textures; + + foreach (const QGeoTileSpec &spec, toRemove) + mapRoot->textures.take(spec)->deleteLater(); + foreach (const QGeoTileSpec &spec, toAdd) { + QGeoTileTexture *tileTexture = d->textures_.value(spec).data(); + if (!tileTexture || tileTexture->image.isNull()) + continue; + mapRoot->textures.insert(spec, window->createTextureFromImage(tileTexture->image)); + } - painter->setCamera(camera); - sceneNode_->draw(painter); + double sideLength = d->scaleFactor_ * d->tileSize_ * d->sideLength_; + mapRoot->updateTiles(mapRoot->tiles, d, 0); + mapRoot->updateTiles(mapRoot->wrapLeft, d, +sideLength); + mapRoot->updateTiles(mapRoot->wrapRight, d, -sideLength); - glEnable(GL_DEPTH_TEST); + mapRoot->isTextureLinear = d->linearScaling_; - camera->blockSignals(old); + return mapRoot; } QT_END_NAMESPACE diff --git a/src/location/maps/qgeomapscene_p.h b/src/location/maps/qgeomapscene_p.h index 203eeb8a..bfef71ee 100644 --- a/src/location/maps/qgeomapscene_p.h +++ b/src/location/maps/qgeomapscene_p.h @@ -67,12 +67,11 @@ class QGeoTileSpec; class QDoubleVector2D; -class QGLSceneNode; -class QGLCamera; -class QGLPainter; -class QGLTexture2D; class QGeoTileTexture; +class QSGNode; +class QQuickWindow; + class QPointF; class QGeoMapScenePrivate; @@ -97,9 +96,7 @@ public: QDoubleVector2D screenPositionToMercator(const QDoubleVector2D &pos) const; QDoubleVector2D mercatorToScreenPosition(const QDoubleVector2D &mercator) const; - QGLCamera *camera() const; - QGLSceneNode *sceneNode() const; - void paintGL(QGLPainter *painter); + QSGNode *updateSceneGraph(QSGNode *oldNode, QQuickWindow *window); bool verticalLock() const; QSet<QGeoTileSpec> texturedTiles(); diff --git a/src/location/maps/qgeotilecache.cpp b/src/location/maps/qgeotilecache.cpp index 3bcb2275..a51ce815 100644 --- a/src/location/maps/qgeotilecache.cpp +++ b/src/location/maps/qgeotilecache.cpp @@ -50,14 +50,10 @@ #include <QPixmap> #include <QDebug> -#include <Qt3D/qgltexture2d.h> - Q_DECLARE_METATYPE(QList<QGeoTileSpec>) Q_DECLARE_METATYPE(QSet<QGeoTileSpec>) QT_BEGIN_NAMESPACE -QMutex QGeoTileCache::cleanupMutex_; -QList<QGLTexture2D*> QGeoTileCache::cleanupList_; class QGeoCachedTileMemory { @@ -75,8 +71,7 @@ public: }; QGeoTileTexture::QGeoTileTexture() - : texture(0), - textureBound(false) {} + : textureBound(false) {} void QCache3QTileEvictionPolicy::aboutToBeRemoved(const QGeoTileSpec &key, QSharedPointer<QGeoCachedTileDisk> obj) { @@ -100,7 +95,6 @@ QGeoCachedTileDisk::~QGeoCachedTileDisk() QGeoTileTexture::~QGeoTileTexture() { - QGeoTileCache::evictFromTextureCache(this); } QGeoTileCache::QGeoTileCache(const QString &directory, QObject *parent) @@ -274,25 +268,6 @@ int QGeoTileCache::textureUsage() const return textureCache_.totalCost(); } -void QGeoTileCache::GLContextAvailable() -{ - QMutexLocker ml(&cleanupMutex_); - - /* Throttle the cleanup to 10 items/frame to avoid blocking the render - * for too long. Normally only 6-20 tiles are on screen at a time so - * eviction rates shouldn't be much higher than this. */ - int todo = qMin(cleanupList_.size(), 10); - for (int i = 0; i < todo; ++i) { - QGLTexture2D *texture = cleanupList_.front(); - if (texture) { - texture->release(); - texture->cleanupResources(); - delete texture; - } - cleanupList_.pop_front(); - } -} - QSharedPointer<QGeoTileTexture> QGeoTileCache::get(const QGeoTileSpec &spec) { QSharedPointer<QGeoTileTexture> tt = textureCache_.object(spec); @@ -372,12 +347,6 @@ void QGeoTileCache::evictFromMemoryCache(QGeoCachedTileMemory * /* tm */) { } -void QGeoTileCache::evictFromTextureCache(QGeoTileTexture *tt) -{ - QMutexLocker ml(&cleanupMutex_); - cleanupList_ << tt->texture; -} - QSharedPointer<QGeoCachedTileDisk> QGeoTileCache::addToDiskCache(const QGeoTileSpec &spec, const QString &filename) { QSharedPointer<QGeoCachedTileDisk> td(new QGeoCachedTileDisk); @@ -409,15 +378,9 @@ QSharedPointer<QGeoTileTexture> QGeoTileCache::addToTextureCache(const QGeoTileS { QSharedPointer<QGeoTileTexture> tt(new QGeoTileTexture); tt->spec = spec; - tt->texture = new QGLTexture2D(); - tt->texture->setPixmap(pixmap); - tt->texture->setHorizontalWrap(QGL::ClampToEdge); - tt->texture->setVerticalWrap(QGL::ClampToEdge); - - /* Do not bind/cleanImage on the texture here -- it needs to be done - * in the render thread (by qgeomapscene) */ + tt->image = pixmap.toImage(); - int textureCost = pixmap.width() * pixmap.height() * pixmap.depth() / 8; + int textureCost = tt->image.width() * tt->image.height() * tt->image.depth() / 8; textureCache_.insert(spec, tt, textureCost); return tt; diff --git a/src/location/maps/qgeotilecache_p.h b/src/location/maps/qgeotilecache_p.h index eee09de3..b9d98e98 100644 --- a/src/location/maps/qgeotilecache_p.h +++ b/src/location/maps/qgeotilecache_p.h @@ -64,6 +64,8 @@ #include "qgeotilespec_p.h" #include "qgeotiledmappingmanagerengine_p.h" +#include <QImage> + QT_BEGIN_NAMESPACE class QGeoMappingManager; @@ -71,7 +73,6 @@ class QGeoMappingManager; class QGeoTile; class QGeoCachedTileMemory; class QGeoTileCache; -class QGLTexture2D; class QPixmap; class QThread; @@ -98,7 +99,7 @@ public: ~QGeoTileTexture(); QGeoTileSpec spec; - QGLTexture2D *texture; + QImage image; bool textureBound; }; @@ -132,15 +133,12 @@ public: int minTextureUsage() const; int textureUsage() const; - void GLContextAvailable(); - QSharedPointer<QGeoTileTexture> get(const QGeoTileSpec &spec); QString directory() const; // can be called without a specific tileCache pointer static void evictFromDiskCache(QGeoCachedTileDisk *td); static void evictFromMemoryCache(QGeoCachedTileMemory *tm); - static void evictFromTextureCache(QGeoTileTexture *tt); void insert(const QGeoTileSpec &spec, const QByteArray &bytes, @@ -168,9 +166,6 @@ private: int minTextureUsage_; int extraTextureUsage_; - - static QMutex cleanupMutex_; - static QList<QGLTexture2D*> cleanupList_; }; QT_END_NAMESPACE diff --git a/src/location/maps/qgeotiledmapdata.cpp b/src/location/maps/qgeotiledmapdata.cpp index 204414f8..f9a8adc6 100644 --- a/src/location/maps/qgeotiledmapdata.cpp +++ b/src/location/maps/qgeotiledmapdata.cpp @@ -55,15 +55,6 @@ #include <qnumeric.h> -#include <Qt3D/qglscenenode.h> -#include <Qt3D/qgeometrydata.h> -#include <Qt3D/qglbuilder.h> -#include <Qt3D/qglpainter.h> -#include <Qt3D/qgeometrydata.h> -#include <Qt3D/qglbuilder.h> -#include <Qt3D/qglcamera.h> -#include <Qt3D/qglsubsurface.h> - #include <QtPositioning/private/qgeoprojection_p.h> #include <QtPositioning/private/qdoublevector2d_p.h> @@ -109,10 +100,10 @@ QGeoTileCache *QGeoTiledMapData::tileCache() return d->tileCache(); } -void QGeoTiledMapData::paintGL(QGLPainter *painter) +QSGNode *QGeoTiledMapData::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) { Q_D(QGeoTiledMapData); - d->paintGL(painter); + return d->updateSceneGraph(oldNode, window); } void QGeoTiledMapData::mapResized(int width, int height) @@ -330,10 +321,9 @@ QSet<QGeoTileSpec> QGeoTiledMapDataPrivate::visibleTiles() return cameraTiles_->tiles(); } -void QGeoTiledMapDataPrivate::paintGL(QGLPainter *painter) +QSGNode *QGeoTiledMapDataPrivate::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) { - mapScene_->paintGL(painter); - cache_->GLContextAvailable(); + return mapScene_->updateSceneGraph(oldNode, window); } QGeoCoordinate QGeoTiledMapDataPrivate::screenPositionToCoordinate(const QDoubleVector2D &pos) const diff --git a/src/location/maps/qgeotiledmapdata_p.h b/src/location/maps/qgeotiledmapdata_p.h index 5a282a8c..9310fded 100644 --- a/src/location/maps/qgeotiledmapdata_p.h +++ b/src/location/maps/qgeotiledmapdata_p.h @@ -68,9 +68,11 @@ class QGeoTileTexture; class QGeoTileCache; class QGeoTiledMapDataPrivate; class QGeoTiledMappingManagerEngine; -class MapItem; class QGeoTileRequestManager; +class QQuickWindow; +class QSGNode; + class QPointF; class Q_LOCATION_EXPORT QGeoTiledMapData : public QGeoMapData @@ -82,7 +84,7 @@ public: QGeoTileCache *tileCache(); - void paintGL(QGLPainter *painter); + QSGNode *updateSceneGraph(QSGNode *, QQuickWindow *window); void newTileFetched(const QGeoTileSpec &spec); diff --git a/src/location/maps/qgeotiledmapdata_p_p.h b/src/location/maps/qgeotiledmapdata_p_p.h index 446b2872..5f30611b 100644 --- a/src/location/maps/qgeotiledmapdata_p_p.h +++ b/src/location/maps/qgeotiledmapdata_p_p.h @@ -81,9 +81,6 @@ class QGeoTileRequestManager; class QGeoMapScene; class QGeoTiledMapData; class QGeoTiledMappingManagerEngine; -class QGLPainter; - -class QGLSceneNode; class QGeoTiledMapDataPrivate { @@ -93,7 +90,7 @@ public: QGeoTileCache *tileCache(); - void paintGL(QGLPainter *painter); + QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window); void changeCameraData(const QGeoCameraData &oldCameraData); void changeActiveMapType(const QGeoMapType mapType); diff --git a/src/src.pro b/src/src.pro index 72274cdc..c00a4b8a 100644 --- a/src/src.pro +++ b/src/src.pro @@ -9,22 +9,19 @@ positioning_doc_snippets.subdir = positioning/doc/snippets positioning_doc_snippets.depends = positioning SUBDIRS += positioning_doc_snippets -#no point in building QtLocation without Qt3D -qtHaveModule(3d) { +qtHaveModule(quick) { SUBDIRS += 3rdparty location.depends = positioning 3rdparty SUBDIRS += location plugins.depends += location - qtHaveModule(quick):imports.depends += location + imports.depends += location location_doc_snippets.subdir = location/doc/snippets location_doc_snippets.depends = location SUBDIRS += location_doc_snippets -} -qtHaveModule(quick) { imports.depends += positioning SUBDIRS += imports } diff --git a/tests/auto/qgeocameratiles/qgeocameratiles.pro b/tests/auto/qgeocameratiles/qgeocameratiles.pro index 1c53e627..0abfa9bf 100644 --- a/tests/auto/qgeocameratiles/qgeocameratiles.pro +++ b/tests/auto/qgeocameratiles/qgeocameratiles.pro @@ -5,5 +5,5 @@ INCLUDEPATH += ../../../src/location/maps SOURCES += tst_qgeocameratiles.cpp -QT += location positioning-private testlib 3d +QT += location positioning-private testlib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qgeomapscene/qgeomapscene.pro b/tests/auto/qgeomapscene/qgeomapscene.pro index a1bacb05..822f0586 100644 --- a/tests/auto/qgeomapscene/qgeomapscene.pro +++ b/tests/auto/qgeomapscene/qgeomapscene.pro @@ -5,5 +5,5 @@ INCLUDEPATH += ../../../src/location/maps SOURCES += tst_qgeomapscene.cpp -QT += location positioning-private 3d testlib +QT += location positioning-private testlib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qgeomapscene/tst_qgeomapscene.cpp b/tests/auto/qgeomapscene/tst_qgeomapscene.cpp index 4303dd0f..6a69c6d1 100644 --- a/tests/auto/qgeomapscene/tst_qgeomapscene.cpp +++ b/tests/auto/qgeomapscene/tst_qgeomapscene.cpp @@ -50,9 +50,6 @@ #include <QtPositioning/private/qgeoprojection_p.h> #include <QtPositioning/private/qdoublevector2d_p.h> -#include <Qt3D/qglscenenode.h> -#include <Qt3D/qgltexture2d.h> - #include <qtest.h> #include <QList> @@ -397,86 +394,6 @@ class tst_QGeoMapScene : public QObject populateScreenMercatorData(); } - void cameraMovementAndTileUpdate(){ - QGeoCameraData camera; - camera.setZoomLevel(4.0); - camera.setCenter(QGeoProjection::mercatorToCoord(QDoubleVector2D(0.5, 0.5))); - - QGeoMapScene mapGeometry; - mapGeometry.setTileSize(16); - mapGeometry.setScreenSize(QSize(16,16)); - mapGeometry.setCameraData(camera); - - QGeoCameraTiles ct; - ct.setMaximumZoomLevel(8); - ct.setTileSize(16); - ct.setCamera(camera); - ct.setScreenSize(QSize(16,16)); - mapGeometry.setVisibleTiles(ct.tiles()); - - int sideLength = 1 << static_cast<int>(floor(camera.zoomLevel())); - double quaterTile = 1.0 / (sideLength * 4.0); - - // test that there are no scene nodes initially - QGLSceneNode* node = mapGeometry.sceneNode(); - QCOMPARE(node->children().count(), 0); - - // the camera is currently centered on top-left corner of the middle tile - // (so 4 tiles should be visible and added to map geometry) - QSharedPointer<QGeoTileTexture> tt(new QGeoTileTexture); - tt->texture = new QGLTexture2D(); - foreach (QGeoTileSpec spec, ct.tiles()) - mapGeometry.addTile(spec, tt); // add tiles with empty texture - QGLSceneNode* node2 = mapGeometry.sceneNode(); - QCOMPARE(node2->children().count(), ct.tiles().count()); - QCOMPARE(node2->children().count(), 4); - - // move camera slightly in x direction but within the same tile bounds - // and verify that no new tiles are added through addTile - camera.setCenter(QGeoProjection::mercatorToCoord(QDoubleVector2D(0.5 + quaterTile, 0.5))); - mapGeometry.setCameraData(camera); - ct.setCamera(camera); - mapGeometry.setVisibleTiles(ct.tiles()); - foreach (QGeoTileSpec spec, ct.tiles()) - mapGeometry.addTile(spec, tt); - QGLSceneNode* node3 = mapGeometry.sceneNode(); - // test to see that there are still only 4 tiles in the map geometry - QCOMPARE(node3->children().count(), ct.tiles().count()); - QCOMPARE(node3->children().count(), 4); - - // move camera further in x to align with edges of middle tile so that 6 tiles are fetched - camera.setCenter(QGeoProjection::mercatorToCoord(QDoubleVector2D(0.5 + quaterTile*2, 0.5))); - mapGeometry.setCameraData(camera); - ct.setCamera(camera); - mapGeometry.setVisibleTiles(ct.tiles()); - foreach (QGeoTileSpec spec, ct.tiles()) - mapGeometry.addTile(spec, tt); - QGLSceneNode* node4 = mapGeometry.sceneNode(); - QCOMPARE(node4->children().count(), ct.tiles().count()); - QCOMPARE(node4->children().count(), 6); - - // move camera further in x so that the 2 tiles on the left are now removed - camera.setCenter(QGeoProjection::mercatorToCoord(QDoubleVector2D(0.5 + quaterTile*4, 0.5))); - mapGeometry.setCameraData(camera); - ct.setCamera(camera); - mapGeometry.setVisibleTiles(ct.tiles()); - foreach (QGeoTileSpec spec, ct.tiles()) - mapGeometry.addTile(spec, tt); - QGLSceneNode* node5 = mapGeometry.sceneNode(); - QCOMPARE(node5->children().count(), ct.tiles().count()); - QCOMPARE(node5->children().count(), 4); - - // test adding tiles with wrapping and clipping - camera.setCenter(QGeoProjection::mercatorToCoord(QDoubleVector2D(0.0, 0.0))); - mapGeometry.setCameraData(camera); - ct.setCamera(camera); - mapGeometry.setVisibleTiles(ct.tiles()); - foreach (QGeoTileSpec spec, ct.tiles()) - mapGeometry.addTile(spec, tt); - QGLSceneNode* node6 = mapGeometry.sceneNode(); - QCOMPARE(node6->children().count(), ct.tiles().count()); - QCOMPARE(node6->children().count(), 2); - } }; QTEST_GUILESS_MAIN(tst_QGeoMapScene) |