diff options
author | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2020-02-14 20:24:19 +0200 |
---|---|---|
committer | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2020-02-17 10:40:03 +0200 |
commit | 1783b7d28e9b85255e7e47a8eba8dbcee96a945c (patch) | |
tree | 1241df27acc5ac2727ba5c9618421609855e1607 | |
parent | f75c9a4dc318384197b30e1c9fd13cf7c0690abf (diff) | |
download | qtlocation-mapboxgl-upstream/alexshalamov_dont_create_weak_in_constructor.tar.gz |
[android] Don't construct weak sheduler in renderer's custructorupstream/alexshalamov_dont_create_weak_in_constructor
Android renderer creates mailbox that is owned by the scheduler that
is required by the mailbox itself. Construction should be split, so
that scheduler is fully constructed and it's weakPtr can be created.
-rw-r--r-- | platform/android/src/map_renderer.cpp | 27 | ||||
-rw-r--r-- | platform/android/src/map_renderer.hpp | 10 |
2 files changed, 28 insertions, 9 deletions
diff --git a/platform/android/src/map_renderer.cpp b/platform/android/src/map_renderer.cpp index f5336e3dd8..3ebbdb7e5e 100644 --- a/platform/android/src/map_renderer.cpp +++ b/platform/android/src/map_renderer.cpp @@ -17,10 +17,21 @@ MapRenderer::MapRenderer(jni::JNIEnv& _env, const jni::Object<MapRenderer>& obj, jni::jfloat pixelRatio_, const jni::String& localIdeographFontFamily_) - : javaPeer(_env, obj) - , pixelRatio(pixelRatio_) - , localIdeographFontFamily(localIdeographFontFamily_ ? jni::Make<std::string>(_env, localIdeographFontFamily_) : optional<std::string>{}) - , mailbox(std::make_shared<Mailbox>(*this)) { + : javaPeer(_env, obj), + pixelRatio(pixelRatio_), + localIdeographFontFamily(localIdeographFontFamily_ ? jni::Make<std::string>(_env, localIdeographFontFamily_) + : optional<std::string>{}), + mailboxData(this) {} + +MapRenderer::MailboxData::MailboxData(Scheduler* scheduler_) : scheduler(scheduler_) { + assert(scheduler); +} + +std::shared_ptr<Mailbox> MapRenderer::MailboxData::getMailbox() const noexcept { + if (!mailbox) { + mailbox = std::make_shared<Mailbox>(*scheduler); + } + return mailbox; } MapRenderer::~MapRenderer() = default; @@ -30,7 +41,7 @@ void MapRenderer::reset() { if (renderer) { // Make sure to destroy the renderer on the GL Thread - auto self = ActorRef<MapRenderer>(*this, mailbox); + auto self = ActorRef<MapRenderer>(*this, mailboxData.getMailbox()); self.ask(&MapRenderer::resetRenderer).wait(); } @@ -93,7 +104,7 @@ void MapRenderer::setObserver(std::shared_ptr<RendererObserver> _rendererObserve } void MapRenderer::requestSnapshot(SnapshotCallback callback) { - auto self = ActorRef<MapRenderer>(*this, mailbox); + auto self = ActorRef<MapRenderer>(*this, mailboxData.getMailbox()); self.invoke( &MapRenderer::scheduleSnapshot, std::make_unique<SnapshotCallback>([&, callback=std::move(callback), runloop=util::RunLoop::Get()](PremultipliedImage image) { @@ -172,7 +183,7 @@ void MapRenderer::onSurfaceCreated(JNIEnv&) { // Create the new backend and renderer backend = std::make_unique<AndroidRendererBackend>(); renderer = std::make_unique<Renderer>(*backend, pixelRatio, localIdeographFontFamily); - rendererRef = std::make_unique<ActorRef<Renderer>>(*renderer, mailbox); + rendererRef = std::make_unique<ActorRef<Renderer>>(*renderer, mailboxData.getMailbox()); // Set the observer on the new Renderer implementation if (rendererObserver) { @@ -193,7 +204,7 @@ void MapRenderer::onSurfaceChanged(JNIEnv& env, jint width, jint height) { void MapRenderer::onRendererReset(JNIEnv&) { // Make sure to destroy the renderer on the GL Thread - auto self = ActorRef<MapRenderer>(*this, mailbox); + auto self = ActorRef<MapRenderer>(*this, mailboxData.getMailbox()); self.ask(&MapRenderer::resetRenderer).wait(); } diff --git a/platform/android/src/map_renderer.hpp b/platform/android/src/map_renderer.hpp index 047f1870c7..e37d37cfc8 100644 --- a/platform/android/src/map_renderer.hpp +++ b/platform/android/src/map_renderer.hpp @@ -82,6 +82,14 @@ protected: void scheduleSnapshot(std::unique_ptr<SnapshotCallback>); private: + struct MailboxData { + explicit MailboxData(Scheduler*); + std::shared_ptr<Mailbox> getMailbox() const noexcept; + + private: + Scheduler* scheduler; + mutable std::shared_ptr<Mailbox> mailbox; + }; // Called from the GL Thread // // Resets the renderer @@ -107,7 +115,7 @@ private: optional<std::string> localIdeographFontFamily; std::shared_ptr<ThreadPool> threadPool; - std::shared_ptr<Mailbox> mailbox; + const MailboxData mailboxData; std::mutex initialisationMutex; std::shared_ptr<RendererObserver> rendererObserver; |