From 9842214bb66d3f57699358e09b650516571d47eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Sat, 10 Nov 2018 13:18:54 +0100 Subject: [PATCH] Parallelized tile loader --- src/map/tileloader.cpp | 96 ++++++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 23 deletions(-) diff --git a/src/map/tileloader.cpp b/src/map/tileloader.cpp index 9a33fe16..448b08fb 100644 --- a/src/map/tileloader.cpp +++ b/src/map/tileloader.cpp @@ -1,17 +1,43 @@ #include #include #include +#include +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#include +#else // QT_VERSION < 5 +#include +#endif // QT_VERSION < 5 #include "tileloader.h" -static bool loadTileFile(Tile &tile, const QString &file) +class TileImage { - if (!tile.pixmap().load(file, tile.zoom().toString().toLatin1())) { - qWarning("%s: error loading tile file", qPrintable(file)); - return false; +public: + TileImage(const QString &file, Tile &tile) + : _file(file), _tile(tile) {} + + void createPixmap() + { + _tile.pixmap().convertFromImage(_image); + } + void load() + { + QByteArray z(_tile.zoom().toString().toLatin1()); + _image.load(_file, z); } - return true; + const QString &file() const {return _file;} + Tile &tile() {return _tile;} + +private: + QString _file; + Tile &_tile; + QImage _image; +}; + +static void render(TileImage &ti) +{ + ti.load(); } TileLoader::TileLoader(const QString &dir, QObject *parent) @@ -27,18 +53,23 @@ TileLoader::TileLoader(const QString &dir, QObject *parent) void TileLoader::loadTilesAsync(QVector &list) { QList dl; + QList imgs; for (int i = 0; i < list.size(); i++) { Tile &t = list[i]; QString file(tileFile(t)); + + if (QPixmapCache::find(file, t.pixmap())) + continue; + QFileInfo fi(file); if (fi.exists()) - loadTileFile(t, file); + imgs.append(TileImage(file, t)); else { QUrl url(tileUrl(t)); if (url.isLocalFile()) - loadTileFile(t, url.toLocalFile()); + imgs.append(TileImage(url.toLocalFile(), t)); else dl.append(Download(url, file)); } @@ -46,45 +77,64 @@ void TileLoader::loadTilesAsync(QVector &list) if (!dl.empty()) _downloader->get(dl, _authorization); + + QFuture future = QtConcurrent::map(imgs, render); + future.waitForFinished(); + + for (int i = 0; i < imgs.size(); i++) { + TileImage &ti = imgs[i]; + ti.createPixmap(); + QPixmapCache::insert(ti.file(), ti.tile().pixmap()); + } } void TileLoader::loadTilesSync(QVector &list) { QList dl; + QList tl; + QList imgs; for (int i = 0; i < list.size(); i++) { Tile &t = list[i]; QString file(tileFile(t)); + + if (QPixmapCache::find(file, t.pixmap())) + continue; + QFileInfo fi(file); if (fi.exists()) - loadTileFile(t, file); + imgs.append(TileImage(file, t)); else { QUrl url(tileUrl(t)); if (url.isLocalFile()) - loadTileFile(t, url.toLocalFile()); - else + imgs.append(TileImage(url.toLocalFile(), t)); + else { dl.append(Download(url, file)); + tl.append(&t); + } } } - if (dl.empty()) - return; + if (!dl.empty()) { + QEventLoop wait; + QObject::connect(_downloader, SIGNAL(finished()), &wait, SLOT(quit())); + if (_downloader->get(dl, _authorization)) + wait.exec(); - QEventLoop wait; - QObject::connect(_downloader, SIGNAL(finished()), &wait, SLOT(quit())); - if (_downloader->get(dl, _authorization)) - wait.exec(); - - for (int i = 0; i < list.size(); i++) { - Tile &t = list[i]; - - if (t.pixmap().isNull()) { - QString file = tileFile(t); + for (int i = 0; i < tl.size(); i++) { + Tile *t = tl[i]; + QString file = tileFile(*t); if (QFileInfo(file).exists()) - loadTileFile(t, file); + imgs.append(TileImage(file, *t)); } } + + QFuture future = QtConcurrent::map(imgs, render); + future.waitForFinished(); + + for (int i = 0; i < imgs.size(); i++) + imgs[i].createPixmap(); } void TileLoader::clearCache()