diff options
author | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2019-10-30 12:04:01 +0200 |
---|---|---|
committer | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2019-10-31 10:24:55 +0200 |
commit | 4afb4438ebf0c8e7d4b4ae5fcfd10d363be6c3c7 (patch) | |
tree | 8ddf07a7a05a0514df2fe1a9c90b31e37fa9fafd /platform/android | |
parent | 8c498cd36c07b1019e5ddb60d5f9f8872f036e25 (diff) | |
download | qtlocation-mapboxgl-4afb4438ebf0c8e7d4b4ae5fcfd10d363be6c3c7.tar.gz |
[android] Convert GeoJSON features to tiles in background
Composing tiles from the GeoJSON features is an expensive
operation that might block UI thread on updating the `GeoJsonSource`
with the new data.
This change moves tile composing to the background thread and thus
unblocks the UI thread.
Diffstat (limited to 'platform/android')
-rw-r--r-- | platform/android/src/style/sources/geojson_source.cpp | 82 | ||||
-rw-r--r-- | platform/android/src/style/sources/geojson_source.hpp | 20 |
2 files changed, 51 insertions, 51 deletions
diff --git a/platform/android/src/style/sources/geojson_source.cpp b/platform/android/src/style/sources/geojson_source.cpp index 5ff4864275..0eece4b1ad 100644 --- a/platform/android/src/style/sources/geojson_source.cpp +++ b/platform/android/src/style/sources/geojson_source.cpp @@ -44,18 +44,16 @@ namespace android { } GeoJSONSource::GeoJSONSource(jni::JNIEnv& env, const jni::String& sourceId, const jni::Object<>& options) - : Source(env, std::make_unique<mbgl::style::GeoJSONSource>( - jni::Make<std::string>(env, sourceId), - convertGeoJSONOptions(env, options))) - , converter(std::make_unique<Actor<FeatureConverter>>(Scheduler::GetBackground())) { - } + : Source(env, + std::make_unique<mbgl::style::GeoJSONSource>(jni::Make<std::string>(env, sourceId), + convertGeoJSONOptions(env, options))), + converter(std::make_unique<Actor<FeatureConverter>>(Scheduler::GetBackground(), + source.as<style::GeoJSONSource>()->getOptions())) {} - GeoJSONSource::GeoJSONSource(jni::JNIEnv& env, - mbgl::style::Source& coreSource, - AndroidRendererFrontend& frontend) - : Source(env, coreSource, createJavaPeer(env), frontend) - , converter(std::make_unique<Actor<FeatureConverter>>(Scheduler::GetBackground())) { - } + GeoJSONSource::GeoJSONSource(jni::JNIEnv& env, mbgl::style::Source& coreSource, AndroidRendererFrontend& frontend) + : Source(env, coreSource, createJavaPeer(env), frontend), + converter(std::make_unique<Actor<FeatureConverter>>(Scheduler::GetBackground(), + source.as<style::GeoJSONSource>()->getOptions())) {} GeoJSONSource::~GeoJSONSource() = default; @@ -63,7 +61,7 @@ namespace android { std::shared_ptr<std::string> json = std::make_shared<std::string>(jni::Make<std::string>(env, jString)); - Update::Converter converterFn = [this, json](ActorRef<Callback> _callback) { + Update::Converter converterFn = [this, json](ActorRef<GeoJSONDataCallback> _callback) { converter->self().invoke(&FeatureConverter::convertJson, json, _callback); }; @@ -84,11 +82,11 @@ namespace android { void GeoJSONSource::setURL(jni::JNIEnv& env, const jni::String& url) { // Update the core source - source.as<mbgl::style::GeoJSONSource>()->GeoJSONSource::setURL(jni::Make<std::string>(env, url)); + source.as<style::GeoJSONSource>()->setURL(jni::Make<std::string>(env, url)); } jni::Local<jni::String> GeoJSONSource::getURL(jni::JNIEnv& env) { - optional<std::string> url = source.as<mbgl::style::GeoJSONSource>()->GeoJSONSource::getURL(); + optional<std::string> url = source.as<style::GeoJSONSource>()->getURL(); return url ? jni::Make<jni::String>(env, *url) : jni::Local<jni::String>(); } @@ -166,7 +164,7 @@ namespace android { auto global = jni::NewGlobal<jni::EnvAttachingDeleter>(env, jObject); auto object = std::make_shared<decltype(global)>(std::move(global)); - Update::Converter converterFn = [this, object](ActorRef<Callback> _callback) { + Update::Converter converterFn = [this, object](ActorRef<GeoJSONDataCallback> _callback) { converter->self().invoke(&FeatureConverter::convertObject<JNIType>, object, _callback); }; @@ -175,25 +173,23 @@ namespace android { void GeoJSONSource::setAsync(Update::Converter converterFn) { awaitingUpdate = std::make_unique<Update>( - std::move(converterFn), - std::make_unique<Actor<Callback>>( - *Scheduler::GetCurrent(), - [this](GeoJSON geoJSON) { - // conversion from Java features to core ones finished - android::UniqueEnv _env = android::AttachEnv(); - - // Update the core source - source.as<mbgl::style::GeoJSONSource>()->GeoJSONSource::setGeoJSON(geoJSON); - - // if there is an awaiting update, execute it, otherwise, release resources - if (awaitingUpdate) { - update = std::move(awaitingUpdate); - update->converterFn(update->callback->self()); - } else { - update.reset(); - } - }) - ); + std::move(converterFn), + std::make_unique<Actor<GeoJSONDataCallback>>( + *Scheduler::GetCurrent(), [this](std::shared_ptr<style::GeoJSONData> geoJSONData) { + // conversion from Java features to core ones finished + android::UniqueEnv _env = android::AttachEnv(); + + // Update the core source + source.as<mbgl::style::GeoJSONSource>()->setGeoJSONData(std::move(geoJSONData)); + + // if there is an awaiting update, execute it, otherwise, release resources + if (awaitingUpdate) { + update = std::move(awaitingUpdate); + update->converterFn(update->callback->self()); + } else { + update.reset(); + } + })); // If another update is running, wait if (update) { @@ -230,12 +226,10 @@ namespace android { ); } - void FeatureConverter::convertJson(std::shared_ptr<std::string> json, - ActorRef<Callback> callback) { + void FeatureConverter::convertJson(std::shared_ptr<std::string> json, ActorRef<GeoJSONDataCallback> callback) { using namespace mbgl::style::conversion; android::UniqueEnv _env = android::AttachEnv(); - // Convert the jni object Error error; optional<GeoJSON> converted = parseGeoJSON(*json, error); @@ -243,23 +237,23 @@ namespace android { mbgl::Log::Error(mbgl::Event::JNI, "Error setting geo json: " + error.message); return; } - - callback.invoke(&Callback::operator(), *converted); + callback.invoke(&GeoJSONDataCallback::operator(), style::GeoJSONData::create(*converted, options)); } template <class JNIType> - void FeatureConverter::convertObject(std::shared_ptr<jni::Global<jni::Object<JNIType>, jni::EnvAttachingDeleter>> jObject, ActorRef<Callback> callback) { + void FeatureConverter::convertObject( + std::shared_ptr<jni::Global<jni::Object<JNIType>, jni::EnvAttachingDeleter>> jObject, + ActorRef<GeoJSONDataCallback> callback) { using namespace mbgl::android::geojson; android::UniqueEnv _env = android::AttachEnv(); // Convert the jni object auto geometry = JNIType::convert(*_env, *jObject); - callback.invoke(&Callback::operator(), GeoJSON(geometry)); + callback.invoke(&GeoJSONDataCallback::operator(), style::GeoJSONData::create(geometry, options)); } - Update::Update(Converter _converterFn, std::unique_ptr<Actor<Callback>> _callback) - : converterFn(std::move(_converterFn)) - , callback(std::move(_callback)) {} + Update::Update(Converter _converterFn, std::unique_ptr<Actor<GeoJSONDataCallback>> _callback) + : converterFn(std::move(_converterFn)), callback(std::move(_callback)) {} } // namespace android } // namespace mbgl diff --git a/platform/android/src/style/sources/geojson_source.hpp b/platform/android/src/style/sources/geojson_source.hpp index e737e41924..e506191ceb 100644 --- a/platform/android/src/style/sources/geojson_source.hpp +++ b/platform/android/src/style/sources/geojson_source.hpp @@ -11,22 +11,28 @@ namespace mbgl { namespace android { -using Callback = std::function<void (GeoJSON)>; +using GeoJSONDataCallback = std::function<void(std::shared_ptr<style::GeoJSONData>)>; -struct FeatureConverter { - void convertJson(std::shared_ptr<std::string>, ActorRef<Callback>); +class FeatureConverter { +public: + explicit FeatureConverter(style::GeoJSONOptions options_) : options(std::move(options_)) {} + void convertJson(std::shared_ptr<std::string>, ActorRef<GeoJSONDataCallback>); template <class JNIType> - void convertObject(std::shared_ptr<jni::Global<jni::Object<JNIType>, jni::EnvAttachingDeleter>>, ActorRef<Callback>); + void convertObject(std::shared_ptr<jni::Global<jni::Object<JNIType>, jni::EnvAttachingDeleter>>, + ActorRef<GeoJSONDataCallback>); + +private: + style::GeoJSONOptions options; }; struct Update { - using Converter = std::function<void (ActorRef<Callback>)>; + using Converter = std::function<void(ActorRef<GeoJSONDataCallback>)>; Converter converterFn; - std::unique_ptr<Actor<Callback>> callback; + std::unique_ptr<Actor<GeoJSONDataCallback>> callback; - Update(Converter, std::unique_ptr<Actor<Callback>>); + Update(Converter, std::unique_ptr<Actor<GeoJSONDataCallback>>); }; class GeoJSONSource : public Source { |