Fix laggy map when using synchronous GeoJSON source [Core fix] (#4092)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bart Louwers <bart@emeel.net>
Co-authored-by: Bart Louwers <bart.louwers@gmail.com>
This commit is contained in:
Alex Cristici
2026-03-03 19:28:45 +02:00
committed by GitHub
parent 10453c1ec4
commit a11571ce21
5 changed files with 32 additions and 153 deletions

View File

@@ -49,20 +49,24 @@ GeoJSONSource::GeoJSONSource(jni::JNIEnv& env, const jni::String& sourceId, cons
: 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>()->impl().getOptions())) {}
converter(
std::make_unique<OptionalActor<FeatureConverter>>(source.as<style::GeoJSONSource>()->isUpdateSynchronous(),
Scheduler::GetBackground(),
source.as<style::GeoJSONSource>()->impl().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(),
source.as<style::GeoJSONSource>()->impl().getOptions())) {}
converter(
std::make_unique<OptionalActor<FeatureConverter>>(source.as<style::GeoJSONSource>()->isUpdateSynchronous(),
Scheduler::GetBackground(),
source.as<style::GeoJSONSource>()->impl().getOptions())) {}
GeoJSONSource::~GeoJSONSource() = default;
void GeoJSONSource::setGeoJSONString(jni::JNIEnv& env, const jni::String& jString) {
std::shared_ptr<std::string> json = std::make_shared<std::string>(jni::Make<std::string>(env, jString));
ActorRef<FeatureConverter> converterRef = converter->self();
OptionalActorRef<FeatureConverter> converterRef = converter->self();
Update::Converter converterFn = [converterRef, json](ActorRef<GeoJSONDataCallback> _callback) {
converterRef.invoke(&FeatureConverter::convertJson, json, _callback);
};
@@ -70,17 +74,6 @@ void GeoJSONSource::setGeoJSONString(jni::JNIEnv& env, const jni::String& jStrin
setAsync(converterFn);
}
void GeoJSONSource::setGeoJSONStringSync(jni::JNIEnv& env, const jni::String& jString) {
std::shared_ptr<std::string> json = std::make_shared<std::string>(jni::Make<std::string>(env, jString));
ActorRef<FeatureConverter> converterRef = converter->self();
Update::Converter converterFn = [converterRef, json](ActorRef<GeoJSONDataCallback> _callback) {
converterRef.ask(&FeatureConverter::convertJson, json, _callback).wait();
};
setAsync(converterFn);
}
void GeoJSONSource::setFeatureCollection(jni::JNIEnv& env, const jni::Object<geojson::FeatureCollection>& jFeatures) {
setCollectionAsync(env, jFeatures);
}
@@ -93,19 +86,6 @@ void GeoJSONSource::setGeometry(jni::JNIEnv& env, const jni::Object<geojson::Geo
setCollectionAsync(env, jGeometry);
}
void GeoJSONSource::setFeatureCollectionSync(jni::JNIEnv& env,
const jni::Object<geojson::FeatureCollection>& jFeatures) {
setCollectionSync(env, jFeatures);
}
void GeoJSONSource::setFeatureSync(jni::JNIEnv& env, const jni::Object<geojson::Feature>& jFeature) {
setCollectionSync(env, jFeature);
}
void GeoJSONSource::setGeometrySync(jni::JNIEnv& env, const jni::Object<geojson::Geometry>& jGeometry) {
setCollectionSync(env, jGeometry);
}
void GeoJSONSource::setURL(jni::JNIEnv& env, const jni::String& url) {
// Update the core source
source.as<style::GeoJSONSource>()->setURL(jni::Make<std::string>(env, url));
@@ -195,7 +175,7 @@ void GeoJSONSource::setCollectionAsync(jni::JNIEnv& env, const jni::Object<JNITy
auto global = jni::NewGlobal<jni::EnvAttachingDeleter>(env, jObject);
auto object = std::make_shared<decltype(global)>(std::move(global));
ActorRef<FeatureConverter> converterRef = converter->self();
OptionalActorRef<FeatureConverter> converterRef = converter->self();
Update::Converter converterFn = [converterRef, object](ActorRef<GeoJSONDataCallback> _callback) {
converterRef.invoke(&FeatureConverter::convertObject<JNIType>, object, _callback);
};
@@ -233,19 +213,6 @@ void GeoJSONSource::setAsync(Update::Converter converterFn) {
update->converterFn(update->callback->self());
}
template <class JNIType>
void GeoJSONSource::setCollectionSync(jni::JNIEnv& env, const jni::Object<JNIType>& jObject) {
auto global = jni::NewGlobal<jni::EnvAttachingDeleter>(env, jObject);
auto object = std::make_shared<decltype(global)>(std::move(global));
ActorRef<FeatureConverter> converterRef = converter->self();
Update::Converter converterFn = [converterRef, object](ActorRef<GeoJSONDataCallback> _callback) {
converterRef.ask(&FeatureConverter::convertObject<JNIType>, object, _callback).wait();
};
setAsync(converterFn);
}
jboolean GeoJSONSource::isUpdateSynchronous(jni::JNIEnv&) {
return source.as<style::GeoJSONSource>()->isUpdateSynchronous();
}
@@ -268,10 +235,6 @@ void GeoJSONSource::registerNative(jni::JNIEnv& env) {
METHOD(&GeoJSONSource::setFeatureCollection, "nativeSetFeatureCollection"),
METHOD(&GeoJSONSource::setFeature, "nativeSetFeature"),
METHOD(&GeoJSONSource::setGeometry, "nativeSetGeometry"),
METHOD(&GeoJSONSource::setGeoJSONStringSync, "nativeSetGeoJsonStringSync"),
METHOD(&GeoJSONSource::setFeatureCollectionSync, "nativeSetFeatureCollectionSync"),
METHOD(&GeoJSONSource::setFeatureSync, "nativeSetFeatureSync"),
METHOD(&GeoJSONSource::setGeometrySync, "nativeSetGeometrySync"),
METHOD(&GeoJSONSource::setURL, "nativeSetUrl"),
METHOD(&GeoJSONSource::getURL, "nativeGetUrl"),
METHOD(&GeoJSONSource::querySourceFeatures, "querySourceFeatures"),

View File

@@ -2,6 +2,7 @@
#include "source.hpp"
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/actor/optional_actor.hpp>
#include "../../geojson/geometry.hpp"
#include "../../geojson/feature.hpp"
#include "../../geojson/feature_collection.hpp"
@@ -55,11 +56,6 @@ private:
void setFeature(jni::JNIEnv&, const jni::Object<geojson::Feature>&);
void setGeometry(jni::JNIEnv&, const jni::Object<geojson::Geometry>&);
void setGeoJSONStringSync(jni::JNIEnv&, const jni::String&);
void setFeatureCollectionSync(jni::JNIEnv&, const jni::Object<geojson::FeatureCollection>&);
void setFeatureSync(jni::JNIEnv&, const jni::Object<geojson::Feature>&);
void setGeometrySync(jni::JNIEnv&, const jni::Object<geojson::Geometry>&);
void setURL(jni::JNIEnv&, const jni::String&);
jni::Local<jni::Array<jni::Object<geojson::Feature>>> querySourceFeatures(jni::JNIEnv&,
@@ -79,7 +75,7 @@ private:
std::unique_ptr<Update> awaitingUpdate;
std::unique_ptr<Update> update;
std::shared_ptr<ThreadPool> threadPool;
std::unique_ptr<Actor<FeatureConverter>> converter;
std::unique_ptr<OptionalActor<FeatureConverter>> converter;
template <class JNIType>
void setCollectionAsync(jni::JNIEnv&, const jni::Object<JNIType>&);