From 2445869b0c3df5ba5b9c2afc1caba7f67f6f18a3 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Fri, 24 Jan 2020 12:38:08 +0200 Subject: GeoJSONSource is re-using the existing scheduler Thus avoiding spawing new threads on `setGeoJSONData()` calls. --- include/mbgl/style/sources/geojson_source.hpp | 5 ++++- src/mbgl/style/sources/geojson_source.cpp | 16 ++++++++++++++-- src/mbgl/style/sources/geojson_source_impl.cpp | 26 +++++++++++++++----------- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/include/mbgl/style/sources/geojson_source.hpp b/include/mbgl/style/sources/geojson_source.hpp index df2f9d2daf..750d29627d 100644 --- a/include/mbgl/style/sources/geojson_source.hpp +++ b/include/mbgl/style/sources/geojson_source.hpp @@ -42,7 +42,8 @@ public: using TileFeatures = mapbox::feature::feature_collection; using Features = mapbox::feature::feature_collection; static std::shared_ptr create(const GeoJSON&, - Immutable = GeoJSONOptions::defaultOptions()); + Immutable = GeoJSONOptions::defaultOptions(), + std::shared_ptr scheduler = nullptr); virtual ~GeoJSONData() = default; virtual void getTile(const CanonicalTileID&, const std::function&) = 0; @@ -53,6 +54,8 @@ public: const std::uint32_t limit = 10u, const std::uint32_t offset = 0u) = 0; virtual std::uint8_t getClusterExpansionZoom(std::uint32_t) = 0; + + virtual std::shared_ptr getScheduler() { return nullptr; } }; class GeoJSONSource final : public Source { diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp index d8414c1f84..3afccf07f2 100644 --- a/src/mbgl/style/sources/geojson_source.cpp +++ b/src/mbgl/style/sources/geojson_source.cpp @@ -39,8 +39,20 @@ void GeoJSONSource::setURL(const std::string& url_) { } } +namespace { + +inline std::shared_ptr createGeoJSONData(const mapbox::geojson::geojson& geoJSON, + const GeoJSONSource::Impl& impl) { + if (auto data = impl.getData().lock()) { + return GeoJSONData::create(geoJSON, impl.getOptions(), data->getScheduler()); + } + return GeoJSONData::create(geoJSON, impl.getOptions()); +} + +} // namespace + void GeoJSONSource::setGeoJSON(const mapbox::geojson::geojson& geoJSON) { - setGeoJSONData(GeoJSONData::create(geoJSON, impl().getOptions())); + setGeoJSONData(createGeoJSONData(geoJSON, impl())); } void GeoJSONSource::setGeoJSONData(std::shared_ptr geoJSONData) { @@ -83,7 +95,7 @@ void GeoJSONSource::loadDescription(FileSource& fileSource) { conversion::Error error; std::shared_ptr geoJSONData; if (optional geoJSON = conversion::convertJSON(*data, error)) { - geoJSONData = GeoJSONData::create(*geoJSON, current.getOptions()); + geoJSONData = createGeoJSONData(*geoJSON, current); } else { // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for tiles to load. Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", error.message.c_str()); diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp index e73876b429..bb5445f02b 100644 --- a/src/mbgl/style/sources/geojson_source_impl.cpp +++ b/src/mbgl/style/sources/geojson_source_impl.cpp @@ -13,8 +13,7 @@ namespace mbgl { namespace style { -class GeoJSONVTData : public GeoJSONData { -public: +class GeoJSONVTData final : public GeoJSONData { void getTile(const CanonicalTileID& id, const std::function& fn) final { assert(fn); scheduler->scheduleAndReplyValue( @@ -29,18 +28,21 @@ public: return 0; } -private: + std::shared_ptr getScheduler() final { return scheduler; } + friend GeoJSONData; - GeoJSONVTData(const GeoJSON& geoJSON, const mapbox::geojsonvt::Options& options) - : impl(std::make_shared(geoJSON, options)), - scheduler(Scheduler::GetSequenced()) {} + GeoJSONVTData(const GeoJSON& geoJSON, + const mapbox::geojsonvt::Options& options, + std::shared_ptr scheduler_) + : impl(std::make_shared(geoJSON, options)), scheduler(std::move(scheduler_)) { + assert(scheduler); + } std::shared_ptr impl; // Accessed on worker thread. std::shared_ptr scheduler; }; -class SuperclusterData : public GeoJSONData { -public: +class SuperclusterData final : public GeoJSONData { void getTile(const CanonicalTileID& id, const std::function& fn) final { assert(fn); fn(impl.getTile(id.z, id.x, id.y)); @@ -56,7 +58,6 @@ public: return impl.getClusterExpansionZoom(cluster_id); } -private: friend GeoJSONData; SuperclusterData(const Features& features, const mapbox::supercluster::Options& options) : impl(features, options) {} @@ -78,7 +79,9 @@ T evaluateFeature(const mapbox::feature::feature& f, } // static -std::shared_ptr GeoJSONData::create(const GeoJSON& geoJSON, Immutable options) { +std::shared_ptr GeoJSONData::create(const GeoJSON& geoJSON, + Immutable options, + std::shared_ptr scheduler) { constexpr double scale = util::EXTENT / util::tileSize; if (options->cluster && geoJSON.is() && !geoJSON.get().empty()) { mapbox::supercluster::Options clusterOptions; @@ -114,7 +117,8 @@ std::shared_ptr GeoJSONData::create(const GeoJSON& geoJSON, Immutab vtOptions.buffer = ::round(scale * options->buffer); vtOptions.tolerance = scale * options->tolerance; vtOptions.lineMetrics = options->lineMetrics; - return std::shared_ptr(new GeoJSONVTData(geoJSON, vtOptions)); + if (!scheduler) scheduler = Scheduler::GetSequenced(); + return std::shared_ptr(new GeoJSONVTData(geoJSON, vtOptions, std::move(scheduler))); } GeoJSONSource::Impl::Impl(std::string id_, Immutable options_) -- cgit v1.2.1