diff options
Diffstat (limited to 'platform')
-rw-r--r-- | platform/android/config.cmake | 3 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.cpp | 5 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.hpp | 2 | ||||
-rw-r--r-- | platform/default/thread_pool.cpp | 55 | ||||
-rw-r--r-- | platform/ios/config.cmake | 3 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 11 | ||||
-rw-r--r-- | platform/linux/config.cmake | 3 | ||||
-rw-r--r-- | platform/macos/config.cmake | 3 | ||||
-rw-r--r-- | platform/macos/src/MGLMapView.mm | 9 | ||||
-rw-r--r-- | platform/node/src/node_log.cpp | 3 | ||||
-rw-r--r-- | platform/node/src/node_log.hpp | 5 | ||||
-rw-r--r-- | platform/node/src/node_map.cpp | 3 | ||||
-rw-r--r-- | platform/node/src/node_map.hpp | 3 | ||||
-rw-r--r-- | platform/node/src/node_thread_pool.cpp | 39 | ||||
-rw-r--r-- | platform/node/src/node_thread_pool.hpp | 37 | ||||
-rw-r--r-- | platform/node/src/util/async_queue.hpp | 4 | ||||
-rw-r--r-- | platform/qt/qt.cmake | 3 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl.cpp | 3 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl_p.hpp | 2 |
19 files changed, 183 insertions, 13 deletions
diff --git a/platform/android/config.cmake b/platform/android/config.cmake index 1e6132dc30..74412e4ae5 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -48,6 +48,9 @@ macro(mbgl_platform_core) # Headless view # TODO + + # Thread pool + PRIVATE platform/default/thread_pool.cpp ) target_include_directories(mbgl-core diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 2714b832e3..5bd2694932 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -60,7 +60,8 @@ NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio_, int env(env_), pixelRatio(pixelRatio_), availableProcessors(availableProcessors_), - totalMemory(totalMemory_) { + totalMemory(totalMemory_), + threadPool(4) { mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::NativeMapView"); assert(env_ != nullptr); @@ -81,7 +82,7 @@ NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio_, int mbgl::android::cachePath + "/mbgl-offline.db", mbgl::android::apkPath); - map = std::make_unique<mbgl::Map>(*this, *fileSource, MapMode::Continuous); + map = std::make_unique<mbgl::Map>(*this, *fileSource, threadPool, MapMode::Continuous); float zoomFactor = map->getMaxZoom() - map->getMinZoom() + 1; float cpuFactor = availableProcessors; diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index 7974f282d9..d42890dae2 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -3,6 +3,7 @@ #include <mbgl/map/map.hpp> #include <mbgl/map/view.hpp> #include <mbgl/util/noncopyable.hpp> +#include <mbgl/platform/default/thread_pool.hpp> #include <mbgl/storage/default_file_source.hpp> #include <string> @@ -95,6 +96,7 @@ private: // Ensure these are initialised last std::unique_ptr<mbgl::DefaultFileSource> fileSource; + mbgl::ThreadPool threadPool; std::unique_ptr<mbgl::Map> map; mbgl::EdgeInsets insets; diff --git a/platform/default/thread_pool.cpp b/platform/default/thread_pool.cpp new file mode 100644 index 0000000000..7108312c58 --- /dev/null +++ b/platform/default/thread_pool.cpp @@ -0,0 +1,55 @@ +#include <mbgl/platform/default/thread_pool.hpp> +#include <mbgl/actor/mailbox.hpp> + +namespace mbgl { + +ThreadPool::ThreadPool(std::size_t count) { + threads.reserve(count); + for (std::size_t i = 0; i < count; ++i) { + threads.emplace_back([this] () { + while (true) { + std::unique_lock<std::mutex> lock(mutex); + + cv.wait(lock, [this] { + return !queue.empty() || terminate; + }); + + if (terminate) { + return; + } + + auto mailbox = queue.front(); + queue.pop(); + lock.unlock(); + + if (auto locked = mailbox.lock()) { + locked->receive(); + } + } + }); + } +} + +ThreadPool::~ThreadPool() { + { + std::lock_guard<std::mutex> lock(mutex); + terminate = true; + } + + cv.notify_all(); + + for (auto& thread : threads) { + thread.join(); + } +} + +void ThreadPool::schedule(std::weak_ptr<Mailbox> mailbox) { + { + std::lock_guard<std::mutex> lock(mutex); + queue.push(mailbox); + } + + cv.notify_one(); +} + +} // namespace mbgl diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index 6c83395a3e..e5480e37df 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -40,6 +40,9 @@ macro(mbgl_platform_core) PRIVATE platform/darwin/src/headless_view_eagl.mm PRIVATE platform/default/headless_display.cpp PRIVATE platform/default/headless_view.cpp + + # Thread pool + PRIVATE platform/default/thread_pool.cpp ) target_add_mason_package(mbgl-core PUBLIC geojson) diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 88f4d8a970..194f1a88d4 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -13,6 +13,7 @@ #include <mbgl/map/mode.hpp> #include <mbgl/platform/platform.hpp> #include <mbgl/platform/darwin/reachability.h> +#include <mbgl/platform/default/thread_pool.hpp> #include <mbgl/storage/default_file_source.hpp> #include <mbgl/storage/network_status.hpp> #include <mbgl/style/transition_options.hpp> @@ -258,6 +259,7 @@ public: { mbgl::Map *_mbglMap; MBGLView *_mbglView; + mbgl::ThreadPool *_mbglThreadPool; BOOL _opaque; @@ -397,7 +399,8 @@ public: // setup mbgl map mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource; - _mbglMap = new mbgl::Map(*_mbglView, *mbglFileSource, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default); + _mbglThreadPool = new mbgl::ThreadPool(4); + _mbglMap = new mbgl::Map(*_mbglView, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default); [self validateTileCacheSize]; // start paused if in IB @@ -650,6 +653,12 @@ public: _mbglView = nullptr; } + if (_mbglThreadPool) + { + delete _mbglThreadPool; + _mbglThreadPool = nullptr; + } + if ([[EAGLContext currentContext] isEqual:_context]) { [EAGLContext setCurrentContext:nil]; diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index 050a03bcb2..86e8697f8c 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -44,6 +44,9 @@ macro(mbgl_platform_core) PRIVATE platform/default/headless_display.cpp PRIVATE platform/default/headless_view.cpp PRIVATE platform/default/headless_view_glx.cpp + + # Thread pool + PRIVATE platform/default/thread_pool.cpp ) target_include_directories(mbgl-core diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index f8d4ab398f..645feb90c3 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -38,6 +38,9 @@ macro(mbgl_platform_core) PRIVATE platform/darwin/src/headless_view_cgl.cpp PRIVATE platform/default/headless_display.cpp PRIVATE platform/default/headless_view.cpp + + # Thread pool + PRIVATE platform/default/thread_pool.cpp ) target_add_mason_package(mbgl-core PUBLIC geojson) diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index a8f91a24e7..46766b573b 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -22,6 +22,7 @@ #import <mbgl/annotation/annotation.hpp> #import <mbgl/map/camera.hpp> #import <mbgl/platform/darwin/reachability.h> +#import <mbgl/platform/default/thread_pool.hpp> #import <mbgl/gl/extension.hpp> #import <mbgl/gl/gl.hpp> #import <mbgl/sprite/sprite_image.hpp> @@ -158,6 +159,7 @@ public: /// Cross-platform map view controller. mbgl::Map *_mbglMap; MGLMapViewImpl *_mbglView; + mbgl::ThreadPool *_mbglThreadPool; NSPanGestureRecognizer *_panGestureRecognizer; NSMagnificationGestureRecognizer *_magnificationGestureRecognizer; @@ -261,7 +263,8 @@ public: [[NSFileManager defaultManager] removeItemAtURL:legacyCacheURL error:NULL]; mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource; - _mbglMap = new mbgl::Map(*_mbglView, *mbglFileSource, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default); + _mbglThreadPool = new mbgl::ThreadPool(4); + _mbglMap = new mbgl::Map(*_mbglView, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default); [self validateTileCacheSize]; // Install the OpenGL layer. Interface Builder’s synchronous drawing means @@ -466,6 +469,10 @@ public: delete _mbglView; _mbglView = nullptr; } + if (_mbglThreadPool) { + delete _mbglThreadPool; + _mbglThreadPool = nullptr; + } } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(__unused NSDictionary *)change context:(void *)context { diff --git a/platform/node/src/node_log.cpp b/platform/node/src/node_log.cpp index 5ea0bcc06a..0a97ebce36 100644 --- a/platform/node/src/node_log.cpp +++ b/platform/node/src/node_log.cpp @@ -1,5 +1,4 @@ #include "node_log.hpp" -#include "util/async_queue.hpp" #include <mbgl/util/enum.hpp> @@ -19,7 +18,7 @@ struct NodeLogObserver::LogMessage { }; NodeLogObserver::NodeLogObserver(v8::Local<v8::Object> target) - : queue(new Queue(uv_default_loop(), [this](LogMessage &message) { + : queue(new util::AsyncQueue<LogMessage>(uv_default_loop(), [this](LogMessage &message) { Nan::HandleScope scope; auto msg = Nan::New<v8::Object>(); diff --git a/platform/node/src/node_log.hpp b/platform/node/src/node_log.hpp index d29e4e28e0..a19c61284b 100644 --- a/platform/node/src/node_log.hpp +++ b/platform/node/src/node_log.hpp @@ -1,5 +1,7 @@ #pragma once +#include "util/async_queue.hpp" + #include <mbgl/platform/log.hpp> #pragma GCC diagnostic push @@ -24,8 +26,7 @@ private: Nan::Persistent<v8::Object> module; struct LogMessage; - using Queue = util::AsyncQueue<LogMessage>; - Queue *queue = nullptr; + util::AsyncQueue<LogMessage>* queue; }; } diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index 4d4be5be66..a13adbc417 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -777,7 +777,8 @@ NodeMap::NodeMap(v8::Local<v8::Object> options) : Nan::HandleScope scope; return Nan::Has(options, Nan::New("ratio").ToLocalChecked()).FromJust() ? Nan::Get(options, Nan::New("ratio").ToLocalChecked()).ToLocalChecked()->NumberValue() : 1.0; }()), - map(std::make_unique<mbgl::Map>(view, *this, mbgl::MapMode::Still)), + threadpool(), + map(std::make_unique<mbgl::Map>(view, *this, threadpool, mbgl::MapMode::Still)), async(new uv_async_t) { view.setMapChangeCallback([&](mbgl::MapChange change) { diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp index c0b025c369..cdca1587ea 100644 --- a/platform/node/src/node_map.hpp +++ b/platform/node/src/node_map.hpp @@ -1,5 +1,7 @@ #pragma once +#include "node_thread_pool.hpp" + #include <mbgl/map/map.hpp> #include <mbgl/storage/file_source.hpp> #include <mbgl/platform/default/headless_view.hpp> @@ -52,6 +54,7 @@ public: std::unique_ptr<mbgl::AsyncRequest> request(const mbgl::Resource&, mbgl::FileSource::Callback); mbgl::HeadlessView view; + NodeThreadPool threadpool; std::unique_ptr<mbgl::Map> map; std::exception_ptr error; diff --git a/platform/node/src/node_thread_pool.cpp b/platform/node/src/node_thread_pool.cpp new file mode 100644 index 0000000000..a9faef6f09 --- /dev/null +++ b/platform/node/src/node_thread_pool.cpp @@ -0,0 +1,39 @@ +#include "node_thread_pool.hpp" +#include "util/async_queue.hpp" + +#include <mbgl/actor/mailbox.hpp> + +namespace node_mbgl { + +NodeThreadPool::NodeThreadPool() + : queue(new util::AsyncQueue<std::weak_ptr<mbgl::Mailbox>>(uv_default_loop(), [this](std::weak_ptr<mbgl::Mailbox> mailbox) { + Worker* worker = new Worker(mailbox); + Nan::AsyncQueueWorker(worker); + })) { + // Don't keep the event loop alive. + queue->unref(); +} + +NodeThreadPool::~NodeThreadPool() { + queue->stop(); +} + +void NodeThreadPool::schedule(std::weak_ptr<mbgl::Mailbox> mailbox) { + queue->send(std::move(mailbox)); +} + +NodeThreadPool::Worker::Worker(std::weak_ptr<mbgl::Mailbox> mailbox_) + : AsyncWorker(nullptr), + mailbox(std::move(mailbox_)) {}; + +void NodeThreadPool::Worker::Execute() { + if (auto locked = mailbox.lock()) { + locked->receive(); + } +} + +void NodeThreadPool::Worker::WorkComplete() { + // no-op to avoid calling nullptr callback +} + +} // namespace node_mbgl diff --git a/platform/node/src/node_thread_pool.hpp b/platform/node/src/node_thread_pool.hpp new file mode 100644 index 0000000000..d412e53d3d --- /dev/null +++ b/platform/node/src/node_thread_pool.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include <mbgl/actor/scheduler.hpp> + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wshadow" +#include <nan.h> +#pragma GCC diagnostic pop + +namespace node_mbgl { + +namespace util { template <typename T> class AsyncQueue; } + +class NodeThreadPool : public mbgl::Scheduler { +public: + NodeThreadPool(); + ~NodeThreadPool(); + + void schedule(std::weak_ptr<mbgl::Mailbox>) override; + +private: + util::AsyncQueue<std::weak_ptr<mbgl::Mailbox>>* queue; + + class Worker : public Nan::AsyncWorker { + public: + Worker(std::weak_ptr<mbgl::Mailbox>); + + void Execute(); + void WorkComplete(); + + private: + std::weak_ptr<mbgl::Mailbox> mailbox; + }; +}; + +} // namespace node_mbgl diff --git a/platform/node/src/util/async_queue.hpp b/platform/node/src/util/async_queue.hpp index b9081b3aeb..87737437c3 100644 --- a/platform/node/src/util/async_queue.hpp +++ b/platform/node/src/util/async_queue.hpp @@ -28,6 +28,7 @@ public: q->process(); }); } + ~AsyncQueue() {} void send(T &&data) { { @@ -60,9 +61,6 @@ public: } private: - ~AsyncQueue() { - } - void process() { std::unique_ptr<T> item; while (true) { diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake index dc60455b0a..398e173cfa 100644 --- a/platform/qt/qt.cmake +++ b/platform/qt/qt.cmake @@ -30,6 +30,9 @@ set(MBGL_QT_FILES # Misc PRIVATE platform/default/log_stderr.cpp + # Thread pool + PRIVATE platform/default/thread_pool.cpp + # Platform integration PRIVATE platform/qt/src/async_task.cpp PRIVATE platform/qt/src/async_task_impl.hpp diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp index 103ed83256..d0a05301f8 100644 --- a/platform/qt/src/qmapboxgl.cpp +++ b/platform/qt/src/qmapboxgl.cpp @@ -811,8 +811,9 @@ QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settin settings.cacheDatabasePath().toStdString(), settings.assetPath().toStdString(), settings.cacheDatabaseMaximumSize())) + , threadPool(4) , mapObj(std::make_unique<mbgl::Map>( - *this, *fileSourceObj, + *this, *fileSourceObj, threadPool, static_cast<mbgl::MapMode>(settings.mapMode()), static_cast<mbgl::GLContextMode>(settings.contextMode()), static_cast<mbgl::ConstrainMode>(settings.constrainMode()), diff --git a/platform/qt/src/qmapboxgl_p.hpp b/platform/qt/src/qmapboxgl_p.hpp index 11b5f695ca..c35ac4e7ba 100644 --- a/platform/qt/src/qmapboxgl_p.hpp +++ b/platform/qt/src/qmapboxgl_p.hpp @@ -4,6 +4,7 @@ #include <mbgl/map/map.hpp> #include <mbgl/map/view.hpp> +#include <mbgl/platform/default/thread_pool.hpp> #include <mbgl/storage/default_file_source.hpp> #include <mbgl/util/geo.hpp> @@ -34,6 +35,7 @@ public: QMapboxGL *q_ptr { nullptr }; std::unique_ptr<mbgl::DefaultFileSource> fileSourceObj; + mbgl::ThreadPool threadPool; std::unique_ptr<mbgl::Map> mapObj; bool dirty { false }; |