Skip to content

Commit

Permalink
Sprite loader, GeoJSON and Style are scheduler-aware
Browse files Browse the repository at this point in the history
  • Loading branch information
mwilsnd committed Jun 24, 2024
1 parent a90548c commit 0e97700
Show file tree
Hide file tree
Showing 32 changed files with 173 additions and 108 deletions.
19 changes: 13 additions & 6 deletions include/mbgl/actor/scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ class Scheduler {
/// The |TaskFn| return type must be compatible with the |ReplyFn| argument
/// type. Note: the task result is copied and passed by value.
template <typename TaskFn, typename ReplyFn>
void scheduleAndReplyValue(const TaskFn& task, const ReplyFn& reply) {
void scheduleAndReplyValue(const util::SimpleIdentity tag, TaskFn&& task, ReplyFn&& reply) {
assert(GetCurrent());
scheduleAndReplyValue(task, reply, GetCurrent()->makeWeakPtr());
scheduleAndReplyValue(tag, task, reply, GetCurrent()->makeWeakPtr());
}

/// Wait until there's nothing pending or in process
Expand Down Expand Up @@ -104,18 +104,19 @@ class Scheduler {

protected:
template <typename TaskFn, typename ReplyFn>
void scheduleAndReplyValue(const TaskFn& task,
void scheduleAndReplyValue(const util::SimpleIdentity tag,
const TaskFn& task,
const ReplyFn& reply,
mapbox::base::WeakPtr<Scheduler> replyScheduler) {
auto scheduled = [replyScheduler = std::move(replyScheduler), task, reply] {
auto scheduled = [replyScheduler = std::move(replyScheduler), tag, task, reply] {
auto lock = replyScheduler.lock();
if (!replyScheduler) return;
auto scheduledReply = [reply, result = task()] {
reply(result);
};
replyScheduler->schedule(std::move(scheduledReply));
replyScheduler->schedule(tag, std::move(scheduledReply));
};
schedule(std::move(scheduled));
schedule(tag, std::move(scheduled));
}

std::function<void(const std::exception_ptr)> handler;
Expand All @@ -141,6 +142,12 @@ class TaggedScheduler {
void runRenderJobs(bool closeQueue = false) { scheduler->runRenderJobs(tag, closeQueue); }
void waitForEmpty() const noexcept { scheduler->waitForEmpty(tag); }

/// type. Note: the task result is copied and passed by value.
template <typename TaskFn, typename ReplyFn>
void scheduleAndReplyValue(TaskFn&& task, ReplyFn&& reply) {
scheduler->scheduleAndReplyValue(tag, task, reply);
}

const mbgl::util::SimpleIdentity tag;

private:
Expand Down
3 changes: 3 additions & 0 deletions include/mbgl/renderer/renderer_frontend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <mbgl/gfx/drawable.hpp>
#endif

#include <mbgl/actor/scheduler.hpp>
#include <memory>

namespace mbgl {
Expand All @@ -30,6 +31,8 @@ class RendererFrontend {
/// Coalescing updates is up to the implementer
virtual void update(std::shared_ptr<UpdateParameters>) = 0;

virtual const TaggedScheduler& getThreadPool() const = 0;

protected:
};

Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/style/sources/geojson_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class GeoJSONData {
using TileFeatures = mapbox::feature::feature_collection<int16_t>;
using Features = mapbox::feature::feature_collection<double>;
static std::shared_ptr<GeoJSONData> create(const GeoJSON&,
std::shared_ptr<Scheduler> scheduler,
std::shared_ptr<Scheduler> sequencedScheduler,
const Immutable<GeoJSONOptions>& = GeoJSONOptions::defaultOptions());

virtual ~GeoJSONData() = default;
Expand Down
3 changes: 2 additions & 1 deletion include/mbgl/style/style.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <mbgl/actor/scheduler.hpp>
#include <mbgl/map/camera.hpp>
#include <mbgl/style/image.hpp>
#include <mbgl/style/transition_options.hpp>
Expand All @@ -22,7 +23,7 @@ class Layer;

class Style {
public:
Style(std::shared_ptr<FileSource>, float pixelRatio);
Style(std::shared_ptr<FileSource>, float pixelRatio, const TaggedScheduler& threadPool_);
~Style();

void loadJSON(const std::string&);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ void AndroidRendererFrontend::update(std::shared_ptr<UpdateParameters> params) {
updateAsyncTask->send();
}

const TaggedScheduler& AndroidRendererFrontend::getThreadPool() const {
return mapRenderer.getRendererBackend().getThreadPool();
}

void AndroidRendererFrontend::reduceMemoryUse() {
mapRenderer.actor().invoke(&Renderer::reduceMemoryUse);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class AndroidRendererFrontend : public RendererFrontend {

void update(std::shared_ptr<UpdateParameters>) override;

const TaggedScheduler& getThreadPool() const override;

// Feature querying
std::vector<Feature> queryRenderedFeatures(const ScreenCoordinate&, const RenderedQueryOptions&) const;
std::vector<Feature> queryRenderedFeatures(const ScreenBox&, const RenderedQueryOptions&) const;
Expand Down
2 changes: 2 additions & 0 deletions platform/android/MapLibreAndroid/src/cpp/map_renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class MapRenderer : public Scheduler {
using SnapshotCallback = std::function<void(PremultipliedImage)>;
void requestSnapshot(SnapshotCallback);

AndroidRendererBackend& getRendererBackend() const { return *backend; }

protected:
// Called from the GL Thread //

Expand Down
5 changes: 5 additions & 0 deletions platform/darwin/src/MLNRendererFrontend.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/gfx/backend_scope.hpp>
#include <mbgl/gfx/renderer_backend.hpp>
#include <mbgl/renderer/renderer.hpp>
Expand Down Expand Up @@ -33,6 +34,10 @@ class MLNRenderFrontend : public mbgl::RendererFrontend {
}
}

const TaggedScheduler& getThreadPool() const override {
return mbglBackend.getThreadPool();
}

void setObserver(mbgl::RendererObserver& observer) override {
if (!renderer) return;
renderer->setObserver(&observer);
Expand Down
1 change: 1 addition & 0 deletions platform/default/include/mbgl/gfx/headless_frontend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class HeadlessFrontend : public RendererFrontend {

void reset() override;
void update(std::shared_ptr<UpdateParameters>) override;
const TaggedScheduler& getThreadPool() const override;
void setObserver(RendererObserver&) override;

double getFrameTime() const;
Expand Down
4 changes: 4 additions & 0 deletions platform/default/src/mbgl/gfx/headless_frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ void HeadlessFrontend::update(std::shared_ptr<UpdateParameters> updateParameters
}
}

const TaggedScheduler& HeadlessFrontend::getThreadPool() const {
return backend->getRendererBackend()->getThreadPool();
}

void HeadlessFrontend::setObserver(RendererObserver& observer_) {
assert(renderer);
renderer->setObserver(&observer_);
Expand Down
8 changes: 8 additions & 0 deletions platform/default/src/mbgl/map/map_snapshotter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ class SnapshotterRenderer final : public RendererObserver {
return std::move(stillImage);
}

const TaggedScheduler& getThreadPool() const {
return frontend.getThreadPool();
}

private:
PremultipliedImage stillImage;
bool hasPendingStillImageRequest = false;
Expand Down Expand Up @@ -156,6 +160,10 @@ class SnapshotterRendererFrontend final : public RendererFrontend {

PremultipliedImage takeImage() { return renderer->actor().ask(&SnapshotterRenderer::takeImage).get(); }

const mbgl::TaggedScheduler& getThreadPool() const override {
return renderer->actor().ask(&SnapshotterRenderer::getThreadPool).get();
}

private:
std::shared_ptr<UpdateParameters> updateParameters;
const std::unique_ptr<util::Thread<SnapshotterRenderer>> renderer;
Expand Down
4 changes: 4 additions & 0 deletions platform/glfw/glfw_renderer_frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ void GLFWRendererFrontend::update(std::shared_ptr<mbgl::UpdateParameters> params
glfwView.invalidate();
}

const TaggedScheduler& GLFWRendererFrontend::getThreadPool() const {
return glfwView.getRendererBackend().getThreadPool();
}

void GLFWRendererFrontend::render() {
MLN_TRACE_FUNC();

Expand Down
1 change: 1 addition & 0 deletions platform/glfw/glfw_renderer_frontend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class GLFWRendererFrontend : public mbgl::RendererFrontend {
void setObserver(mbgl::RendererObserver&) override;

void update(std::shared_ptr<mbgl::UpdateParameters>) override;
const TaggedScheduler& getThreadPool() const override;
void render();

mbgl::Renderer* getRenderer();
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/map/map_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Map::Impl::Impl(RendererFrontend& frontend_,
pixelRatio(mapOptions.pixelRatio()),
crossSourceCollisions(mapOptions.crossSourceCollisions()),
fileSource(std::move(fileSource_)),
style(std::make_unique<style::Style>(fileSource, pixelRatio)),
style(std::make_unique<style::Style>(fileSource, pixelRatio, frontend_.getThreadPool())),
annotationManager(*style) {
transform.setNorthOrientation(mapOptions.northOrientation());
style->impl->setObserver(this);
Expand Down
39 changes: 20 additions & 19 deletions src/mbgl/sprite/sprite_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ struct SpriteLoader::Data {
std::unique_ptr<AsyncRequest> spriteRequest;
};

SpriteLoader::SpriteLoader(float pixelRatio_)
SpriteLoader::SpriteLoader(float pixelRatio_, const TaggedScheduler& threadPool_)
: pixelRatio(pixelRatio_),
observer(&nullObserver),
threadPool(Scheduler::GetBackground()) {}
threadPool(threadPool_) {}

SpriteLoader::~SpriteLoader() = default;

Expand Down Expand Up @@ -93,25 +93,26 @@ void SpriteLoader::emitSpriteLoadedIfComplete(style::Sprite sprite) {
std::exception_ptr error;
};

auto parseClosure = [sprite = sprite, image = data->image, json = data->json]() -> ParseResult {
try {
return {parseSprite(sprite.id, *image, *json), nullptr};
} catch (...) {
return {{}, std::current_exception()};
}
};

auto resultClosure = [this, sprite = sprite, weak = weakFactory.makeWeakPtr()](ParseResult result) {
if (!weak) return; // This instance has been deleted.
threadPool.scheduleAndReplyValue(
/* parseClosure */
[sprite = sprite, image = data->image, json = data->json]() -> ParseResult {
try {
return {parseSprite(sprite.id, *image, *json), nullptr};
} catch (...) {
return {{}, std::current_exception()};
}
},
/* resultClosure */
[this, sprite = sprite, weak = weakFactory.makeWeakPtr()](ParseResult result) {
if (!weak) return; // This instance has been deleted.

if (result.error) {
observer->onSpriteError(std::optional(sprite), result.error);
return;
}
observer->onSpriteLoaded(std::optional(sprite), std::move(result.images));
};
if (result.error) {
observer->onSpriteError(std::optional(sprite), result.error);
return;
}
observer->onSpriteLoaded(std::optional(sprite), std::move(result.images));
});

threadPool->scheduleAndReplyValue(parseClosure, resultClosure);
}

void SpriteLoader::setObserver(SpriteLoaderObserver* observer_) {
Expand Down
6 changes: 3 additions & 3 deletions src/mbgl/sprite/sprite_loader.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <mbgl/actor/scheduler.hpp>
#include <mbgl/style/image.hpp>
#include <mbgl/style/sprite.hpp>
#include <mapbox/std/weak.hpp>
Expand All @@ -15,11 +16,10 @@ namespace mbgl {

class FileSource;
class SpriteLoaderObserver;
class Scheduler;

class SpriteLoader {
public:
SpriteLoader(float pixelRatio);
SpriteLoader(float pixelRatio, const TaggedScheduler& threadPool_);
~SpriteLoader();

void load(const std::optional<style::Sprite> sprite, FileSource&);
Expand All @@ -39,7 +39,7 @@ class SpriteLoader {
std::mutex dataMapMutex;

SpriteLoaderObserver* observer = nullptr;
std::shared_ptr<Scheduler> threadPool;
TaggedScheduler threadPool;
mapbox::base::WeakPtrFactory<SpriteLoader> weakFactory{this};
// Do not add members here, see `WeakPtrFactory`
};
Expand Down
4 changes: 2 additions & 2 deletions src/mbgl/style/sources/geojson_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <mbgl/util/async_request.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/thread_pool.hpp>
#include <mbgl/util/identity.hpp>

namespace mbgl {
namespace style {
Expand All @@ -21,7 +22,6 @@ Immutable<GeoJSONOptions> GeoJSONOptions::defaultOptions() {

GeoJSONSource::GeoJSONSource(std::string id, Immutable<GeoJSONOptions> options)
: Source(makeMutable<Impl>(std::move(id), std::move(options))),
threadPool(Scheduler::GetBackground()),
sequencedScheduler(Scheduler::GetSequenced()) {}

GeoJSONSource::~GeoJSONSource() = default;
Expand Down Expand Up @@ -102,7 +102,7 @@ void GeoJSONSource::loadDescription(FileSource& fileSource) {
loaded = true;
observer->onSourceLoaded(*this);
};
threadPool->scheduleAndReplyValue(makeImplInBackground, onImplReady);
threadPool->scheduleAndReplyValue(util::SimpleIdentity::Empty, makeImplInBackground, onImplReady);
}
});
}
Expand Down
16 changes: 9 additions & 7 deletions src/mbgl/style/sources/geojson_source_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <mbgl/util/feature.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/thread_pool.hpp>
#include <mbgl/util/identity.hpp>

#ifdef _MSC_VER
#pragma warning(push)
Expand All @@ -25,7 +26,8 @@ namespace style {
class GeoJSONVTData final : public GeoJSONData {
void getTile(const CanonicalTileID& id, const std::function<void(TileFeatures)>& fn) final {
assert(fn);
scheduler->scheduleAndReplyValue(
sequencedScheduler->scheduleAndReplyValue(
util::SimpleIdentity::Empty,
[id, geoJSONVT_impl = this->impl]() -> TileFeatures {
return geoJSONVT_impl->getTile(id.z, id.x, id.y).features;
},
Expand All @@ -41,14 +43,14 @@ class GeoJSONVTData final : public GeoJSONData {
friend GeoJSONData;
GeoJSONVTData(const GeoJSON& geoJSON,
const mapbox::geojsonvt::Options& options,
std::shared_ptr<Scheduler> scheduler_)
std::shared_ptr<Scheduler> sequencedScheduler_)
: impl(std::make_shared<mapbox::geojsonvt::GeoJSONVT>(geoJSON, options)),
scheduler(std::move(scheduler_)) {
assert(scheduler);
sequencedScheduler(std::move(sequencedScheduler_)) {
assert(sequencedScheduler);
}

std::shared_ptr<mapbox::geojsonvt::GeoJSONVT> impl; // Accessed on worker thread.
std::shared_ptr<Scheduler> scheduler;
std::shared_ptr<Scheduler> sequencedScheduler;
};

class SuperclusterData final : public GeoJSONData {
Expand Down Expand Up @@ -89,7 +91,7 @@ T evaluateFeature(const mapbox::feature::feature<double>& f,

// static
std::shared_ptr<GeoJSONData> GeoJSONData::create(const GeoJSON& geoJSON,
std::shared_ptr<Scheduler> scheduler,
std::shared_ptr<Scheduler> sequencedScheduler,
const Immutable<GeoJSONOptions>& options) {
constexpr double scale = util::EXTENT / util::tileSize_D;
if (options->cluster && geoJSON.is<Features>() && !geoJSON.get<Features>().empty()) {
Expand Down Expand Up @@ -126,7 +128,7 @@ std::shared_ptr<GeoJSONData> GeoJSONData::create(const GeoJSON& geoJSON,
vtOptions.buffer = static_cast<uint16_t>(::round(scale * options->buffer));
vtOptions.tolerance = scale * options->tolerance;
vtOptions.lineMetrics = options->lineMetrics;
return std::shared_ptr<GeoJSONData>(new GeoJSONVTData(geoJSON, vtOptions, std::move(scheduler)));
return std::shared_ptr<GeoJSONData>(new GeoJSONVTData(geoJSON, vtOptions, std::move(sequencedScheduler)));
}

GeoJSONSource::Impl::Impl(std::string id_, Immutable<GeoJSONOptions> options_)
Expand Down
4 changes: 2 additions & 2 deletions src/mbgl/style/style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
namespace mbgl {
namespace style {

Style::Style(std::shared_ptr<FileSource> fileSource, float pixelRatio)
: impl(std::make_unique<Impl>(std::move(fileSource), pixelRatio)) {}
Style::Style(std::shared_ptr<FileSource> fileSource, float pixelRatio, const TaggedScheduler& threadPool_)
: impl(std::make_unique<Impl>(std::move(fileSource), pixelRatio, threadPool_)) {}

Style::~Style() = default;

Expand Down
4 changes: 2 additions & 2 deletions src/mbgl/style/style_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ namespace style {

static Observer nullObserver;

Style::Impl::Impl(std::shared_ptr<FileSource> fileSource_, float pixelRatio)
Style::Impl::Impl(std::shared_ptr<FileSource> fileSource_, float pixelRatio, const TaggedScheduler& threadPool_)
: fileSource(std::move(fileSource_)),
spriteLoader(std::make_unique<SpriteLoader>(pixelRatio)),
spriteLoader(std::make_unique<SpriteLoader>(pixelRatio, threadPool_)),
light(std::make_unique<Light>()),
observer(&nullObserver) {
spriteLoader->setObserver(this);
Expand Down
Loading

0 comments on commit 0e97700

Please sign in to comment.