summaryrefslogtreecommitdiff
path: root/src/location
diff options
context:
space:
mode:
Diffstat (limited to 'src/location')
-rw-r--r--src/location/maps/maps.pri2
-rw-r--r--src/location/maps/qgeomap.cpp18
-rw-r--r--src/location/maps/qgeomap_p.h9
-rw-r--r--src/location/maps/qgeomapdata.cpp22
-rw-r--r--src/location/maps/qgeomapdata_p.h8
-rw-r--r--src/location/maps/qgeomapdata_p_p.h6
-rw-r--r--src/location/maps/qgeomapscene.cpp445
-rw-r--r--src/location/maps/qgeomapscene_p.h11
-rw-r--r--src/location/maps/qgeotilecache.cpp43
-rw-r--r--src/location/maps/qgeotilecache_p.h11
-rw-r--r--src/location/maps/qgeotiledmapdata.cpp18
-rw-r--r--src/location/maps/qgeotiledmapdata_p.h6
-rw-r--r--src/location/maps/qgeotiledmapdata_p_p.h5
13 files changed, 232 insertions, 372 deletions
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..568bcb57 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 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));
+ 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(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));
-
- 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,209 @@ 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;
+};
+
+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);
}
- glEnable(GL_SCISSOR_TEST);
+ ~QGeoMapRootNode()
+ {
+ qDeleteAll(textures.values());
+ }
- painter->setScissor(QRect(screenOffsetX_, screenOffsetY_, screenWidth_, screenHeight_));
+ void setClipRect(const QRect &rect)
+ {
+ if (rect != clipRect) {
+ QSGGeometry::updateRectGeometry(&geometry, rect);
+ QSGClipNode::setClipRect(rect);
+ clipRect = rect;
+ markDirty(DirtyGeometry);
+ }
+ }
- painter->setCamera(camera_);
+ void updateTiles(QGeoMapTileContainerNode *root, QGeoMapScenePrivate *d, double camAdjust);
- painter->setMainLight(light_);
+ bool isTextureLinear;
- sceneNode_->draw(painter);
+ QSGGeometry geometry;
+ QRect clipRect;
- QGLCamera *camera = camera_;
+ QSGTransformNode *root;
- bool old = camera->blockSignals(true);
+ 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
- glDisable(GL_DEPTH_TEST);
+ QHash<QGeoTileSpec, QSGTexture *> textures;
+};
- double sideLength = scaleFactor_ * tileSize_ * sideLength_;
+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 c = QDoubleVector3D(camera->center());
- c.setX(c.x() + sideLength);
- camera->setCenter(c);
+static QVector3D toVector3D(const QDoubleVector3D& in)
+{
+ return QVector3D(in.x(), in.y(), in.z());
+}
- 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(toVector3D(eye), toVector3D(center), toVector3D(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);