summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2020-02-14 20:24:19 +0200
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2020-02-17 10:40:03 +0200
commit1783b7d28e9b85255e7e47a8eba8dbcee96a945c (patch)
tree1241df27acc5ac2727ba5c9618421609855e1607
parentf75c9a4dc318384197b30e1c9fd13cf7c0690abf (diff)
downloadqtlocation-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.cpp27
-rw-r--r--platform/android/src/map_renderer.hpp10
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;