update linux-ci to Ubuntu 24.04, apply clang-tidy fixes (#3998)
This commit is contained in:
14
.clang-tidy
14
.clang-tidy
@@ -104,7 +104,7 @@ Checks: [
|
|||||||
-readability-redundant-member-init,
|
-readability-redundant-member-init,
|
||||||
-readability-redundant-string-init,
|
-readability-redundant-string-init,
|
||||||
-readability-simplify-boolean-expr,
|
-readability-simplify-boolean-expr,
|
||||||
-readability-static-accessed-through-instance
|
-readability-static-accessed-through-instance,
|
||||||
-readability-static-definition-in-anonymous-namespace,
|
-readability-static-definition-in-anonymous-namespace,
|
||||||
-readability-suspicious-call-argument,
|
-readability-suspicious-call-argument,
|
||||||
-readability-uppercase-literal-suffix,
|
-readability-uppercase-literal-suffix,
|
||||||
@@ -118,7 +118,17 @@ Checks: [
|
|||||||
-readability-enum-initial-value,
|
-readability-enum-initial-value,
|
||||||
-boost-use-ranges,
|
-boost-use-ranges,
|
||||||
-modernize-use-constraints,
|
-modernize-use-constraints,
|
||||||
-portability-template-virtual-member-function
|
-portability-template-virtual-member-function,
|
||||||
|
-portability-avoid-pragma-once,
|
||||||
|
-llvm-prefer-static-over-anonymous-namespace,
|
||||||
|
-readability-use-concise-preprocessor-directives,
|
||||||
|
-modernize-type-traits,
|
||||||
|
-misc-use-internal-linkage,
|
||||||
|
-modernize-use-ranges,
|
||||||
|
-modernize-use-integer-sign-comparison,
|
||||||
|
-clang-analyzer-core.CallAndMessage,
|
||||||
|
-clang-diagnostic-deprecated-declarations,
|
||||||
|
-clang-analyzer-security.ArrayBound
|
||||||
]
|
]
|
||||||
WarningsAsErrors: '*'
|
WarningsAsErrors: '*'
|
||||||
HeaderFilterRegex: '.*'
|
HeaderFilterRegex: '.*'
|
||||||
|
|||||||
2
.github/workflows/linux-ci.yml
vendored
2
.github/workflows/linux-ci.yml
vendored
@@ -29,7 +29,7 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre_job:
|
pre_job:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
outputs:
|
outputs:
|
||||||
should_skip: ${{ github.event_name != 'workflow_dispatch' && steps.changed-files.outputs.linux_any_modified != 'true' }}
|
should_skip: ${{ github.event_name != 'workflow_dispatch' && steps.changed-files.outputs.linux_any_modified != 'true' }}
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -51,14 +51,16 @@ public:
|
|||||||
|
|
||||||
// Construct the `Object` from a tuple containing the constructor arguments
|
// Construct the `Object` from a tuple containing the constructor arguments
|
||||||
// (i.e. `Object(std::get<0>(args), std::get<1>(args), ...)`)
|
// (i.e. `Object(std::get<0>(args), std::get<1>(args), ...)`)
|
||||||
template <class ArgsTuple, std::size_t ArgCount = std::tuple_size<std::decay_t<ArgsTuple>>::value>
|
template <class ArgsTuple,
|
||||||
|
std::size_t ArgCount = std::tuple_size<std::decay_t<ArgsTuple>>::value> // NOLINT(modernize-type-traits)
|
||||||
EstablishedActor(Scheduler& scheduler, AspiringActor<Object>& parent_, ArgsTuple&& args)
|
EstablishedActor(Scheduler& scheduler, AspiringActor<Object>& parent_, ArgsTuple&& args)
|
||||||
: parent(parent_) {
|
: parent(parent_) {
|
||||||
emplaceObject(std::forward<ArgsTuple>(args), std::make_index_sequence<ArgCount>{});
|
emplaceObject(std::forward<ArgsTuple>(args), std::make_index_sequence<ArgCount>{});
|
||||||
parent.mailbox->open(scheduler);
|
parent.mailbox->open(scheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ArgsTuple, std::size_t ArgCount = std::tuple_size<std::decay_t<ArgsTuple>>::value>
|
template <class ArgsTuple,
|
||||||
|
std::size_t ArgCount = std::tuple_size<std::decay_t<ArgsTuple>>::value> // NOLINT(modernize-type-traits)
|
||||||
EstablishedActor(const TaggedScheduler& scheduler, AspiringActor<Object>& parent_, ArgsTuple&& args) {
|
EstablishedActor(const TaggedScheduler& scheduler, AspiringActor<Object>& parent_, ArgsTuple&& args) {
|
||||||
EstablishedActor(*scheduler.get(), parent_, std::forward<ArgsTuple>(args));
|
EstablishedActor(*scheduler.get(), parent_, std::forward<ArgsTuple>(args));
|
||||||
}
|
}
|
||||||
@@ -98,7 +100,7 @@ private:
|
|||||||
// Used to expand a tuple holding the constructor arguments
|
// Used to expand a tuple holding the constructor arguments
|
||||||
template <class ArgsTuple, std::size_t... I>
|
template <class ArgsTuple, std::size_t... I>
|
||||||
void emplaceObject(ArgsTuple&& args, std::index_sequence<I...>) {
|
void emplaceObject(ArgsTuple&& args, std::index_sequence<I...>) {
|
||||||
emplaceObject(std::move(std::get<I>(std::forward<ArgsTuple>(args)))...);
|
emplaceObject(std::move(std::get<I>(std::forward<ArgsTuple>(args)))...); // NOLINT(bugprone-use-after-move)
|
||||||
(void)args; // mark args as used: if it's empty tuple, it's not actually used above.
|
(void)args; // mark args as used: if it's empty tuple, it's not actually used above.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public:
|
|||||||
gfx::RenderingStats& renderingStats() { return stats; }
|
gfx::RenderingStats& renderingStats() { return stats; }
|
||||||
const gfx::RenderingStats& renderingStats() const { return stats; }
|
const gfx::RenderingStats& renderingStats() const { return stats; }
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#ifndef NDEBUG
|
||||||
virtual void visualizeStencilBuffer() = 0;
|
virtual void visualizeStencilBuffer() = 0;
|
||||||
virtual void visualizeDepthBuffer(float depthRangeSize) = 0;
|
virtual void visualizeDepthBuffer(float depthRangeSize) = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ struct RenderingStats {
|
|||||||
|
|
||||||
RenderingStats& operator+=(const RenderingStats&);
|
RenderingStats& operator+=(const RenderingStats&);
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#ifndef NDEBUG
|
||||||
std::string toString(std::string_view separator) const;
|
std::string toString(std::string_view separator) const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -126,10 +126,10 @@ public:
|
|||||||
const gfx::StencilMode&,
|
const gfx::StencilMode&,
|
||||||
const gfx::Renderable&) const;
|
const gfx::Renderable&) const;
|
||||||
|
|
||||||
virtual bool emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr&,
|
bool emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr&,
|
||||||
const void* data,
|
const void* data,
|
||||||
std::size_t size,
|
std::size_t size,
|
||||||
bool persistent) override;
|
bool persistent) override;
|
||||||
|
|
||||||
/// Get a reusable buffer containing the standard fixed tile vertices (+/- `util::EXTENT`)
|
/// Get a reusable buffer containing the standard fixed tile vertices (+/- `util::EXTENT`)
|
||||||
const BufferResource& getTileVertexBuffer();
|
const BufferResource& getTileVertexBuffer();
|
||||||
|
|||||||
@@ -49,16 +49,17 @@ std::enable_if_t<std::is_integral_v<T>, std::optional<T>> parse(std::string_view
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
if constexpr (std::is_same_v<T, int32_t>) {
|
if constexpr (std::is_same_v<T, int32_t>) {
|
||||||
long val = std::strtol(str.data(), &end, base);
|
long val = std::strtol(str.data(), &end, base); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
if (errno == 0 && end == str.data() + str.size()) return static_cast<T>(val);
|
if (errno == 0 && end == str.data() + str.size()) return static_cast<T>(val);
|
||||||
} else if constexpr (std::is_same_v<T, uint32_t>) {
|
} else if constexpr (std::is_same_v<T, uint32_t>) {
|
||||||
unsigned long val = std::strtoul(str.data(), &end, base);
|
unsigned long val = std::strtoul(str.data(), &end, base); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
if (errno == 0 && end == str.data() + str.size()) return static_cast<T>(val);
|
if (errno == 0 && end == str.data() + str.size()) return static_cast<T>(val);
|
||||||
} else if constexpr (std::is_same_v<T, int64_t>) {
|
} else if constexpr (std::is_same_v<T, int64_t>) {
|
||||||
long long val = std::strtoll(str.data(), &end, base);
|
long long val = std::strtoll(str.data(), &end, base); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
if (errno == 0 && end == str.data() + str.size()) return static_cast<T>(val);
|
if (errno == 0 && end == str.data() + str.size()) return static_cast<T>(val);
|
||||||
} else if constexpr (std::is_same_v<T, uint64_t>) {
|
} else if constexpr (std::is_same_v<T, uint64_t>) {
|
||||||
unsigned long long val = std::strtoull(str.data(), &end, base);
|
unsigned long long val = std::strtoull(
|
||||||
|
str.data(), &end, base); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
if (errno == 0 && end == str.data() + str.size()) return static_cast<T>(val);
|
if (errno == 0 && end == str.data() + str.size()) return static_cast<T>(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,13 +75,13 @@ std::enable_if_t<std::is_floating_point_v<T>, std::optional<T>> parse(std::strin
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
if constexpr (std::is_same_v<T, float>) {
|
if constexpr (std::is_same_v<T, float>) {
|
||||||
float val = std::strtof(str.data(), &end);
|
float val = std::strtof(str.data(), &end); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
if (errno == 0 && end == str.data() + str.size()) return val;
|
if (errno == 0 && end == str.data() + str.size()) return val;
|
||||||
} else if constexpr (std::is_same_v<T, double>) {
|
} else if constexpr (std::is_same_v<T, double>) {
|
||||||
double val = std::strtod(str.data(), &end);
|
double val = std::strtod(str.data(), &end); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
if (errno == 0 && end == str.data() + str.size()) return val;
|
if (errno == 0 && end == str.data() + str.size()) return val;
|
||||||
} else if constexpr (std::is_same_v<T, long double>) {
|
} else if constexpr (std::is_same_v<T, long double>) {
|
||||||
long double val = std::strtold(str.data(), &end);
|
long double val = std::strtold(str.data(), &end); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
if (errno == 0 && end == str.data() + str.size()) return val;
|
if (errno == 0 && end == str.data() + str.size()) return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ private:
|
|||||||
|
|
||||||
// Adds a WorkTask to the queue, and wakes it up.
|
// Adds a WorkTask to the queue, and wakes it up.
|
||||||
void push(Priority priority, std::shared_ptr<WorkTask> task) {
|
void push(Priority priority, std::shared_ptr<WorkTask> task) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
if (priority == Priority::High) {
|
if (priority == Priority::High) {
|
||||||
highPriorityQueue.emplace(std::move(task));
|
highPriorityQueue.emplace(std::move(task));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// will be defined as hidden by default.
|
// will be defined as hidden by default.
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#if defined WIN32
|
#ifdef WIN32
|
||||||
#ifdef MBGL_BUILDING_LIB
|
#ifdef MBGL_BUILDING_LIB
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define MBGL_EXPORT __attribute__((dllexport))
|
#define MBGL_EXPORT __attribute__((dllexport))
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
|
|
||||||
void operator()() override {
|
void operator()() override {
|
||||||
// Lock the mutex while processing so that cancel() will block.
|
// Lock the mutex while processing so that cancel() will block.
|
||||||
std::lock_guard<std::recursive_mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
if (!canceled->load(std::memory_order_acquire)) {
|
if (!canceled->load(std::memory_order_acquire)) {
|
||||||
invoke(std::make_index_sequence<std::tuple_size_v<P>>{});
|
invoke(std::make_index_sequence<std::tuple_size_v<P>>{});
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
/// If the task has completed and the after callback has executed, this will
|
/// If the task has completed and the after callback has executed, this will
|
||||||
/// do nothing.
|
/// do nothing.
|
||||||
void cancel() override {
|
void cancel() override {
|
||||||
std::lock_guard<std::recursive_mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
canceled->store(true, std::memory_order_release);
|
canceled->store(true, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ void MapRenderer::reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Lock to make sure there is no concurrent initialisation on the gl thread
|
// Lock to make sure there is no concurrent initialisation on the gl thread
|
||||||
std::lock_guard<std::mutex> lock(initialisationMutex);
|
std::scoped_lock lock(initialisationMutex);
|
||||||
rendererObserver.reset();
|
rendererObserver.reset();
|
||||||
} catch (const std::exception& exception) {
|
} catch (const std::exception& exception) {
|
||||||
Log::Error(Event::Android, std::string("MapRenderer::reset failed: ") + exception.what());
|
Log::Error(Event::Android, std::string("MapRenderer::reset failed: ") + exception.what());
|
||||||
@@ -153,7 +153,7 @@ void MapRenderer::requestRender(JNIEnv& env, jni::Local<jni::Object<MapRenderer>
|
|||||||
void MapRenderer::update(std::shared_ptr<UpdateParameters> params) {
|
void MapRenderer::update(std::shared_ptr<UpdateParameters> params) {
|
||||||
try {
|
try {
|
||||||
// Lock on the parameters
|
// Lock on the parameters
|
||||||
std::lock_guard<std::mutex> lock(updateMutex);
|
std::scoped_lock lock(updateMutex);
|
||||||
updateParameters = std::move(params);
|
updateParameters = std::move(params);
|
||||||
} catch (const std::exception& exception) {
|
} catch (const std::exception& exception) {
|
||||||
Log::Error(Event::Android, std::string("MapRenderer::update failed: ") + exception.what());
|
Log::Error(Event::Android, std::string("MapRenderer::update failed: ") + exception.what());
|
||||||
@@ -163,7 +163,7 @@ void MapRenderer::update(std::shared_ptr<UpdateParameters> params) {
|
|||||||
void MapRenderer::setObserver(std::shared_ptr<RendererObserver> _rendererObserver) {
|
void MapRenderer::setObserver(std::shared_ptr<RendererObserver> _rendererObserver) {
|
||||||
try {
|
try {
|
||||||
// Lock as the initialization can come from the main thread or the GL thread first
|
// Lock as the initialization can come from the main thread or the GL thread first
|
||||||
std::lock_guard<std::mutex> lock(initialisationMutex);
|
std::scoped_lock lock(initialisationMutex);
|
||||||
|
|
||||||
rendererObserver = std::move(_rendererObserver);
|
rendererObserver = std::move(_rendererObserver);
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ void MapRenderer::render(JNIEnv&) {
|
|||||||
|
|
||||||
void MapRenderer::onSurfaceCreated(JNIEnv& env, const jni::Object<AndroidSurface>& surface) {
|
void MapRenderer::onSurfaceCreated(JNIEnv& env, const jni::Object<AndroidSurface>& surface) {
|
||||||
// Lock as the initialization can come from the main thread or the GL thread first
|
// Lock as the initialization can come from the main thread or the GL thread first
|
||||||
std::lock_guard<std::mutex> lock(initialisationMutex);
|
std::scoped_lock lock(initialisationMutex);
|
||||||
|
|
||||||
// The android system will have already destroyed the underlying
|
// The android system will have already destroyed the underlying
|
||||||
// GL resources if this is not the first initialization and an
|
// GL resources if this is not the first initialization and an
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ void RunLoop::Impl::wake() {
|
|||||||
|
|
||||||
void RunLoop::Impl::addRunnable(Runnable* runnable) {
|
void RunLoop::Impl::addRunnable(Runnable* runnable) {
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
runnables.push_back(runnable);
|
runnables.push_back(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ void RunLoop::Impl::addRunnable(Runnable* runnable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RunLoop::Impl::removeRunnable(Runnable* runnable) {
|
void RunLoop::Impl::removeRunnable(Runnable* runnable) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
runnables.remove(runnable);
|
runnables.remove(runnable);
|
||||||
if (runnables.empty()) {
|
if (runnables.empty()) {
|
||||||
cvEmpty.notify_all();
|
cvEmpty.notify_all();
|
||||||
@@ -178,7 +178,7 @@ Milliseconds RunLoop::Impl::processRunnables() {
|
|||||||
auto nextDue = TimePoint::max();
|
auto nextDue = TimePoint::max();
|
||||||
std::list<Runnable*> tmp;
|
std::list<Runnable*> tmp;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
|
|
||||||
// O(N) but in the render thread where we get tons
|
// O(N) but in the render thread where we get tons
|
||||||
// of messages, the size of the list is usually 1~2.
|
// of messages, the size of the list is usually 1~2.
|
||||||
@@ -220,7 +220,7 @@ void RunLoop::Impl::waitForEmpty() {
|
|||||||
while (true) {
|
while (true) {
|
||||||
std::size_t remaining;
|
std::size_t remaining;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
remaining = runnables.size();
|
remaining = runnables.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void notify(const Response& response_) {
|
void notify(const Response& response_) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
response = response_;
|
response = response_;
|
||||||
async.send();
|
async.send();
|
||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cancel() {
|
void cancel() {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ void RunLoop::waitForEmpty([[maybe_unused]] const SimpleIdentity tag) {
|
|||||||
while (true) {
|
while (true) {
|
||||||
std::size_t remaining;
|
std::size_t remaining;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
remaining = defaultQueue.size() + highPriorityQueue.size();
|
remaining = defaultQueue.size() + highPriorityQueue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,22 +42,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setResourceOptions(ResourceOptions options) {
|
void setResourceOptions(ResourceOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
resourceOptions = options;
|
resourceOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceOptions getResourceOptions() {
|
ResourceOptions getResourceOptions() {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return resourceOptions.clone();
|
return resourceOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClientOptions(ClientOptions options) {
|
void setClientOptions(ClientOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
clientOptions = options;
|
clientOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientOptions getClientOptions() {
|
ClientOptions getClientOptions() {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
return clientOptions.clone();
|
return clientOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,22 +176,22 @@ public:
|
|||||||
void resume() { thread->resume(); }
|
void resume() { thread->resume(); }
|
||||||
|
|
||||||
void setResourceOptions(ResourceOptions options) {
|
void setResourceOptions(ResourceOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
resourceOptions = options;
|
resourceOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceOptions getResourceOptions() {
|
ResourceOptions getResourceOptions() {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return resourceOptions.clone();
|
return resourceOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClientOptions(ClientOptions options) {
|
void setClientOptions(ClientOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
clientOptions = options;
|
clientOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientOptions getClientOptions() {
|
ClientOptions getClientOptions() {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
return clientOptions.clone();
|
return clientOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -245,22 +245,22 @@ int HTTPFileSource::Impl::startTimeout(CURLM * /* multi */, long timeout_ms, voi
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HTTPFileSource::Impl::setResourceOptions(ResourceOptions options) {
|
void HTTPFileSource::Impl::setResourceOptions(ResourceOptions options) {
|
||||||
std::lock_guard lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
resourceOptions = options;
|
resourceOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceOptions HTTPFileSource::Impl::getResourceOptions() {
|
ResourceOptions HTTPFileSource::Impl::getResourceOptions() {
|
||||||
std::lock_guard lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return resourceOptions.clone();
|
return resourceOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPFileSource::Impl::setClientOptions(ClientOptions options) {
|
void HTTPFileSource::Impl::setClientOptions(ClientOptions options) {
|
||||||
std::lock_guard lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
clientOptions = options;
|
clientOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientOptions HTTPFileSource::Impl::getClientOptions() {
|
ClientOptions HTTPFileSource::Impl::getClientOptions() {
|
||||||
std::lock_guard lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
return clientOptions.clone();
|
return clientOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,22 +40,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setResourceOptions(ResourceOptions options) {
|
void setResourceOptions(ResourceOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
resourceOptions = options;
|
resourceOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceOptions getResourceOptions() {
|
ResourceOptions getResourceOptions() {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return resourceOptions.clone();
|
return resourceOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClientOptions(ClientOptions options) {
|
void setClientOptions(ClientOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
clientOptions = options;
|
clientOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientOptions getClientOptions() {
|
ClientOptions getClientOptions() {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
return clientOptions.clone();
|
return clientOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ public:
|
|||||||
void resume() { thread->resume(); }
|
void resume() { thread->resume(); }
|
||||||
|
|
||||||
void setResourceOptions(ResourceOptions options) {
|
void setResourceOptions(ResourceOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
resourceOptions = options;
|
resourceOptions = options;
|
||||||
assetFileSource->setResourceOptions(options.clone());
|
assetFileSource->setResourceOptions(options.clone());
|
||||||
databaseFileSource->setResourceOptions(options.clone());
|
databaseFileSource->setResourceOptions(options.clone());
|
||||||
@@ -206,12 +206,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ResourceOptions getResourceOptions() {
|
ResourceOptions getResourceOptions() {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return resourceOptions.clone();
|
return resourceOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClientOptions(ClientOptions options) {
|
void setClientOptions(ClientOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
clientOptions = options;
|
clientOptions = options;
|
||||||
assetFileSource->setClientOptions(options.clone());
|
assetFileSource->setClientOptions(options.clone());
|
||||||
databaseFileSource->setClientOptions(options.clone());
|
databaseFileSource->setClientOptions(options.clone());
|
||||||
@@ -222,7 +222,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClientOptions getClientOptions() {
|
ClientOptions getClientOptions() {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
return clientOptions.clone();
|
return clientOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -223,22 +223,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setResourceOptions(ResourceOptions options) {
|
void setResourceOptions(ResourceOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
resourceOptions = options;
|
resourceOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceOptions getResourceOptions() {
|
ResourceOptions getResourceOptions() {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return resourceOptions.clone();
|
return resourceOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClientOptions(ClientOptions options) {
|
void setClientOptions(ClientOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
clientOptions = options;
|
clientOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientOptions getClientOptions() {
|
ClientOptions getClientOptions() {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
return clientOptions.clone();
|
return clientOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,8 +124,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void activateOrQueueRequest(OnlineFileRequest* req) {
|
void activateOrQueueRequest(OnlineFileRequest* req) {
|
||||||
assert(allRequests.find(req) != allRequests.end());
|
assert(allRequests.contains(req));
|
||||||
assert(activeRequests.find(req) == activeRequests.end());
|
assert(!activeRequests.contains(req));
|
||||||
assert(!req->request);
|
assert(!req->request);
|
||||||
|
|
||||||
if (activeRequests.size() >= getMaximumConcurrentRequests()) {
|
if (activeRequests.size() >= getMaximumConcurrentRequests()) {
|
||||||
@@ -167,7 +167,7 @@ public:
|
|||||||
|
|
||||||
bool isPending(OnlineFileRequest* req) { return pendingRequests.contains(req); }
|
bool isPending(OnlineFileRequest* req) { return pendingRequests.contains(req); }
|
||||||
|
|
||||||
bool isActive(OnlineFileRequest* req) { return activeRequests.find(req) != activeRequests.end(); }
|
bool isActive(OnlineFileRequest* req) { return activeRequests.contains(req); }
|
||||||
|
|
||||||
void setResourceTransform(ResourceTransform transform) { resourceTransform = std::move(transform); }
|
void setResourceTransform(ResourceTransform transform) { resourceTransform = std::move(transform); }
|
||||||
|
|
||||||
@@ -339,26 +339,26 @@ public:
|
|||||||
void setResourceOptions(ResourceOptions options) {
|
void setResourceOptions(ResourceOptions options) {
|
||||||
thread->actor().invoke(&OnlineFileSourceThread::setResourceOptions, options.clone());
|
thread->actor().invoke(&OnlineFileSourceThread::setResourceOptions, options.clone());
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
cachedResourceOptions = options;
|
cachedResourceOptions = options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceOptions getResourceOptions() {
|
ResourceOptions getResourceOptions() {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return cachedResourceOptions.clone();
|
return cachedResourceOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClientOptions(ClientOptions options) {
|
void setClientOptions(ClientOptions options) {
|
||||||
thread->actor().invoke(&OnlineFileSourceThread::setClientOptions, options.clone());
|
thread->actor().invoke(&OnlineFileSourceThread::setClientOptions, options.clone());
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
cachedClientOptions = options;
|
cachedClientOptions = options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientOptions getClientOptions() {
|
ClientOptions getClientOptions() {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
return cachedClientOptions.clone();
|
return cachedClientOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ public:
|
|||||||
const auto maxConcurrentRequests = static_cast<uint32_t>(*maximumConcurrentRequests);
|
const auto maxConcurrentRequests = static_cast<uint32_t>(*maximumConcurrentRequests);
|
||||||
thread->actor().invoke(&OnlineFileSourceThread::setMaximumConcurrentRequests, maxConcurrentRequests);
|
thread->actor().invoke(&OnlineFileSourceThread::setMaximumConcurrentRequests, maxConcurrentRequests);
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(maximumConcurrentRequestsMutex);
|
std::scoped_lock lock(maximumConcurrentRequestsMutex);
|
||||||
cachedMaximumConcurrentRequests = maxConcurrentRequests;
|
cachedMaximumConcurrentRequests = maxConcurrentRequests;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -379,7 +379,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getMaximumConcurrentRequests() const {
|
uint32_t getMaximumConcurrentRequests() const {
|
||||||
std::lock_guard<std::mutex> lock(maximumConcurrentRequestsMutex);
|
std::scoped_lock lock(maximumConcurrentRequestsMutex);
|
||||||
return cachedMaximumConcurrentRequests;
|
return cachedMaximumConcurrentRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ public:
|
|||||||
if (auto* apiKey = value.getString()) {
|
if (auto* apiKey = value.getString()) {
|
||||||
thread->actor().invoke(&OnlineFileSourceThread::setApiKey, *apiKey);
|
thread->actor().invoke(&OnlineFileSourceThread::setApiKey, *apiKey);
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
cachedResourceOptions.withApiKey(*apiKey);
|
cachedResourceOptions.withApiKey(*apiKey);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -396,7 +396,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string getApiKey() const {
|
std::string getApiKey() const {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return cachedResourceOptions.apiKey();
|
return cachedResourceOptions.apiKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,7 +404,7 @@ public:
|
|||||||
if (auto* baseURL = value.getString()) {
|
if (auto* baseURL = value.getString()) {
|
||||||
thread->actor().invoke(&OnlineFileSourceThread::setAPIBaseURL, *baseURL);
|
thread->actor().invoke(&OnlineFileSourceThread::setAPIBaseURL, *baseURL);
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
cachedResourceOptions.withTileServerOptions(
|
cachedResourceOptions.withTileServerOptions(
|
||||||
cachedResourceOptions.tileServerOptions().clone().withBaseURL(*baseURL));
|
cachedResourceOptions.tileServerOptions().clone().withBaseURL(*baseURL));
|
||||||
}
|
}
|
||||||
@@ -414,7 +414,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string getAPIBaseURL() const {
|
std::string getAPIBaseURL() const {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return cachedResourceOptions.tileServerOptions().baseURL();
|
return cachedResourceOptions.tileServerOptions().baseURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,22 +177,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setResourceOptions(ResourceOptions options) {
|
void setResourceOptions(ResourceOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
resourceOptions = options;
|
resourceOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceOptions getResourceOptions() {
|
ResourceOptions getResourceOptions() {
|
||||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
std::scoped_lock lock(resourceOptionsMutex);
|
||||||
return resourceOptions.clone();
|
return resourceOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClientOptions(ClientOptions options) {
|
void setClientOptions(ClientOptions options) {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
clientOptions = options;
|
clientOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientOptions getClientOptions() {
|
ClientOptions getClientOptions() {
|
||||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
std::scoped_lock lock(clientOptionsMutex);
|
||||||
return clientOptions.clone();
|
return clientOptions.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void getHeader(const std::string& url, AsyncRequest* req, AsyncCallback callback) {
|
void getHeader(const std::string& url, AsyncRequest* req, AsyncCallback callback) {
|
||||||
if (header_cache.find(url) != header_cache.end()) {
|
if (header_cache.contains(url)) {
|
||||||
callback(std::unique_ptr<Response::Error>());
|
callback(std::unique_ptr<Response::Error>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,191 +229,197 @@ private:
|
|||||||
resource.dataRange = std::make_pair<uint64_t, uint64_t>(pmtilesHeaderOffset,
|
resource.dataRange = std::make_pair<uint64_t, uint64_t>(pmtilesHeaderOffset,
|
||||||
pmtilesHeaderOffset + pmtilesHeaderLength - 1);
|
pmtilesHeaderOffset + pmtilesHeaderLength - 1);
|
||||||
|
|
||||||
tasks[req] = getFileSource()->request(resource, [=, this](const Response& response) {
|
tasks[req] = getFileSource()->request(
|
||||||
if (response.error) {
|
resource, [=, this](const Response& response) { // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
std::string message = std::string("Error fetching PMTiles header: ") + response.error->message;
|
if (response.error) {
|
||||||
|
std::string message = std::string("Error fetching PMTiles header: ") + response.error->message;
|
||||||
|
|
||||||
if (response.error->message.empty() && response.error->reason == Response::Error::Reason::NotFound) {
|
if (response.error->message.empty() &&
|
||||||
if (url.starts_with(mbgl::util::FILE_PROTOCOL)) {
|
response.error->reason == Response::Error::Reason::NotFound) {
|
||||||
message += "path not found: " +
|
if (url.starts_with(mbgl::util::FILE_PROTOCOL)) {
|
||||||
url.substr(std::char_traits<char>::length(mbgl::util::FILE_PROTOCOL));
|
message += "path not found: " +
|
||||||
} else {
|
url.substr(std::char_traits<char>::length(mbgl::util::FILE_PROTOCOL));
|
||||||
message += "url not found: " + url;
|
} else {
|
||||||
|
message += "url not found: " + url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(std::make_unique<Response::Error>(response.error->reason, message));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(std::make_unique<Response::Error>(response.error->reason, message));
|
try {
|
||||||
|
pmtiles::headerv3 header = pmtiles::deserialize_header(response.data->substr(0, 127));
|
||||||
|
|
||||||
return;
|
if ((header.internal_compression != pmtiles::COMPRESSION_NONE &&
|
||||||
}
|
header.internal_compression != pmtiles::COMPRESSION_GZIP) ||
|
||||||
|
(header.tile_compression != pmtiles::COMPRESSION_NONE &&
|
||||||
|
header.tile_compression != pmtiles::COMPRESSION_GZIP)) {
|
||||||
|
throw std::runtime_error("Compression method not supported");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
header_cache.emplace(url, header);
|
||||||
pmtiles::headerv3 header = pmtiles::deserialize_header(response.data->substr(0, 127));
|
|
||||||
|
|
||||||
if ((header.internal_compression != pmtiles::COMPRESSION_NONE &&
|
callback(std::unique_ptr<Response::Error>());
|
||||||
header.internal_compression != pmtiles::COMPRESSION_GZIP) ||
|
} catch (const std::exception& e) {
|
||||||
(header.tile_compression != pmtiles::COMPRESSION_NONE &&
|
callback(std::make_unique<Response::Error>(
|
||||||
header.tile_compression != pmtiles::COMPRESSION_GZIP)) {
|
Response::Error::Reason::Other, std::string("Error parsing PMTiles header: ") + e.what()));
|
||||||
throw std::runtime_error("Compression method not supported");
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
header_cache.emplace(url, header);
|
|
||||||
|
|
||||||
callback(std::unique_ptr<Response::Error>());
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
callback(std::make_unique<Response::Error>(Response::Error::Reason::Other,
|
|
||||||
std::string("Error parsing PMTiles header: ") + e.what()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void getMetadata(std::string& url, AsyncRequest* req, AsyncCallback callback) {
|
void getMetadata(std::string& url, AsyncRequest* req, AsyncCallback callback) {
|
||||||
if (metadata_cache.find(url) != metadata_cache.end()) {
|
if (metadata_cache.contains(url)) {
|
||||||
callback(std::unique_ptr<Response::Error>());
|
callback(std::unique_ptr<Response::Error>());
|
||||||
}
|
}
|
||||||
|
|
||||||
getHeader(url, req, [=, this](std::unique_ptr<Response::Error> error) {
|
getHeader(
|
||||||
if (error) {
|
url,
|
||||||
callback(std::move(error));
|
req,
|
||||||
return;
|
[=, this](std::unique_ptr<Response::Error> error) { // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
}
|
if (error) {
|
||||||
|
callback(std::move(error));
|
||||||
pmtiles::headerv3 header = header_cache.at(url);
|
return;
|
||||||
|
|
||||||
auto parse_callback = [=, this](const std::string& data) {
|
|
||||||
Document doc;
|
|
||||||
|
|
||||||
auto& allocator = doc.GetAllocator();
|
|
||||||
|
|
||||||
if (!data.empty()) {
|
|
||||||
doc.Parse(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!doc.IsObject()) {
|
pmtiles::headerv3 header = header_cache.at(url);
|
||||||
doc.SetObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
doc.AddMember("tilejson", "3.0.0", allocator);
|
auto parse_callback = [=, this](const std::string& data) {
|
||||||
|
Document doc;
|
||||||
|
|
||||||
if (!doc.HasMember("scheme")) {
|
auto& allocator = doc.GetAllocator();
|
||||||
doc.AddMember("scheme", rapidjson::Value(), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
doc["scheme"] = rapidjson::Value().SetString("xyz");
|
if (!data.empty()) {
|
||||||
|
doc.Parse(data);
|
||||||
if (!doc.HasMember("tiles")) {
|
|
||||||
doc.AddMember("tiles", rapidjson::Value(), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doc["tiles"].IsArray()) {
|
|
||||||
doc["tiles"] = rapidjson::Value().SetArray().PushBack(
|
|
||||||
rapidjson::Value().SetString(std::string(util::PMTILES_PROTOCOL + url), allocator), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate tile type field to source encoding.
|
|
||||||
if (header.tile_type == pmtiles::TILETYPE_MLT) {
|
|
||||||
doc.AddMember("encoding", "mlt", allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doc.HasMember("bounds")) {
|
|
||||||
doc.AddMember("bounds", rapidjson::Value(), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doc["bounds"].IsArray()) {
|
|
||||||
doc["bounds"] = rapidjson::Value()
|
|
||||||
.SetArray()
|
|
||||||
.PushBack(static_cast<double>(header.min_lon_e7) / 1e7, allocator)
|
|
||||||
.PushBack(static_cast<double>(header.min_lat_e7) / 1e7, allocator)
|
|
||||||
.PushBack(static_cast<double>(header.max_lon_e7) / 1e7, allocator)
|
|
||||||
.PushBack(static_cast<double>(header.max_lat_e7) / 1e7, allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doc.HasMember("center")) {
|
|
||||||
doc.AddMember("center", rapidjson::Value(), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doc["center"].IsArray()) {
|
|
||||||
doc["center"] = rapidjson::Value()
|
|
||||||
.SetArray()
|
|
||||||
.PushBack(static_cast<double>(header.center_lon_e7) / 1e7, allocator)
|
|
||||||
.PushBack(static_cast<double>(header.center_lat_e7) / 1e7, allocator)
|
|
||||||
.PushBack(header.center_zoom, allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doc.HasMember("minzoom")) {
|
|
||||||
doc.AddMember("minzoom", rapidjson::Value(), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& minzoom = doc["minzoom"];
|
|
||||||
|
|
||||||
if (minzoom.IsString()) {
|
|
||||||
minzoom.SetInt(std::atoi(minzoom.GetString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!minzoom.IsNumber()) {
|
|
||||||
minzoom = rapidjson::Value().SetUint(header.min_zoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
doc["minzoom"] = minzoom;
|
|
||||||
|
|
||||||
if (!doc.HasMember("maxzoom")) {
|
|
||||||
doc.AddMember("maxzoom", rapidjson::Value(), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& maxzoom = doc["maxzoom"];
|
|
||||||
|
|
||||||
if (maxzoom.IsString()) {
|
|
||||||
maxzoom.SetInt(std::atoi(maxzoom.GetString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!maxzoom.IsNumber()) {
|
|
||||||
maxzoom = rapidjson::Value().SetUint(header.max_zoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
doc["maxzoom"] = maxzoom;
|
|
||||||
|
|
||||||
std::string metadata = serialize(doc);
|
|
||||||
metadata_cache.emplace(url, metadata);
|
|
||||||
|
|
||||||
callback(std::unique_ptr<Response::Error>());
|
|
||||||
};
|
|
||||||
|
|
||||||
if (header.json_metadata_bytes > 0) {
|
|
||||||
Resource resource(Resource::Kind::Source, url);
|
|
||||||
resource.loadingMethod = Resource::LoadingMethod::Network;
|
|
||||||
resource.dataRange = std::make_pair(header.json_metadata_offset,
|
|
||||||
header.json_metadata_offset + header.json_metadata_bytes - 1);
|
|
||||||
|
|
||||||
tasks[req] = getFileSource()->request(resource, [=](const Response& responseMetadata) {
|
|
||||||
if (responseMetadata.error) {
|
|
||||||
callback(std::make_unique<Response::Error>(
|
|
||||||
responseMetadata.error->reason,
|
|
||||||
std::string("Error fetching PMTiles metadata: ") + responseMetadata.error->message));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string data = *responseMetadata.data;
|
if (!doc.IsObject()) {
|
||||||
|
doc.SetObject();
|
||||||
if (header.internal_compression == pmtiles::COMPRESSION_GZIP) {
|
|
||||||
data = util::decompress(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_callback(data);
|
doc.AddMember("tilejson", "3.0.0", allocator);
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
if (!doc.HasMember("scheme")) {
|
||||||
}
|
doc.AddMember("scheme", rapidjson::Value(), allocator);
|
||||||
|
}
|
||||||
|
|
||||||
parse_callback(std::string());
|
doc["scheme"] = rapidjson::Value().SetString("xyz");
|
||||||
});
|
|
||||||
|
if (!doc.HasMember("tiles")) {
|
||||||
|
doc.AddMember("tiles", rapidjson::Value(), allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc["tiles"].IsArray()) {
|
||||||
|
doc["tiles"] = rapidjson::Value().SetArray().PushBack(
|
||||||
|
rapidjson::Value().SetString(std::string(util::PMTILES_PROTOCOL + url), allocator),
|
||||||
|
allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate tile type field to source encoding.
|
||||||
|
if (header.tile_type == pmtiles::TILETYPE_MLT) {
|
||||||
|
doc.AddMember("encoding", "mlt", allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc.HasMember("bounds")) {
|
||||||
|
doc.AddMember("bounds", rapidjson::Value(), allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc["bounds"].IsArray()) {
|
||||||
|
doc["bounds"] = rapidjson::Value()
|
||||||
|
.SetArray()
|
||||||
|
.PushBack(static_cast<double>(header.min_lon_e7) / 1e7, allocator)
|
||||||
|
.PushBack(static_cast<double>(header.min_lat_e7) / 1e7, allocator)
|
||||||
|
.PushBack(static_cast<double>(header.max_lon_e7) / 1e7, allocator)
|
||||||
|
.PushBack(static_cast<double>(header.max_lat_e7) / 1e7, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc.HasMember("center")) {
|
||||||
|
doc.AddMember("center", rapidjson::Value(), allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc["center"].IsArray()) {
|
||||||
|
doc["center"] = rapidjson::Value()
|
||||||
|
.SetArray()
|
||||||
|
.PushBack(static_cast<double>(header.center_lon_e7) / 1e7, allocator)
|
||||||
|
.PushBack(static_cast<double>(header.center_lat_e7) / 1e7, allocator)
|
||||||
|
.PushBack(header.center_zoom, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc.HasMember("minzoom")) {
|
||||||
|
doc.AddMember("minzoom", rapidjson::Value(), allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& minzoom = doc["minzoom"];
|
||||||
|
|
||||||
|
if (minzoom.IsString()) {
|
||||||
|
minzoom.SetInt(std::atoi(minzoom.GetString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!minzoom.IsNumber()) {
|
||||||
|
minzoom = rapidjson::Value().SetUint(header.min_zoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
doc["minzoom"] = minzoom;
|
||||||
|
|
||||||
|
if (!doc.HasMember("maxzoom")) {
|
||||||
|
doc.AddMember("maxzoom", rapidjson::Value(), allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& maxzoom = doc["maxzoom"];
|
||||||
|
|
||||||
|
if (maxzoom.IsString()) {
|
||||||
|
maxzoom.SetInt(std::atoi(maxzoom.GetString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!maxzoom.IsNumber()) {
|
||||||
|
maxzoom = rapidjson::Value().SetUint(header.max_zoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
doc["maxzoom"] = maxzoom;
|
||||||
|
|
||||||
|
std::string metadata = serialize(doc);
|
||||||
|
metadata_cache.emplace(url, metadata);
|
||||||
|
|
||||||
|
callback(std::unique_ptr<Response::Error>());
|
||||||
|
};
|
||||||
|
|
||||||
|
if (header.json_metadata_bytes > 0) {
|
||||||
|
Resource resource(Resource::Kind::Source, url);
|
||||||
|
resource.loadingMethod = Resource::LoadingMethod::Network;
|
||||||
|
resource.dataRange = std::make_pair(header.json_metadata_offset,
|
||||||
|
header.json_metadata_offset + header.json_metadata_bytes - 1);
|
||||||
|
|
||||||
|
tasks[req] = getFileSource()->request(resource, [=](const Response& responseMetadata) {
|
||||||
|
if (responseMetadata.error) {
|
||||||
|
callback(std::make_unique<Response::Error>(
|
||||||
|
responseMetadata.error->reason,
|
||||||
|
std::string("Error fetching PMTiles metadata: ") + responseMetadata.error->message));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string data = *responseMetadata.data;
|
||||||
|
|
||||||
|
if (header.internal_compression == pmtiles::COMPRESSION_GZIP) {
|
||||||
|
data = util::decompress(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_callback(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_callback(std::string());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void storeDirectory(const std::string& url,
|
void storeDirectory(const std::string& url,
|
||||||
uint64_t directoryOffset,
|
uint64_t directoryOffset,
|
||||||
uint64_t directoryLength,
|
uint64_t directoryLength,
|
||||||
const std::string& directoryData) {
|
const std::string& directoryData) {
|
||||||
if (directory_cache.find(url) == directory_cache.end()) {
|
if (!directory_cache.contains(url)) {
|
||||||
directory_cache.emplace(url, std::map<std::string, std::vector<pmtiles::entryv3>>());
|
directory_cache.emplace(url, std::map<std::string, std::vector<pmtiles::entryv3>>());
|
||||||
directory_cache_control.emplace(url, std::vector<std::string>());
|
directory_cache_control.emplace(url, std::vector<std::string>());
|
||||||
}
|
}
|
||||||
@@ -437,8 +443,7 @@ private:
|
|||||||
std::string directory_cache_key = url + "|" + std::to_string(directoryOffset) + "|" +
|
std::string directory_cache_key = url + "|" + std::to_string(directoryOffset) + "|" +
|
||||||
std::to_string(directoryLength);
|
std::to_string(directoryLength);
|
||||||
|
|
||||||
if (directory_cache.find(url) != directory_cache.end() &&
|
if (directory_cache.contains(url) && directory_cache.at(url).contains(directory_cache_key)) {
|
||||||
directory_cache.at(url).find(directory_cache_key) != directory_cache.at(url).end()) {
|
|
||||||
if (directory_cache_control.at(url).back() != directory_cache_key) {
|
if (directory_cache_control.at(url).back() != directory_cache_key) {
|
||||||
directory_cache_control.at(url).emplace_back(directory_cache_key);
|
directory_cache_control.at(url).emplace_back(directory_cache_key);
|
||||||
|
|
||||||
@@ -511,36 +516,41 @@ private:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDirectory(url, req, directoryOffset, directoryLength, [=, this](std::unique_ptr<Response::Error> error) {
|
getDirectory(
|
||||||
if (error) {
|
url,
|
||||||
callback(std::make_pair(0, 0), std::move(error));
|
req,
|
||||||
return;
|
directoryOffset,
|
||||||
}
|
directoryLength,
|
||||||
|
[=, this](std::unique_ptr<Response::Error> error) { // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
pmtiles::headerv3 header = header_cache.at(url);
|
if (error) {
|
||||||
std::vector<pmtiles::entryv3> directory = directory_cache.at(url).at(
|
callback(std::make_pair(0, 0), std::move(error));
|
||||||
url + "|" + std::to_string(directoryOffset) + "|" + std::to_string(directoryLength));
|
|
||||||
|
|
||||||
pmtiles::entryv3 entry = pmtiles::find_tile(directory, tileID);
|
|
||||||
|
|
||||||
if (entry.length > 0) {
|
|
||||||
if (entry.run_length > 0) {
|
|
||||||
callback(std::make_pair(header.tile_data_offset + entry.offset, entry.length), {});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTileAddress(url,
|
pmtiles::headerv3 header = header_cache.at(url);
|
||||||
req,
|
std::vector<pmtiles::entryv3> directory = directory_cache.at(url).at(
|
||||||
tileID,
|
url + "|" + std::to_string(directoryOffset) + "|" + std::to_string(directoryLength));
|
||||||
header.leaf_dirs_offset + entry.offset,
|
|
||||||
entry.length,
|
|
||||||
directoryDepth + 1,
|
|
||||||
std::move(callback));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(std::make_pair(0, 0), {});
|
pmtiles::entryv3 entry = pmtiles::find_tile(directory, tileID);
|
||||||
});
|
|
||||||
|
if (entry.length > 0) {
|
||||||
|
if (entry.run_length > 0) {
|
||||||
|
callback(std::make_pair(header.tile_data_offset + entry.offset, entry.length), {});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTileAddress(url,
|
||||||
|
req,
|
||||||
|
tileID,
|
||||||
|
header.leaf_dirs_offset + entry.offset,
|
||||||
|
entry.length,
|
||||||
|
directoryDepth + 1,
|
||||||
|
std::move(callback));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(std::make_pair(0, 0), {});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string serialize(Document& doc) {
|
std::string serialize(Document& doc) {
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ void RunLoop::waitForEmpty([[maybe_unused]] const mbgl::util::SimpleIdentity tag
|
|||||||
while (true) {
|
while (true) {
|
||||||
std::size_t remaining;
|
std::size_t remaining;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
remaining = defaultQueue.size() + highPriorityQueue.size();
|
remaining = defaultQueue.size() + highPriorityQueue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,15 @@ namespace mbgl {
|
|||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
std::u16string convertUTF8ToUTF16(const std::string& str) {
|
std::u16string convertUTF8ToUTF16(const std::string& str) {
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> conv;
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>
|
||||||
|
conv; // NOLINT(clang-diagnostic-deprecated-declarations)
|
||||||
|
|
||||||
return conv.from_bytes(str);
|
return conv.from_bytes(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string convertUTF16ToUTF8(const std::u16string& str) {
|
std::string convertUTF16ToUTF8(const std::u16string& str) {
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> conv;
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>
|
||||||
|
conv; // NOLINT(clang-diagnostic-deprecated-declarations)
|
||||||
|
|
||||||
return conv.to_bytes(str);
|
return conv.to_bytes(str);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public:
|
|||||||
|
|
||||||
void send(T &&data) {
|
void send(T &&data) {
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
queue.push(std::make_unique<T>(std::move(data)));
|
queue.push(std::make_unique<T>(std::move(data)));
|
||||||
}
|
}
|
||||||
uv_async_send(&async);
|
uv_async_send(&async);
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
|
|
||||||
void send(std::unique_ptr<T> data) {
|
void send(std::unique_ptr<T> data) {
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
queue.push(std::move(data));
|
queue.push(std::move(data));
|
||||||
}
|
}
|
||||||
uv_async_send(&async);
|
uv_async_send(&async);
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void RunLoop::waitForEmpty([[maybe_unused]] const mbgl::util::SimpleIdentity tag
|
|||||||
while (true) {
|
while (true) {
|
||||||
std::size_t remaining;
|
std::size_t remaining;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
remaining = defaultQueue.size() + highPriorityQueue.size();
|
remaining = defaultQueue.size() + highPriorityQueue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void addToIndex(std::size_t sz, void* ptr) {
|
void addToIndex(std::size_t sz, void* ptr) {
|
||||||
std::lock_guard<std::mutex> mlk(indexMutex);
|
std::scoped_lock mlk(indexMutex);
|
||||||
FlagGuard flk(suppresIndexing);
|
FlagGuard flk(suppresIndexing);
|
||||||
allocationsCount++;
|
allocationsCount++;
|
||||||
indexedMemorySize += sz;
|
indexedMemorySize += sz;
|
||||||
@@ -38,7 +38,7 @@ void addToIndex(std::size_t sz, void* ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void removeFromIndex(void* ptr) {
|
void removeFromIndex(void* ptr) {
|
||||||
std::lock_guard<std::mutex> mlk(indexMutex);
|
std::scoped_lock mlk(indexMutex);
|
||||||
FlagGuard flk(suppresIndexing);
|
FlagGuard flk(suppresIndexing);
|
||||||
auto it = memoryIndex.find(ptr);
|
auto it = memoryIndex.find(ptr);
|
||||||
if (it == memoryIndex.end()) return;
|
if (it == memoryIndex.end()) return;
|
||||||
@@ -66,7 +66,7 @@ bool AllocationIndex::isActive() {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
void AllocationIndex::reset() {
|
void AllocationIndex::reset() {
|
||||||
std::lock_guard<std::mutex> mlk(indexMutex);
|
std::scoped_lock mlk(indexMutex);
|
||||||
FlagGuard flk(suppresIndexing);
|
FlagGuard flk(suppresIndexing);
|
||||||
memoryIndex.clear();
|
memoryIndex.clear();
|
||||||
indexedMemorySize = 0;
|
indexedMemorySize = 0;
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ void Mailbox::open(Scheduler& scheduler_) {
|
|||||||
|
|
||||||
// As with close(), block until neither receive() nor push() are in
|
// As with close(), block until neither receive() nor push() are in
|
||||||
// progress, and acquire the two mutexes in the same order.
|
// progress, and acquire the two mutexes in the same order.
|
||||||
std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex);
|
std::scoped_lock receivingLock(receivingMutex);
|
||||||
std::lock_guard<std::mutex> pushingLock(pushingMutex);
|
std::scoped_lock pushingLock(pushingMutex);
|
||||||
|
|
||||||
if (closed) {
|
if (closed) {
|
||||||
return;
|
return;
|
||||||
@@ -51,8 +51,8 @@ void Mailbox::close() {
|
|||||||
// will obtain them when it self-sends a message, and consistent lock
|
// will obtain them when it self-sends a message, and consistent lock
|
||||||
// acquisition order prevents deadlocks. The receiving mutex is recursive to
|
// acquisition order prevents deadlocks. The receiving mutex is recursive to
|
||||||
// allow a mailbox (and thus the actor) to close itself.
|
// allow a mailbox (and thus the actor) to close itself.
|
||||||
std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex);
|
std::scoped_lock receivingLock(receivingMutex);
|
||||||
std::lock_guard<std::mutex> pushingLock(pushingMutex);
|
std::scoped_lock pushingLock(pushingMutex);
|
||||||
|
|
||||||
closed = true;
|
closed = true;
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ void Mailbox::push(std::unique_ptr<Message> message) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
MLN_TRACE_ZONE(push lock);
|
MLN_TRACE_ZONE(push lock);
|
||||||
std::lock_guard<std::mutex> pushingLock(pushingMutex);
|
std::scoped_lock pushingLock(pushingMutex);
|
||||||
|
|
||||||
if (closed) {
|
if (closed) {
|
||||||
state = State::Abandoned;
|
state = State::Abandoned;
|
||||||
@@ -99,7 +99,7 @@ void Mailbox::push(std::unique_ptr<Message> message) {
|
|||||||
bool wasEmpty = false;
|
bool wasEmpty = false;
|
||||||
{
|
{
|
||||||
MLN_TRACE_ZONE(queue lock);
|
MLN_TRACE_ZONE(queue lock);
|
||||||
std::lock_guard<std::mutex> queueLock(queueMutex);
|
std::scoped_lock queueLock(queueMutex);
|
||||||
wasEmpty = queue.empty();
|
wasEmpty = queue.empty();
|
||||||
queue.push(std::move(message));
|
queue.push(std::move(message));
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ void Mailbox::receive() {
|
|||||||
state = State::Idle;
|
state = State::Idle;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex);
|
std::scoped_lock receivingLock(receivingMutex);
|
||||||
|
|
||||||
if (closed) {
|
if (closed) {
|
||||||
state = State::Abandoned;
|
state = State::Abandoned;
|
||||||
@@ -135,7 +135,7 @@ void Mailbox::receive() {
|
|||||||
bool wasEmpty = false;
|
bool wasEmpty = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> queueLock(queueMutex);
|
std::scoped_lock queueLock(queueMutex);
|
||||||
assert(!queue.empty());
|
assert(!queue.empty());
|
||||||
message = std::move(queue.front());
|
message = std::move(queue.front());
|
||||||
queue.pop();
|
queue.pop();
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ std::shared_ptr<Scheduler> Scheduler::GetBackground() {
|
|||||||
static std::weak_ptr<Scheduler> weak;
|
static std::weak_ptr<Scheduler> weak;
|
||||||
static std::mutex mtx;
|
static std::mutex mtx;
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(mtx);
|
std::scoped_lock lock(mtx);
|
||||||
std::shared_ptr<Scheduler> scheduler = weak.lock();
|
std::shared_ptr<Scheduler> scheduler = weak.lock();
|
||||||
|
|
||||||
if (!scheduler) {
|
if (!scheduler) {
|
||||||
@@ -54,7 +54,7 @@ std::shared_ptr<Scheduler> Scheduler::GetSequenced() {
|
|||||||
static std::mutex mtx;
|
static std::mutex mtx;
|
||||||
static std::size_t lastUsedIndex = 0u;
|
static std::size_t lastUsedIndex = 0u;
|
||||||
|
|
||||||
std::lock_guard lock(mtx);
|
std::scoped_lock lock(mtx);
|
||||||
|
|
||||||
lastUsedIndex = (lastUsedIndex + 1) % kSchedulersCount;
|
lastUsedIndex = (lastUsedIndex + 1) % kSchedulersCount;
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ void updateRenderables(GetTileFn getTile,
|
|||||||
covered = true;
|
covered = true;
|
||||||
parentOrChildTileFound = false;
|
parentOrChildTileFound = false;
|
||||||
overscaledZ = idealDataTileID.overscaledZ + 1;
|
overscaledZ = idealDataTileID.overscaledZ + 1;
|
||||||
if (overscaledZ > zoomRange.max) {
|
if (std::cmp_greater(overscaledZ, zoomRange.max)) {
|
||||||
// We're looking for an overzoomed child tile.
|
// We're looking for an overzoomed child tile.
|
||||||
const auto childDataTileID = idealDataTileID.scaledTo(overscaledZ);
|
const auto childDataTileID = idealDataTileID.scaledTo(overscaledZ);
|
||||||
tile = getTile(childDataTileID);
|
tile = getTile(childDataTileID);
|
||||||
@@ -90,7 +90,8 @@ void updateRenderables(GetTileFn getTile,
|
|||||||
|
|
||||||
if (!covered) {
|
if (!covered) {
|
||||||
// We couldn't find child tiles that entirely cover the ideal tile.
|
// We couldn't find child tiles that entirely cover the ideal tile.
|
||||||
for (overscaledZ = idealDataTileID.overscaledZ - 1; overscaledZ >= zoomRange.min; --overscaledZ) {
|
for (overscaledZ = idealDataTileID.overscaledZ - 1; std::cmp_greater_equal(overscaledZ, zoomRange.min);
|
||||||
|
--overscaledZ) {
|
||||||
const auto parentDataTileID = idealDataTileID.scaledTo(overscaledZ);
|
const auto parentDataTileID = idealDataTileID.scaledTo(overscaledZ);
|
||||||
|
|
||||||
// Request / render parent tile only if it's overscale
|
// Request / render parent tile only if it's overscale
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ void AnnotationManager::onStyleLoaded() {
|
|||||||
|
|
||||||
AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation) {
|
AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation) {
|
||||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN(nextID++);
|
CHECK_ANNOTATIONS_ENABLED_AND_RETURN(nextID++);
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
AnnotationID id = nextID++;
|
AnnotationID id = nextID++;
|
||||||
Annotation::visit(annotation, [&](const auto& annotation_) { this->add(id, annotation_); });
|
Annotation::visit(annotation, [&](const auto& annotation_) { this->add(id, annotation_); });
|
||||||
dirty = true;
|
dirty = true;
|
||||||
@@ -62,14 +62,14 @@ AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation) {
|
|||||||
|
|
||||||
bool AnnotationManager::updateAnnotation(const AnnotationID& id, const Annotation& annotation) {
|
bool AnnotationManager::updateAnnotation(const AnnotationID& id, const Annotation& annotation) {
|
||||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN(true);
|
CHECK_ANNOTATIONS_ENABLED_AND_RETURN(true);
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
Annotation::visit(annotation, [&](const auto& annotation_) { this->update(id, annotation_); });
|
Annotation::visit(annotation, [&](const auto& annotation_) { this->update(id, annotation_); });
|
||||||
return dirty;
|
return dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnnotationManager::removeAnnotation(const AnnotationID& id) {
|
void AnnotationManager::removeAnnotation(const AnnotationID& id) {
|
||||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
remove(id);
|
remove(id);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@ void AnnotationManager::updateStyle() {
|
|||||||
style.get().impl->addLayer(std::move(layer));
|
style.get().impl->addLayer(std::move(layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
|
|
||||||
for (const auto& shape : shapeAnnotations) {
|
for (const auto& shape : shapeAnnotations) {
|
||||||
shape.second->updateStyle(*style.get().impl);
|
shape.second->updateStyle(*style.get().impl);
|
||||||
@@ -212,7 +212,7 @@ void AnnotationManager::updateStyle() {
|
|||||||
|
|
||||||
void AnnotationManager::updateData() {
|
void AnnotationManager::updateData() {
|
||||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
if (dirty) {
|
if (dirty) {
|
||||||
for (auto& tile : tiles) {
|
for (auto& tile : tiles) {
|
||||||
tile->setData(getTileData(tile->id.canonical));
|
tile->setData(getTileData(tile->id.canonical));
|
||||||
@@ -223,14 +223,14 @@ void AnnotationManager::updateData() {
|
|||||||
|
|
||||||
void AnnotationManager::addTile(AnnotationTile& tile) {
|
void AnnotationManager::addTile(AnnotationTile& tile) {
|
||||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
tiles.insert(&tile);
|
tiles.insert(&tile);
|
||||||
tile.setData(getTileData(tile.id.canonical));
|
tile.setData(getTileData(tile.id.canonical));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnnotationManager::removeTile(AnnotationTile& tile) {
|
void AnnotationManager::removeTile(AnnotationTile& tile) {
|
||||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
tiles.erase(&tile);
|
tiles.erase(&tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ std::string prefixedImageID(const std::string& id) {
|
|||||||
|
|
||||||
void AnnotationManager::addImage(std::unique_ptr<style::Image> image) {
|
void AnnotationManager::addImage(std::unique_ptr<style::Image> image) {
|
||||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
const std::string id = prefixedImageID(image->getID());
|
const std::string id = prefixedImageID(image->getID());
|
||||||
images.erase(id);
|
images.erase(id);
|
||||||
auto inserted = images.emplace(id,
|
auto inserted = images.emplace(id,
|
||||||
@@ -256,7 +256,7 @@ void AnnotationManager::addImage(std::unique_ptr<style::Image> image) {
|
|||||||
|
|
||||||
void AnnotationManager::removeImage(const std::string& id_) {
|
void AnnotationManager::removeImage(const std::string& id_) {
|
||||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
const std::string id = prefixedImageID(id_);
|
const std::string id = prefixedImageID(id_);
|
||||||
images.erase(id);
|
images.erase(id);
|
||||||
style.get().impl->removeImage(id);
|
style.get().impl->removeImage(id);
|
||||||
@@ -264,7 +264,7 @@ void AnnotationManager::removeImage(const std::string& id_) {
|
|||||||
|
|
||||||
double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id_) {
|
double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id_) {
|
||||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN(0.0);
|
CHECK_ANNOTATIONS_ENABLED_AND_RETURN(0.0);
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
const std::string id = prefixedImageID(id_);
|
const std::string id = prefixedImageID(id_);
|
||||||
auto it = images.find(id);
|
auto it = images.find(id);
|
||||||
return it != images.end() ? -(it->second.getImage().size.height / it->second.getPixelRatio()) / 2 : 0.0;
|
return it != images.end() ? -(it->second.getImage().size.height / it->second.getPixelRatio()) / 2 : 0.0;
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ void FeatureIndex::query(std::unordered_map<std::string, std::vector<Feature>>&
|
|||||||
std::vector<RefIndexedSubfeature> features = grid.query(
|
std::vector<RefIndexedSubfeature> features = grid.query(
|
||||||
{convertPoint<float>(box.min - additionalPadding), convertPoint<float>(box.max + additionalPadding)});
|
{convertPoint<float>(box.min - additionalPadding), convertPoint<float>(box.max + additionalPadding)});
|
||||||
|
|
||||||
std::sort(features.begin(), features.end(), [](const RefIndexedSubfeature& a, const RefIndexedSubfeature& b) {
|
std::ranges::sort(features, [](const RefIndexedSubfeature& a, const RefIndexedSubfeature& b) {
|
||||||
return a.getSortIndex() > b.getSortIndex();
|
return a.getSortIndex() > b.getSortIndex();
|
||||||
});
|
});
|
||||||
size_t previousSortIndex = std::numeric_limits<size_t>::max();
|
size_t previousSortIndex = std::numeric_limits<size_t>::max();
|
||||||
@@ -206,30 +206,28 @@ std::unordered_map<std::string, std::vector<Feature>> FeatureIndex::lookupSymbol
|
|||||||
std::vector<std::reference_wrapper<const RefIndexedSubfeature>> sortedFeatures(symbolFeatures.begin(),
|
std::vector<std::reference_wrapper<const RefIndexedSubfeature>> sortedFeatures(symbolFeatures.begin(),
|
||||||
symbolFeatures.end());
|
symbolFeatures.end());
|
||||||
|
|
||||||
std::sort(sortedFeatures.begin(),
|
std::ranges::sort(sortedFeatures, [featureSortOrder](const RefIndexedSubfeature& a, const RefIndexedSubfeature& b) {
|
||||||
sortedFeatures.end(),
|
// Same idea as the non-symbol sort order, but symbol features may
|
||||||
[featureSortOrder](const RefIndexedSubfeature& a, const RefIndexedSubfeature& b) {
|
// have changed their sort order since their corresponding
|
||||||
// Same idea as the non-symbol sort order, but symbol features may
|
// IndexedSubfeature was added to the CollisionIndex The
|
||||||
// have changed their sort order since their corresponding
|
// 'featureSortOrder' is relatively inefficient for querying but
|
||||||
// IndexedSubfeature was added to the CollisionIndex The
|
// cheap to build on every bucket sort
|
||||||
// 'featureSortOrder' is relatively inefficient for querying but
|
if (featureSortOrder) {
|
||||||
// cheap to build on every bucket sort
|
// queryRenderedSymbols documentation says we'll return features in
|
||||||
if (featureSortOrder) {
|
// "top-to-bottom" rendering order (aka last-to-first).
|
||||||
// queryRenderedSymbols documentation says we'll return features in
|
// Actually there can be multiple symbol instances per feature, so
|
||||||
// "top-to-bottom" rendering order (aka last-to-first).
|
// we sort each feature based on the first matching symbol instance.
|
||||||
// Actually there can be multiple symbol instances per feature, so
|
auto sortedA = std::find(featureSortOrder->begin(), featureSortOrder->end(), a.getIndex());
|
||||||
// we sort each feature based on the first matching symbol instance.
|
auto sortedB = std::find(featureSortOrder->begin(), featureSortOrder->end(), b.getIndex());
|
||||||
auto sortedA = std::find(featureSortOrder->begin(), featureSortOrder->end(), a.getIndex());
|
assert(sortedA != featureSortOrder->end());
|
||||||
auto sortedB = std::find(featureSortOrder->begin(), featureSortOrder->end(), b.getIndex());
|
assert(sortedB != featureSortOrder->end());
|
||||||
assert(sortedA != featureSortOrder->end());
|
return sortedA > sortedB;
|
||||||
assert(sortedB != featureSortOrder->end());
|
} else {
|
||||||
return sortedA > sortedB;
|
// Bucket hasn't been re-sorted based on angle, so use same
|
||||||
} else {
|
// "reverse of appearance in source data" logic as non-symboles
|
||||||
// Bucket hasn't been re-sorted based on angle, so use same
|
return a.getSortIndex() > b.getSortIndex();
|
||||||
// "reverse of appearance in source data" logic as non-symboles
|
}
|
||||||
return a.getSortIndex() > b.getSortIndex();
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const auto& symbolFeature : sortedFeatures) {
|
for (const auto& symbolFeature : sortedFeatures) {
|
||||||
mat4 unusedMatrix;
|
mat4 unusedMatrix;
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ DynamicTexture::DynamicTexture(Context& context, Size size, TexturePixelType pix
|
|||||||
texture = context.createTexture2D();
|
texture = context.createTexture2D();
|
||||||
texture->setSize(size);
|
texture->setSize(size);
|
||||||
texture->setFormat(pixelType, TextureChannelDataType::UnsignedByte);
|
texture->setFormat(pixelType, TextureChannelDataType::UnsignedByte);
|
||||||
texture->setSamplerConfiguration(
|
texture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
.wrapU = gfx::TextureWrapType::Clamp,
|
||||||
|
.wrapV = gfx::TextureWrapType::Clamp});
|
||||||
#if MLN_DEFER_UPLOAD_ON_RENDER_THREAD
|
#if MLN_DEFER_UPLOAD_ON_RENDER_THREAD
|
||||||
deferredCreation = true;
|
deferredCreation = true;
|
||||||
#else
|
#else
|
||||||
@@ -37,7 +38,7 @@ bool DynamicTexture::isEmpty() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<TextureHandle> DynamicTexture::reserveSize(const Size& size, int32_t uniqueId) {
|
std::optional<TextureHandle> DynamicTexture::reserveSize(const Size& size, int32_t uniqueId) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
mapbox::Bin* bin = shelfPack.packOne(uniqueId, size.width, size.height);
|
mapbox::Bin* bin = shelfPack.packOne(uniqueId, size.width, size.height);
|
||||||
if (!bin) {
|
if (!bin) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -49,7 +50,7 @@ std::optional<TextureHandle> DynamicTexture::reserveSize(const Size& size, int32
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DynamicTexture::uploadImage(const uint8_t* pixelData, TextureHandle& texHandle) {
|
void DynamicTexture::uploadImage(const uint8_t* pixelData, TextureHandle& texHandle) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
const auto& rect = texHandle.getRectangle();
|
const auto& rect = texHandle.getRectangle();
|
||||||
const auto imageSize = Size(rect.w, rect.h);
|
const auto imageSize = Size(rect.w, rect.h);
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ std::optional<TextureHandle> DynamicTexture::addImage(const uint8_t* pixelData,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DynamicTexture::uploadDeferredImages() {
|
void DynamicTexture::uploadDeferredImages() {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
if (deferredCreation) {
|
if (deferredCreation) {
|
||||||
texture->create();
|
texture->create();
|
||||||
deferredCreation = false;
|
deferredCreation = false;
|
||||||
@@ -88,7 +89,7 @@ void DynamicTexture::uploadDeferredImages() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DynamicTexture::removeTexture(const TextureHandle& texHandle) {
|
void DynamicTexture::removeTexture(const TextureHandle& texHandle) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
auto* bin = shelfPack.getBin(texHandle.getId());
|
auto* bin = shelfPack.getBin(texHandle.getId());
|
||||||
if (!bin) {
|
if (!bin) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <mbgl/gfx/dynamic_texture_atlas.hpp>
|
#include <mbgl/gfx/dynamic_texture_atlas.hpp>
|
||||||
#include <mbgl/gfx/context.hpp>
|
#include <mbgl/gfx/context.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
@@ -11,14 +12,16 @@ constexpr const uint16_t padding = ImagePosition::padding + extraPadding;
|
|||||||
constexpr const Size startSize = {512, 512};
|
constexpr const Size startSize = {512, 512};
|
||||||
constexpr const Size dummySize = {1, 1};
|
constexpr const Size dummySize = {1, 1};
|
||||||
|
|
||||||
|
namespace {
|
||||||
Rect<uint16_t> rectWithoutExtraPadding(const Rect<uint16_t>& rect) {
|
Rect<uint16_t> rectWithoutExtraPadding(const Rect<uint16_t>& rect) {
|
||||||
return Rect<uint16_t>(
|
return Rect<uint16_t>(
|
||||||
rect.x + extraPadding, rect.y + extraPadding, rect.w - 2 * extraPadding, rect.h - 2 * extraPadding);
|
rect.x + extraPadding, rect.y + extraPadding, rect.w - 2 * extraPadding, rect.h - 2 * extraPadding);
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
GlyphAtlas DynamicTextureAtlas::uploadGlyphs(const GlyphMap& glyphs) {
|
GlyphAtlas DynamicTextureAtlas::uploadGlyphs(const GlyphMap& glyphs) {
|
||||||
using GlyphsToUpload = std::vector<std::tuple<TextureHandle, Immutable<Glyph>, FontStackHash>>;
|
using GlyphsToUpload = std::vector<std::tuple<TextureHandle, Immutable<Glyph>, FontStackHash>>;
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
|
|
||||||
GlyphAtlas glyphAtlas;
|
GlyphAtlas glyphAtlas;
|
||||||
if (!glyphs.size()) {
|
if (!glyphs.size()) {
|
||||||
@@ -97,8 +100,8 @@ GlyphAtlas DynamicTextureAtlas::uploadGlyphs(const GlyphMap& glyphs) {
|
|||||||
glyphAtlas.dynamicTexture->uploadImage(paddedImage.data.get(), texHandle);
|
glyphAtlas.dynamicTexture->uploadImage(paddedImage.data.get(), texHandle);
|
||||||
}
|
}
|
||||||
glyphAtlas.textureHandles.emplace_back(texHandle);
|
glyphAtlas.textureHandles.emplace_back(texHandle);
|
||||||
glyphAtlas.glyphPositions[fontStack].emplace(glyph->id,
|
glyphAtlas.glyphPositions[fontStack].emplace(
|
||||||
GlyphPosition{rectWithoutExtraPadding(rect), glyph->metrics});
|
glyph->id, GlyphPosition{.rect = rectWithoutExtraPadding(rect), .metrics = glyph->metrics});
|
||||||
}
|
}
|
||||||
return glyphAtlas;
|
return glyphAtlas;
|
||||||
}
|
}
|
||||||
@@ -107,7 +110,7 @@ ImageAtlas DynamicTextureAtlas::uploadIconsAndPatterns(const ImageMap& icons,
|
|||||||
const ImageMap& patterns,
|
const ImageMap& patterns,
|
||||||
const ImageVersionMap& versionMap) {
|
const ImageVersionMap& versionMap) {
|
||||||
using ImagesToUpload = std::vector<std::pair<TextureHandle, Immutable<style::Image::Impl>>>;
|
using ImagesToUpload = std::vector<std::pair<TextureHandle, Immutable<style::Image::Impl>>>;
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
|
|
||||||
ImageAtlas imageAtlas;
|
ImageAtlas imageAtlas;
|
||||||
if (!icons.size() && !patterns.size()) {
|
if (!icons.size() && !patterns.size()) {
|
||||||
@@ -243,7 +246,7 @@ ImageAtlas DynamicTextureAtlas::uploadIconsAndPatterns(const ImageMap& icons,
|
|||||||
|
|
||||||
void DynamicTextureAtlas::removeTextures(const std::vector<TextureHandle>& textureHandles,
|
void DynamicTextureAtlas::removeTextures(const std::vector<TextureHandle>& textureHandles,
|
||||||
const DynamicTexturePtr& dynamicTexture) {
|
const DynamicTexturePtr& dynamicTexture) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
if (!dynamicTexture) {
|
if (!dynamicTexture) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -252,7 +255,7 @@ void DynamicTextureAtlas::removeTextures(const std::vector<TextureHandle>& textu
|
|||||||
dynamicTexture->removeTexture(texHandle);
|
dynamicTexture->removeTexture(texHandle);
|
||||||
}
|
}
|
||||||
if (dynamicTexture->isEmpty()) {
|
if (dynamicTexture->isEmpty()) {
|
||||||
auto iterator = std::find(dynamicTextures.begin(), dynamicTextures.end(), dynamicTexture);
|
auto iterator = std::ranges::find(dynamicTextures, dynamicTexture);
|
||||||
if (iterator != dynamicTextures.end()) {
|
if (iterator != dynamicTextures.end()) {
|
||||||
dynamicTextures.erase(iterator);
|
dynamicTextures.erase(iterator);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ public:
|
|||||||
const auto& sortKeyProperty = layout.template get<style::CircleSortKey>();
|
const auto& sortKeyProperty = layout.template get<style::CircleSortKey>();
|
||||||
float sortKey = sortKeyProperty.evaluate(*feature, zoom, style::CircleSortKey::defaultValue());
|
float sortKey = sortKeyProperty.evaluate(*feature, zoom, style::CircleSortKey::defaultValue());
|
||||||
CircleFeature circleFeature{.i = i, .feature = std::move(feature), .sortKey = sortKey};
|
CircleFeature circleFeature{.i = i, .feature = std::move(feature), .sortKey = sortKey};
|
||||||
const auto sortPosition = std::lower_bound(features.cbegin(), features.cend(), circleFeature);
|
const auto sortPosition = std::lower_bound(
|
||||||
|
features.cbegin(), features.cend(), circleFeature); // NOLINT(modernize-use-ranges)
|
||||||
features.insert(sortPosition, std::move(circleFeature));
|
features.insert(sortPosition, std::move(circleFeature));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +76,7 @@ public:
|
|||||||
if (!bucket->hasData()) return;
|
if (!bucket->hasData()) return;
|
||||||
|
|
||||||
for (const auto& pair : layerPropertiesMap) {
|
for (const auto& pair : layerPropertiesMap) {
|
||||||
renderData.emplace(pair.first, LayerRenderData{bucket, pair.second});
|
renderData.emplace(pair.first, LayerRenderData{.bucket = bucket, .layerProperties = pair.second});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include <source_location>
|
#include <source_location>
|
||||||
|
|
||||||
#if !defined(MLN_SYMBOL_GUARDS)
|
#ifndef MLN_SYMBOL_GUARDS
|
||||||
#define MLN_SYMBOL_GUARDS 1
|
#define MLN_SYMBOL_GUARDS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
// A temporary shim for partial C++20 support
|
// A temporary shim for partial C++20 support
|
||||||
#if MLN_SYMBOL_GUARDS
|
#if MLN_SYMBOL_GUARDS
|
||||||
#if defined(__clang__)
|
#ifdef __clang__
|
||||||
#if __cplusplus <= 201703L || !__has_builtin(__builtin_source_location)
|
#if __cplusplus <= 201703L || !__has_builtin(__builtin_source_location)
|
||||||
namespace std {
|
namespace std {
|
||||||
struct source_location {
|
struct source_location {
|
||||||
|
|||||||
@@ -153,10 +153,11 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
|||||||
auto modes = layout->get<TextWritingMode>();
|
auto modes = layout->get<TextWritingMode>();
|
||||||
// Remove duplicates and preserve order.
|
// Remove duplicates and preserve order.
|
||||||
std::set<style::TextWritingModeType> seen;
|
std::set<style::TextWritingModeType> seen;
|
||||||
auto end = std::remove_if(modes.begin(), modes.end(), [&seen, this](const auto& placementMode) {
|
auto end = std::ranges::remove_if(modes, [&seen, this](const auto& placementMode) {
|
||||||
allowVerticalPlacement = allowVerticalPlacement || placementMode == style::TextWritingModeType::Vertical;
|
allowVerticalPlacement = allowVerticalPlacement ||
|
||||||
return !seen.insert(placementMode).second;
|
placementMode == style::TextWritingModeType::Vertical;
|
||||||
});
|
return !seen.insert(placementMode).second;
|
||||||
|
}).begin();
|
||||||
modes.erase(end, modes.end());
|
modes.erase(end, modes.end());
|
||||||
placementModes = std::move(modes);
|
placementModes = std::move(modes);
|
||||||
}
|
}
|
||||||
@@ -299,7 +300,10 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
|||||||
if (ft.formattedText || ft.icon) {
|
if (ft.formattedText || ft.icon) {
|
||||||
if (sortFeaturesByKey) {
|
if (sortFeaturesByKey) {
|
||||||
ft.sortKey = layout->evaluate<SymbolSortKey>(zoom, ft, canonicalID);
|
ft.sortKey = layout->evaluate<SymbolSortKey>(zoom, ft, canonicalID);
|
||||||
const auto lowerBound = std::lower_bound(features.begin(), features.end(), ft);
|
const auto lowerBound = std::lower_bound( // NOLINT(modernize-use-ranges)
|
||||||
|
features.begin(),
|
||||||
|
features.end(),
|
||||||
|
ft);
|
||||||
features.insert(lowerBound, std::move(ft));
|
features.insert(lowerBound, std::move(ft));
|
||||||
} else {
|
} else {
|
||||||
features.push_back(std::move(ft));
|
features.push_back(std::move(ft));
|
||||||
@@ -964,7 +968,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor& anchor) {
|
bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor& anchor) {
|
||||||
if (compareText.find(text) == compareText.end()) {
|
if (!compareText.contains(text)) {
|
||||||
compareText.emplace(text, Anchors());
|
compareText.emplace(text, Anchors());
|
||||||
} else {
|
} else {
|
||||||
const auto& otherAnchors = compareText.find(text)->second;
|
const auto& otherAnchors = compareText.find(text)->second;
|
||||||
@@ -1153,7 +1157,7 @@ void SymbolLayout::createBucket(const ImagePositions&,
|
|||||||
if (!firstLoad) {
|
if (!firstLoad) {
|
||||||
bucket->justReloaded = true;
|
bucket->justReloaded = true;
|
||||||
}
|
}
|
||||||
renderData.emplace(pair.first, LayerRenderData{bucket, pair.second});
|
renderData.emplace(pair.first, LayerRenderData{.bucket = bucket, .layerProperties = pair.second});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ std::optional<PlacedGlyph> placeGlyphAlongLine(const float offsetX,
|
|||||||
currentIndex += dir;
|
currentIndex += dir;
|
||||||
|
|
||||||
// offset does not fit on the projected line
|
// offset does not fit on the projected line
|
||||||
if (currentIndex < 0 || currentIndex >= static_cast<int32_t>(line.size())) {
|
if (currentIndex < 0 || std::cmp_greater_equal(currentIndex, static_cast<int32_t>(line.size()))) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,29 +113,29 @@ void Map::Impl::onUpdate() {
|
|||||||
|
|
||||||
transform.updateTransitions(timePoint);
|
transform.updateTransitions(timePoint);
|
||||||
|
|
||||||
UpdateParameters params = {style->impl->isLoaded(),
|
UpdateParameters params = {.styleLoaded = style->impl->isLoaded(),
|
||||||
mode,
|
.mode = mode,
|
||||||
pixelRatio,
|
.pixelRatio = pixelRatio,
|
||||||
debugOptions,
|
.debugOptions = debugOptions,
|
||||||
timePoint,
|
.timePoint = timePoint,
|
||||||
transform.getState(),
|
.transformState = transform.getState(),
|
||||||
style->impl->getGlyphURL(),
|
.glyphURL = style->impl->getGlyphURL(),
|
||||||
style->impl->getFontFaces(),
|
.fontFaces = style->impl->getFontFaces(),
|
||||||
style->impl->areSpritesLoaded(),
|
.spriteLoaded = style->impl->areSpritesLoaded(),
|
||||||
style->impl->getTransitionOptions(),
|
.transitionOptions = style->impl->getTransitionOptions(),
|
||||||
style->impl->getLight()->impl,
|
.light = style->impl->getLight()->impl,
|
||||||
style->impl->getImageImpls(),
|
.images = style->impl->getImageImpls(),
|
||||||
style->impl->getSourceImpls(),
|
.sources = style->impl->getSourceImpls(),
|
||||||
style->impl->getLayerImpls(),
|
.layers = style->impl->getLayerImpls(),
|
||||||
annotationManager.makeWeakPtr(),
|
.annotationManager = annotationManager.makeWeakPtr(),
|
||||||
fileSource,
|
.fileSource = fileSource,
|
||||||
prefetchZoomDelta,
|
.prefetchZoomDelta = prefetchZoomDelta,
|
||||||
bool(stillImageRequest),
|
.stillImageRequest = bool(stillImageRequest),
|
||||||
crossSourceCollisions,
|
.crossSourceCollisions = crossSourceCollisions,
|
||||||
tileLodMinRadius,
|
.tileLodMinRadius = tileLodMinRadius,
|
||||||
tileLodScale,
|
.tileLodScale = tileLodScale,
|
||||||
tileLodPitchThreshold,
|
.tileLodPitchThreshold = tileLodPitchThreshold,
|
||||||
tileLodZoomShift};
|
.tileLodZoomShift = tileLodZoomShift};
|
||||||
|
|
||||||
rendererFrontend.update(std::make_shared<UpdateParameters>(std::move(params)));
|
rendererFrontend.update(std::make_shared<UpdateParameters>(std::move(params)));
|
||||||
}
|
}
|
||||||
@@ -254,8 +254,10 @@ void Map::Impl::onDidFinishRenderingFrame(RenderMode renderMode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == MapMode::Continuous) {
|
if (mode == MapMode::Continuous) {
|
||||||
const MapObserver::RenderFrameStatus frameStatus{
|
const MapObserver::RenderFrameStatus frameStatus{.mode = static_cast<MapObserver::RenderMode>(renderMode),
|
||||||
MapObserver::RenderMode(renderMode), needsRepaint, placemenChanged, stats};
|
.needsRepaint = needsRepaint,
|
||||||
|
.placementChanged = placemenChanged,
|
||||||
|
.renderingStats = stats};
|
||||||
observer.onDidFinishRenderingFrame(frameStatus);
|
observer.onDidFinishRenderingFrame(frameStatus);
|
||||||
|
|
||||||
if (actionJournal) {
|
if (actionJournal) {
|
||||||
@@ -272,7 +274,7 @@ void Map::Impl::onDidFinishRenderingFrame(RenderMode renderMode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (stillImageRequest && rendererFullyLoaded) {
|
} else if (stillImageRequest && rendererFullyLoaded) {
|
||||||
auto request = std::move(stillImageRequest);
|
const auto request = std::move(stillImageRequest);
|
||||||
request->callback(nullptr);
|
request->callback(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,8 @@ UniqueShaderProgram Context::createProgram(shaders::BuiltIn shaderID,
|
|||||||
// options->setOptimizationLevel(MTL::LibraryOptimizationLevelDefault);
|
// options->setOptimizationLevel(MTL::LibraryOptimizationLevelDefault);
|
||||||
|
|
||||||
NS::Error* error = nullptr;
|
NS::Error* error = nullptr;
|
||||||
NS::String* nsSource = NS::String::string(source.data(), NS::UTF8StringEncoding);
|
NS::String* nsSource = NS::String::string(
|
||||||
|
source.data(), NS::UTF8StringEncoding); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
|
|
||||||
const auto& device = backend.getDevice();
|
const auto& device = backend.getDevice();
|
||||||
auto library = NS::TransferPtr(device->newLibrary(nsSource, options.get(), &error));
|
auto library = NS::TransferPtr(device->newLibrary(nsSource, options.get(), &error));
|
||||||
@@ -152,7 +153,8 @@ UniqueShaderProgram Context::createProgram(shaders::BuiltIn shaderID,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto nsVertName = NS::String::string(vertexName.data(), NS::UTF8StringEncoding);
|
const auto nsVertName = NS::String::string(
|
||||||
|
vertexName.data(), NS::UTF8StringEncoding); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
MTLFunctionPtr vertexFunction = NS::TransferPtr(library->newFunction(nsVertName));
|
MTLFunctionPtr vertexFunction = NS::TransferPtr(library->newFunction(nsVertName));
|
||||||
if (!vertexFunction) {
|
if (!vertexFunction) {
|
||||||
Log::Error(Event::Shader, name + " missing vertex function " + vertexName.data());
|
Log::Error(Event::Shader, name + " missing vertex function " + vertexName.data());
|
||||||
@@ -164,7 +166,8 @@ UniqueShaderProgram Context::createProgram(shaders::BuiltIn shaderID,
|
|||||||
// fragment function is optional
|
// fragment function is optional
|
||||||
MTLFunctionPtr fragmentFunction;
|
MTLFunctionPtr fragmentFunction;
|
||||||
if (!fragmentName.empty()) {
|
if (!fragmentName.empty()) {
|
||||||
const auto nsFragName = NS::String::string(fragmentName.data(), NS::UTF8StringEncoding);
|
const auto nsFragName = NS::String::string(
|
||||||
|
fragmentName.data(), NS::UTF8StringEncoding); // NOLINT(bugprone-suspicious-stringview-data-usage)
|
||||||
fragmentFunction = NS::TransferPtr(library->newFunction(nsFragName));
|
fragmentFunction = NS::TransferPtr(library->newFunction(nsFragName));
|
||||||
if (!fragmentFunction) {
|
if (!fragmentFunction) {
|
||||||
Log::Error(Event::Shader, name + " missing fragment function " + fragmentName.data());
|
Log::Error(Event::Shader, name + " missing fragment function " + fragmentName.data());
|
||||||
@@ -286,15 +289,15 @@ const UniqueVertexBufferResource& Context::getEmptyVertexBuffer() {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const auto clipMaskStencilMode = gfx::StencilMode{
|
const auto clipMaskStencilMode = gfx::StencilMode{
|
||||||
/*.test=*/gfx::StencilMode::Always(),
|
.test = gfx::StencilMode::Always(),
|
||||||
/*.ref=*/0,
|
.ref = 0,
|
||||||
/*.mask=*/0b11111111,
|
.mask = 0b11111111,
|
||||||
/*.fail=*/gfx::StencilOpType::Keep,
|
.fail = gfx::StencilOpType::Keep,
|
||||||
/*.depthFail=*/gfx::StencilOpType::Keep,
|
.depthFail = gfx::StencilOpType::Keep,
|
||||||
/*.pass=*/gfx::StencilOpType::Replace,
|
.pass = gfx::StencilOpType::Replace,
|
||||||
};
|
};
|
||||||
const auto clipMaskDepthMode = gfx::DepthMode{/*.func=*/gfx::DepthFunctionType::Always,
|
const auto clipMaskDepthMode = gfx::DepthMode{.func = gfx::DepthFunctionType::Always,
|
||||||
/*.mask=*/gfx::DepthMaskType::ReadOnly};
|
.mask = gfx::DepthMaskType::ReadOnly};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool Context::renderTileClippingMasks(gfx::RenderPass& renderPass,
|
bool Context::renderTileClippingMasks(gfx::RenderPass& renderPass,
|
||||||
|
|||||||
@@ -122,7 +122,10 @@ MTL::Winding mapWindingMode(const gfx::CullFaceWindingType mode) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTL::ScissorRect getMetalScissorRect(gfx::ScissorRect rect) noexcept {
|
MTL::ScissorRect getMetalScissorRect(gfx::ScissorRect rect) noexcept {
|
||||||
return {static_cast<uint32_t>(rect.x), static_cast<uint32_t>(rect.y), rect.width, rect.height};
|
return {.x = static_cast<uint32_t>(rect.x),
|
||||||
|
.y = static_cast<uint32_t>(rect.y),
|
||||||
|
.width = rect.width,
|
||||||
|
.height = rect.height};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -181,8 +184,10 @@ void Drawable::draw(PaintParameters& parameters) const {
|
|||||||
if (impl->renderPassDescriptor && descriptor != *impl->renderPassDescriptor) {
|
if (impl->renderPassDescriptor && descriptor != *impl->renderPassDescriptor) {
|
||||||
impl->pipelineState.reset();
|
impl->pipelineState.reset();
|
||||||
}
|
}
|
||||||
impl->renderPassDescriptor.emplace(gfx::RenderPassDescriptor{
|
impl->renderPassDescriptor.emplace(gfx::RenderPassDescriptor{.renderable = descriptor.renderable,
|
||||||
descriptor.renderable, descriptor.clearColor, descriptor.clearDepth, descriptor.clearStencil});
|
.clearColor = descriptor.clearColor,
|
||||||
|
.clearDepth = descriptor.clearDepth,
|
||||||
|
.clearStencil = descriptor.clearStencil});
|
||||||
|
|
||||||
const auto& shaderMTL = static_cast<const ShaderProgram&>(*shader);
|
const auto& shaderMTL = static_cast<const ShaderProgram&>(*shader);
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ public:
|
|||||||
colorTexture = context.createTexture2D();
|
colorTexture = context.createTexture2D();
|
||||||
colorTexture->setSize(size);
|
colorTexture->setSize(size);
|
||||||
colorTexture->setFormat(gfx::TexturePixelType::RGBA, type);
|
colorTexture->setFormat(gfx::TexturePixelType::RGBA, type);
|
||||||
colorTexture->setSamplerConfiguration(
|
colorTexture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
.wrapU = gfx::TextureWrapType::Clamp,
|
||||||
|
.wrapV = gfx::TextureWrapType::Clamp});
|
||||||
static_cast<Texture2D*>(colorTexture.get())
|
static_cast<Texture2D*>(colorTexture.get())
|
||||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||||
|
|
||||||
@@ -32,8 +33,9 @@ public:
|
|||||||
depthTexture = context.createTexture2D();
|
depthTexture = context.createTexture2D();
|
||||||
depthTexture->setSize(size);
|
depthTexture->setSize(size);
|
||||||
depthTexture->setFormat(gfx::TexturePixelType::Depth, gfx::TextureChannelDataType::Float);
|
depthTexture->setFormat(gfx::TexturePixelType::Depth, gfx::TextureChannelDataType::Float);
|
||||||
depthTexture->setSamplerConfiguration(
|
depthTexture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
.wrapU = gfx::TextureWrapType::Clamp,
|
||||||
|
.wrapV = gfx::TextureWrapType::Clamp});
|
||||||
static_cast<Texture2D*>(depthTexture.get())
|
static_cast<Texture2D*>(depthTexture.get())
|
||||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||||
}
|
}
|
||||||
@@ -44,8 +46,9 @@ public:
|
|||||||
stencilTexture = context.createTexture2D();
|
stencilTexture = context.createTexture2D();
|
||||||
stencilTexture->setSize(size);
|
stencilTexture->setSize(size);
|
||||||
stencilTexture->setFormat(gfx::TexturePixelType::Stencil, gfx::TextureChannelDataType::UnsignedByte);
|
stencilTexture->setFormat(gfx::TexturePixelType::Stencil, gfx::TextureChannelDataType::UnsignedByte);
|
||||||
stencilTexture->setSamplerConfiguration(
|
stencilTexture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
.wrapU = gfx::TextureWrapType::Clamp,
|
||||||
|
.wrapV = gfx::TextureWrapType::Clamp});
|
||||||
static_cast<Texture2D*>(stencilTexture.get())
|
static_cast<Texture2D*>(stencilTexture.get())
|
||||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ void RenderPass::resetState() {
|
|||||||
|
|
||||||
currentCullMode = MTL::CullModeNone;
|
currentCullMode = MTL::CullModeNone;
|
||||||
currentWinding = MTL::WindingClockwise;
|
currentWinding = MTL::WindingClockwise;
|
||||||
currentScissorRect = {0, 0, 0, 0};
|
currentScissorRect = {.x = 0, .y = 0, .width = 0, .height = 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -130,7 +130,7 @@ void RenderPass::bindVertex(const BufferResource& buf, std::size_t offset, std::
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vertexBinds[index] = BindInfo{&buf, actualSize, offset};
|
vertexBinds[index] = BindInfo{.buf = &buf, .size = actualSize, .offset = offset};
|
||||||
}
|
}
|
||||||
buf.bindVertex(encoder, offset, index, actualSize);
|
buf.bindVertex(encoder, offset, index, actualSize);
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ void RenderPass::bindFragment(const BufferResource& buf, std::size_t offset, std
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fragmentBinds[index] = BindInfo{&buf, actualSize, offset};
|
fragmentBinds[index] = BindInfo{.buf = &buf, .size = actualSize, .offset = offset};
|
||||||
}
|
}
|
||||||
buf.bindFragment(encoder, offset, index, actualSize);
|
buf.bindFragment(encoder, offset, index, actualSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Texture2D::Texture2D(Context& context_)
|
|||||||
Texture2D::~Texture2D() {
|
Texture2D::~Texture2D() {
|
||||||
if (metalTexture) {
|
if (metalTexture) {
|
||||||
context.renderingStats().numActiveTextures--;
|
context.renderingStats().numActiveTextures--;
|
||||||
context.renderingStats().memTextures -= getDataSize();
|
context.renderingStats().memTextures -= getDataSize(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,17 +57,17 @@ gfx::Texture2D& Texture2D::setImage(std::shared_ptr<PremultipliedImage> image_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t Texture2D::getDataSize() const noexcept {
|
size_t Texture2D::getDataSize() const noexcept {
|
||||||
return size.width * size.height * getPixelStride();
|
return size.width * size.height * getPixelStride(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Texture2D::getPixelStride() const noexcept {
|
size_t Texture2D::getPixelStride() const noexcept {
|
||||||
switch (channelType) {
|
switch (channelType) {
|
||||||
case gfx::TextureChannelDataType::UnsignedByte:
|
case gfx::TextureChannelDataType::UnsignedByte:
|
||||||
return 1 * numChannels();
|
return 1 * numChannels(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
|
||||||
case gfx::TextureChannelDataType::HalfFloat:
|
case gfx::TextureChannelDataType::HalfFloat:
|
||||||
return 2 * numChannels();
|
return 2 * numChannels(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
|
||||||
case gfx::TextureChannelDataType::Float:
|
case gfx::TextureChannelDataType::Float:
|
||||||
return 4 * numChannels();
|
return 4 * numChannels(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ void TileLayerGroup::render(RenderOrchestrator&, PaintParameters& parameters) {
|
|||||||
// stencil mode for features with stencil enabled or disable stenciling.
|
// stencil mode for features with stencil enabled or disable stenciling.
|
||||||
// 2D drawables will set their own stencil mode within `draw`.
|
// 2D drawables will set their own stencil mode within `draw`.
|
||||||
if (features3d) {
|
if (features3d) {
|
||||||
const auto state = getDepthStencilState(drawable.getEnableDepth(), drawable.getEnableStencil());
|
const auto& state = getDepthStencilState(drawable.getEnableDepth(), drawable.getEnableStencil());
|
||||||
renderPass.setDepthStencilState(state);
|
renderPass.setDepthStencilState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ UniformBuffer::UniformBuffer(BufferResource&& buffer_)
|
|||||||
|
|
||||||
UniformBuffer::UniformBuffer(UniformBuffer&& other)
|
UniformBuffer::UniformBuffer(UniformBuffer&& other)
|
||||||
: gfx::UniformBuffer(std::move(other)),
|
: gfx::UniformBuffer(std::move(other)),
|
||||||
buffer(std::move(other.buffer)) {}
|
buffer(std::move(other.buffer)) {} // NOLINT(bugprone-use-after-move)
|
||||||
|
|
||||||
UniformBuffer::~UniformBuffer() {
|
UniformBuffer::~UniformBuffer() {
|
||||||
buffer.getContext().renderingStats().numUniformBuffers--;
|
buffer.getContext().renderingStats().numUniformBuffers--;
|
||||||
@@ -43,7 +43,7 @@ void UniformBufferArray::bindMtl(RenderPass& renderPass) const noexcept {
|
|||||||
for (size_t id = 0; id < allocatedSize(); id++) {
|
for (size_t id = 0; id < allocatedSize(); id++) {
|
||||||
const auto& uniformBuffer = get(id);
|
const auto& uniformBuffer = get(id);
|
||||||
if (!uniformBuffer) continue;
|
if (!uniformBuffer) continue;
|
||||||
const auto& buffer = static_cast<UniformBuffer&>(*uniformBuffer.get());
|
const auto& buffer = static_cast<UniformBuffer&>(*uniformBuffer);
|
||||||
const auto& resource = buffer.getBufferResource();
|
const auto& resource = buffer.getBufferResource();
|
||||||
if (id != shaders::idDrawableReservedFragmentOnlyUBO) {
|
if (id != shaders::idDrawableReservedFragmentOnlyUBO) {
|
||||||
renderPass.bindVertex(resource, 0, id);
|
renderPass.bindVertex(resource, 0, id);
|
||||||
|
|||||||
@@ -150,10 +150,10 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
|||||||
// up a valid binding or the validation will complain when the shader code references the
|
// up a valid binding or the validation will complain when the shader code references the
|
||||||
// attribute at compile time, regardless of whether it's ever used at runtime.
|
// attribute at compile time, regardless of whether it's ever used at runtime.
|
||||||
bindings[index] = {
|
bindings[index] = {
|
||||||
/*.attribute = */ {defaultAttr.getDataType(), /*offset=*/0},
|
.attribute = {.dataType = defaultAttr.getDataType(), /*offset=*/.offset = 0},
|
||||||
/*.vertexStride = */ static_cast<uint32_t>(VertexAttribute::getStrideOf(defaultAttr.getDataType())),
|
.vertexStride = static_cast<uint32_t>(VertexAttribute::getStrideOf(defaultAttr.getDataType())),
|
||||||
/*.vertexBufferResource = */ nullptr,
|
.vertexBufferResource = nullptr,
|
||||||
/*.vertexOffset = */ 0,
|
.vertexOffset = 0,
|
||||||
};
|
};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,19 +30,19 @@ Settings& Settings::getInstance() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Settings::set(const std::string& key, mapbox::base::Value value) noexcept {
|
void Settings::set(const std::string& key, mapbox::base::Value value) noexcept {
|
||||||
std::lock_guard<std::mutex> lock(impl->mutex);
|
std::scoped_lock lock(impl->mutex);
|
||||||
impl->settings[key] = std::move(value);
|
impl->settings[key] = std::move(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::set(const mapbox::base::ValueObject& values) noexcept {
|
void Settings::set(const mapbox::base::ValueObject& values) noexcept {
|
||||||
std::lock_guard<std::mutex> lock(impl->mutex);
|
std::scoped_lock lock(impl->mutex);
|
||||||
for (const auto& pair : values) {
|
for (const auto& pair : values) {
|
||||||
impl->settings[pair.first] = pair.second;
|
impl->settings[pair.first] = pair.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mapbox::base::ValueObject Settings::get(const std::vector<std::string>& keys) const noexcept {
|
mapbox::base::ValueObject Settings::get(const std::vector<std::string>& keys) const noexcept {
|
||||||
std::lock_guard<std::mutex> lock(impl->mutex);
|
std::scoped_lock lock(impl->mutex);
|
||||||
mapbox::base::ValueObject result;
|
mapbox::base::ValueObject result;
|
||||||
for (const auto& key : keys) {
|
for (const auto& key : keys) {
|
||||||
result[key] = getValue(key, impl->settings);
|
result[key] = getValue(key, impl->settings);
|
||||||
@@ -51,7 +51,7 @@ mapbox::base::ValueObject Settings::get(const std::vector<std::string>& keys) co
|
|||||||
}
|
}
|
||||||
|
|
||||||
mapbox::base::Value Settings::get(const std::string& key) const noexcept {
|
mapbox::base::Value Settings::get(const std::string& key) const noexcept {
|
||||||
std::lock_guard<std::mutex> lock(impl->mutex);
|
std::scoped_lock lock(impl->mutex);
|
||||||
return getValue(key, impl->settings);
|
return getValue(key, impl->settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ DebugBucket::DebugBucket(const OverscaledTileID& id,
|
|||||||
std::optional<Point<int16_t>> prev;
|
std::optional<Point<int16_t>> prev;
|
||||||
|
|
||||||
const glyph& glyph = simplex[c - 32];
|
const glyph& glyph = simplex[c - 32];
|
||||||
for (int32_t j = 0; j < glyph.length; j += 2) {
|
for (int32_t j = 0; std::cmp_less(j, glyph.length); j += 2) {
|
||||||
if (glyph.data[j] == -1 && glyph.data[j + 1] == -1) {
|
if (glyph.data[j] == -1 && glyph.data[j + 1] == -1) {
|
||||||
prev = {};
|
prev = {};
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <mbgl/text/cross_tile_symbol_index.hpp>
|
#include <mbgl/text/cross_tile_symbol_index.hpp>
|
||||||
#include <mbgl/text/placement.hpp>
|
#include <mbgl/text/placement.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
@@ -210,7 +211,7 @@ SymbolInstanceReferences SymbolBucket::getSortedSymbols(const float angle) const
|
|||||||
const float sin = std::sin(angle);
|
const float sin = std::sin(angle);
|
||||||
const float cos = std::cos(angle);
|
const float cos = std::cos(angle);
|
||||||
|
|
||||||
std::sort(result.begin(), result.end(), [sin, cos](const SymbolInstance& a, const SymbolInstance& b) {
|
std::ranges::sort(result, [sin, cos](const SymbolInstance& a, const SymbolInstance& b) {
|
||||||
const auto aRotated = std::lround(sin * a.getAnchor().point.x + cos * a.getAnchor().point.y);
|
const auto aRotated = std::lround(sin * a.getAnchor().point.x + cos * a.getAnchor().point.y);
|
||||||
const auto bRotated = std::lround(sin * b.getAnchor().point.x + cos * b.getAnchor().point.y);
|
const auto bRotated = std::lround(sin * b.getAnchor().point.x + cos * b.getAnchor().point.y);
|
||||||
if (aRotated != bRotated) {
|
if (aRotated != bRotated) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ void ImageManager::setObserver(ImageManagerObserver* observer_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImageManager::setLoaded(bool loaded_) {
|
void ImageManager::setLoaded(bool loaded_) {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
if (loaded == loaded_) {
|
if (loaded == loaded_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -45,11 +45,11 @@ bool ImageManager::isLoaded() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImageManager::addImage(Immutable<style::Image::Impl> image_) {
|
void ImageManager::addImage(Immutable<style::Image::Impl> image_) {
|
||||||
std::lock_guard<std::recursive_mutex> readLock(rwLock);
|
std::scoped_lock readLock(rwLock);
|
||||||
assert(images.find(image_->id) == images.end());
|
assert(!images.contains(image_->id));
|
||||||
|
|
||||||
// Increase cache size if requested image was provided.
|
// Increase cache size if requested image was provided.
|
||||||
if (requestedImages.find(image_->id) != requestedImages.end()) {
|
if (requestedImages.contains(image_->id)) {
|
||||||
requestedImagesCacheSize += image_->image.bytes();
|
requestedImagesCacheSize += image_->image.bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ void ImageManager::addImage(Immutable<style::Image::Impl> image_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ImageManager::updateImage(Immutable<style::Image::Impl> image_) {
|
bool ImageManager::updateImage(Immutable<style::Image::Impl> image_) {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
|
|
||||||
auto oldImage = images.find(image_->id);
|
auto oldImage = images.find(image_->id);
|
||||||
assert(oldImage != images.end());
|
assert(oldImage != images.end());
|
||||||
@@ -68,7 +68,7 @@ bool ImageManager::updateImage(Immutable<style::Image::Impl> image_) {
|
|||||||
|
|
||||||
if (sizeChanged) {
|
if (sizeChanged) {
|
||||||
// Update cache size if requested image size has changed.
|
// Update cache size if requested image size has changed.
|
||||||
if (requestedImages.find(image_->id) != requestedImages.end()) {
|
if (requestedImages.contains(image_->id)) {
|
||||||
int64_t diff = image_->image.bytes() - oldImage->second->image.bytes();
|
int64_t diff = image_->image.bytes() - oldImage->second->image.bytes();
|
||||||
assert(static_cast<int64_t>(requestedImagesCacheSize + diff) >= 0ll);
|
assert(static_cast<int64_t>(requestedImagesCacheSize + diff) >= 0ll);
|
||||||
requestedImagesCacheSize += diff;
|
requestedImagesCacheSize += diff;
|
||||||
@@ -84,7 +84,7 @@ bool ImageManager::updateImage(Immutable<style::Image::Impl> image_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImageManager::removeImage(const std::string& id) {
|
void ImageManager::removeImage(const std::string& id) {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
auto it = images.find(id);
|
auto it = images.find(id);
|
||||||
assert(it != images.end());
|
assert(it != images.end());
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ void ImageManager::removeImage(const std::string& id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const style::Image::Impl* ImageManager::getImage(const std::string& id) const {
|
const style::Image::Impl* ImageManager::getImage(const std::string& id) const {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
if (auto* image = getSharedImage(id)) {
|
if (auto* image = getSharedImage(id)) {
|
||||||
return image->get();
|
return image->get();
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ const style::Image::Impl* ImageManager::getImage(const std::string& id) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Immutable<style::Image::Impl>* ImageManager::getSharedImage(const std::string& id) const {
|
const Immutable<style::Image::Impl>* ImageManager::getSharedImage(const std::string& id) const {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
const auto it = images.find(id);
|
const auto it = images.find(id);
|
||||||
if (it != images.end()) {
|
if (it != images.end()) {
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
@@ -122,7 +122,7 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair)
|
|||||||
// remove previous requests from this tile
|
// remove previous requests from this tile
|
||||||
removeRequestor(requestor);
|
removeRequestor(requestor);
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
|
|
||||||
// If all the icon dependencies are already present ((i.e. if they've been addeded via
|
// If all the icon dependencies are already present ((i.e. if they've been addeded via
|
||||||
// runtime styling), then notify the requestor immediately. Otherwise, if the
|
// runtime styling), then notify the requestor immediately. Otherwise, if the
|
||||||
@@ -133,7 +133,7 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair)
|
|||||||
if (!isLoaded()) {
|
if (!isLoaded()) {
|
||||||
bool hasAllDependencies = true;
|
bool hasAllDependencies = true;
|
||||||
for (const auto& dependency : pair.first) {
|
for (const auto& dependency : pair.first) {
|
||||||
if (images.find(dependency.first) == images.end()) {
|
if (!images.contains(dependency.first)) {
|
||||||
hasAllDependencies = false;
|
hasAllDependencies = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImageManager::removeRequestor(ImageRequestor& requestor) {
|
void ImageManager::removeRequestor(ImageRequestor& requestor) {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
|
|
||||||
requestors.erase(&requestor);
|
requestors.erase(&requestor);
|
||||||
missingImageRequestors.erase(&requestor);
|
missingImageRequestors.erase(&requestor);
|
||||||
@@ -160,7 +160,7 @@ void ImageManager::removeRequestor(ImageRequestor& requestor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImageManager::notifyIfMissingImageAdded() {
|
void ImageManager::notifyIfMissingImageAdded() {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
|
|
||||||
for (auto it = missingImageRequestors.begin(); it != missingImageRequestors.end();) {
|
for (auto it = missingImageRequestors.begin(); it != missingImageRequestors.end();) {
|
||||||
ImageRequestor& requestor = *it->first;
|
ImageRequestor& requestor = *it->first;
|
||||||
@@ -174,13 +174,13 @@ void ImageManager::notifyIfMissingImageAdded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImageManager::reduceMemoryUse() {
|
void ImageManager::reduceMemoryUse() {
|
||||||
std::lock_guard<std::recursive_mutex> readLock(rwLock);
|
std::scoped_lock readLock(rwLock);
|
||||||
|
|
||||||
std::vector<std::string> unusedIDs;
|
std::vector<std::string> unusedIDs;
|
||||||
unusedIDs.reserve(requestedImages.size());
|
unusedIDs.reserve(requestedImages.size());
|
||||||
|
|
||||||
for (const auto& pair : requestedImages) {
|
for (const auto& pair : requestedImages) {
|
||||||
if (pair.second.empty() && images.find(pair.first) != images.end()) {
|
if (pair.second.empty() && images.contains(pair.first)) {
|
||||||
unusedIDs.push_back(pair.first);
|
unusedIDs.push_back(pair.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,7 +199,7 @@ void ImageManager::reduceMemoryUseIfCacheSizeExceedsLimit() {
|
|||||||
|
|
||||||
std::set<std::string> ImageManager::getAvailableImages() const {
|
std::set<std::string> ImageManager::getAvailableImages() const {
|
||||||
MLN_TRACE_FUNC();
|
MLN_TRACE_FUNC();
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
|
|
||||||
{
|
{
|
||||||
MLN_TRACE_ZONE(copy);
|
MLN_TRACE_ZONE(copy);
|
||||||
@@ -208,7 +208,7 @@ std::set<std::string> ImageManager::getAvailableImages() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImageManager::clear() {
|
void ImageManager::clear() {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
|
|
||||||
assert(requestors.empty());
|
assert(requestors.empty());
|
||||||
assert(missingImageRequestors.empty());
|
assert(missingImageRequestors.empty());
|
||||||
@@ -224,14 +224,14 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
|
|||||||
ImageDependencies missingDependencies;
|
ImageDependencies missingDependencies;
|
||||||
|
|
||||||
for (const auto& dependency : pair.first) {
|
for (const auto& dependency : pair.first) {
|
||||||
if (images.find(dependency.first) == images.end()) {
|
if (!images.contains(dependency.first)) {
|
||||||
missingDependencies.emplace(dependency);
|
missingDependencies.emplace(dependency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!missingDependencies.empty()) {
|
if (!missingDependencies.empty()) {
|
||||||
ImageRequestor* requestorPtr = &requestor;
|
ImageRequestor* requestorPtr = &requestor;
|
||||||
assert(!missingImageRequestors.count(requestorPtr));
|
assert(!missingImageRequestors.contains(requestorPtr));
|
||||||
missingImageRequestors.emplace(requestorPtr, pair);
|
missingImageRequestors.emplace(requestorPtr, pair);
|
||||||
|
|
||||||
for (const auto& dependency : missingDependencies) {
|
for (const auto& dependency : missingDependencies) {
|
||||||
@@ -261,7 +261,7 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto removePendingRequests = [this, missingImage] {
|
auto removePendingRequests = [this, missingImage] {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
auto existingRequest = requestedImages.find(missingImage);
|
auto existingRequest = requestedImages.find(missingImage);
|
||||||
if (existingRequest == requestedImages.end()) {
|
if (existingRequest == requestedImages.end()) {
|
||||||
return;
|
return;
|
||||||
@@ -277,7 +277,7 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
|
|||||||
} else {
|
} else {
|
||||||
// Associate requestor with an image that was provided by the client.
|
// Associate requestor with an image that was provided by the client.
|
||||||
for (const auto& dependency : pair.first) {
|
for (const auto& dependency : pair.first) {
|
||||||
if (requestedImages.find(dependency.first) != requestedImages.end()) {
|
if (requestedImages.contains(dependency.first)) {
|
||||||
requestedImages[dependency.first].emplace(&requestor);
|
requestedImages[dependency.first].emplace(&requestor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace mbgl {
|
|||||||
using namespace style;
|
using namespace style;
|
||||||
using namespace shaders;
|
using namespace shaders;
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#ifndef NDEBUG
|
||||||
constexpr auto BackgroundPatternShaderName = "BackgroundPatternShader";
|
constexpr auto BackgroundPatternShaderName = "BackgroundPatternShader";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ void BackgroundLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintPara
|
|||||||
const auto& state = parameters.state;
|
const auto& state = parameters.state;
|
||||||
auto& context = parameters.context;
|
auto& context = parameters.context;
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#ifdef DEBUG
|
||||||
const auto label = layerGroup.getName() + "-update-uniforms";
|
const auto label = layerGroup.getName() + "-update-uniforms";
|
||||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
|
|||||||
auto& context = parameters.context;
|
auto& context = parameters.context;
|
||||||
const auto& evaluated = static_cast<const CircleLayerProperties&>(*evaluatedProperties).evaluated;
|
const auto& evaluated = static_cast<const CircleLayerProperties&>(*evaluatedProperties).evaluated;
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#ifndef NDEBUG
|
||||||
const auto label = layerGroup.getName() + "-update-uniforms";
|
const auto label = layerGroup.getName() + "-update-uniforms";
|
||||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ void HeatmapTextureLayerTweaker::execute(LayerGroupBase& layerGroup, const Paint
|
|||||||
|
|
||||||
const auto& evaluated = static_cast<const HeatmapLayerProperties&>(*evaluatedProperties).evaluated;
|
const auto& evaluated = static_cast<const HeatmapLayerProperties&>(*evaluatedProperties).evaluated;
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#ifndef NDEBUG
|
||||||
const auto label = layerGroup.getName() + "-update-uniforms";
|
const auto label = layerGroup.getName() + "-update-uniforms";
|
||||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ void HillshadeLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParam
|
|||||||
|
|
||||||
const auto& evaluated = static_cast<const HillshadeLayerProperties&>(*evaluatedProperties).evaluated;
|
const auto& evaluated = static_cast<const HillshadeLayerProperties&>(*evaluatedProperties).evaluated;
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#ifndef NDEBUG
|
||||||
const auto label = layerGroup.getName() + "-update-uniforms";
|
const auto label = layerGroup.getName() + "-update-uniforms";
|
||||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#include <mbgl/renderer/update_parameters.hpp>
|
#include <mbgl/renderer/update_parameters.hpp>
|
||||||
#include <mbgl/shaders/shader_program_base.hpp>
|
#include <mbgl/shaders/shader_program_base.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
using namespace style;
|
using namespace style;
|
||||||
@@ -118,10 +120,10 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
[[maybe_unused]] UniqueChangeRequestVec& changes) {
|
[[maybe_unused]] UniqueChangeRequestVec& changes) {
|
||||||
assert(updateParameters);
|
assert(updateParameters);
|
||||||
const auto zoom = state.getIntegerZoom();
|
const auto zoom = state.getIntegerZoom();
|
||||||
const auto tileCover = util::tileCover({state,
|
const auto tileCover = util::tileCover({.transformState = state,
|
||||||
updateParameters->tileLodMinRadius,
|
.tileLodMinRadius = updateParameters->tileLodMinRadius,
|
||||||
updateParameters->tileLodScale,
|
.tileLodScale = updateParameters->tileLodScale,
|
||||||
updateParameters->tileLodPitchThreshold},
|
.tileLodPitchThreshold = updateParameters->tileLodPitchThreshold},
|
||||||
zoom);
|
zoom);
|
||||||
|
|
||||||
// renderTiles is always empty, we use tileCover instead
|
// renderTiles is always empty, we use tileCover instead
|
||||||
@@ -191,8 +193,7 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
// Remove drawables for tiles that are no longer in the cover set.
|
// Remove drawables for tiles that are no longer in the cover set.
|
||||||
// (Note that `RenderTiles` is empty, and this layer does not use it)
|
// (Note that `RenderTiles` is empty, and this layer does not use it)
|
||||||
tileLayerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) -> bool {
|
tileLayerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) -> bool {
|
||||||
return drawable.getTileID() &&
|
return drawable.getTileID() && (std::ranges::find(tileCover, *drawable.getTileID()) == tileCover.end());
|
||||||
(std::find(tileCover.begin(), tileCover.end(), *drawable.getTileID()) == tileCover.end());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// For each tile in the cover set, add a tile drawable if one doesn't already exist.
|
// For each tile in the cover set, add a tile drawable if one doesn't already exist.
|
||||||
|
|||||||
@@ -1277,11 +1277,11 @@ void RenderLocationIndicatorLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
if (info.textureInfo.image) {
|
if (info.textureInfo.image) {
|
||||||
if (!info.textureInfo.texture) {
|
if (!info.textureInfo.texture) {
|
||||||
info.textureInfo.texture = context.createTexture2D();
|
info.textureInfo.texture = context.createTexture2D();
|
||||||
info.textureInfo.texture->setSamplerConfiguration({gfx::TextureFilterType::Linear,
|
info.textureInfo.texture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||||
gfx::TextureWrapType::Clamp,
|
.wrapU = gfx::TextureWrapType::Clamp,
|
||||||
gfx::TextureWrapType::Clamp,
|
.wrapV = gfx::TextureWrapType::Clamp,
|
||||||
16,
|
.maxAnisotropy = 16,
|
||||||
true});
|
.mipmapped = true});
|
||||||
}
|
}
|
||||||
|
|
||||||
info.textureInfo.texture->upload(info.textureInfo.image->get()->image);
|
info.textureInfo.texture->upload(info.textureInfo.image->get()->image);
|
||||||
|
|||||||
@@ -243,8 +243,11 @@ void RenderSymbolLayer::prepare(const LayerPrepareParameters& params) {
|
|||||||
.featureIndex = featureIndex,
|
.featureIndex = featureIndex,
|
||||||
.sourceId = baseImpl->source,
|
.sourceId = baseImpl->source,
|
||||||
.sortKeyRange = sortKeyRange};
|
.sortKeyRange = sortKeyRange};
|
||||||
auto sortPosition = std::upper_bound(
|
auto sortPosition = std::upper_bound( // NOLINT(modernize-use-ranges)
|
||||||
placementData.cbegin(), placementData.cend(), layerData, [](const auto& lhs, const auto& rhs) {
|
placementData.cbegin(),
|
||||||
|
placementData.cend(),
|
||||||
|
layerData,
|
||||||
|
[](const auto& lhs, const auto& rhs) {
|
||||||
assert(lhs.sortKeyRange && rhs.sortKeyRange);
|
assert(lhs.sortKeyRange && rhs.sortKeyRange);
|
||||||
return lhs.sortKeyRange->sortKey < rhs.sortKeyRange->sortKey;
|
return lhs.sortKeyRange->sortKey < rhs.sortKeyRange->sortKey;
|
||||||
});
|
});
|
||||||
@@ -546,7 +549,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
}
|
}
|
||||||
setRenderTileBucketID(tileID, bucket.getID());
|
setRenderTileBucketID(tileID, bucket.getID());
|
||||||
|
|
||||||
assert(bucket.paintProperties.find(getID()) != bucket.paintProperties.end());
|
assert(bucket.paintProperties.contains(getID()));
|
||||||
const auto& bucketPaintProperties = bucket.paintProperties.at(getID());
|
const auto& bucketPaintProperties = bucket.paintProperties.at(getID());
|
||||||
|
|
||||||
auto addCollisionDrawables = [&](const bool isText, const bool hasCollisionBox, const bool hasCollisionCircle) {
|
auto addCollisionDrawables = [&](const bool isText, const bool hasCollisionBox, const bool hasCollisionCircle) {
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ gfx::DepthMode PaintParameters::depthModeForSublayer([[maybe_unused]] uint8_t n,
|
|||||||
float depth = depthRangeSize + ((1 + currentLayer) * numSublayers + n) * depthEpsilon;
|
float depth = depthRangeSize + ((1 + currentLayer) * numSublayers + n) * depthEpsilon;
|
||||||
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, mask, {depth, depth}};
|
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, mask, {depth, depth}};
|
||||||
#else
|
#else
|
||||||
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, mask};
|
return gfx::DepthMode{.func = gfx::DepthFunctionType::LessEqual, .mask = mask};
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ gfx::DepthMode PaintParameters::depthModeFor3D() const {
|
|||||||
#if MLN_RENDER_BACKEND_OPENGL
|
#if MLN_RENDER_BACKEND_OPENGL
|
||||||
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, gfx::DepthMaskType::ReadWrite, {0.0, depthRangeSize}};
|
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, gfx::DepthMaskType::ReadWrite, {0.0, depthRangeSize}};
|
||||||
#else
|
#else
|
||||||
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, gfx::DepthMaskType::ReadWrite};
|
return gfx::DepthMode{.func = gfx::DepthFunctionType::LessEqual, .mask = gfx::DepthMaskType::ReadWrite};
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,12 +150,8 @@ void PaintParameters::clearStencil() {
|
|||||||
const auto debugGroup = renderPass->createDebugGroup("tile-clip-mask-clear");
|
const auto debugGroup = renderPass->createDebugGroup("tile-clip-mask-clear");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const std::vector<shaders::ClipUBO> tileUBO = {
|
const std::vector<shaders::ClipUBO> tileUBO = {shaders::ClipUBO{
|
||||||
shaders::ClipUBO{/* .matrix = */ util::cast<float>(matrixForTile({0, 0, 0})),
|
.matrix = util::cast<float>(matrixForTile({0, 0, 0})), .stencil_ref = 0, .pad1 = 0, .pad2 = 0, .pad3 = 0}};
|
||||||
/* .stencil_ref = */ 0,
|
|
||||||
/* .pad1 = */ 0,
|
|
||||||
/* .pad2 = */ 0,
|
|
||||||
/* .pad3 = */ 0}};
|
|
||||||
mtlContext.renderTileClippingMasks(*renderPass, staticData, tileUBO);
|
mtlContext.renderTileClippingMasks(*renderPass, staticData, tileUBO);
|
||||||
context.renderingStats().stencilClears++;
|
context.renderingStats().stencilClears++;
|
||||||
#elif MLN_RENDER_BACKEND_VULKAN
|
#elif MLN_RENDER_BACKEND_VULKAN
|
||||||
@@ -239,11 +235,11 @@ void PaintParameters::renderTileClippingMasks(const RenderTiles& renderTiles) {
|
|||||||
tileUBOs.reserve(count);
|
tileUBOs.reserve(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
tileUBOs.emplace_back(shaders::ClipUBO{/* .matrix = */ util::cast<float>(matrixForTile(tileID)),
|
tileUBOs.emplace_back(shaders::ClipUBO{.matrix = util::cast<float>(matrixForTile(tileID)),
|
||||||
/* .stencil_ref = */ static_cast<uint32_t>(stencilID),
|
.stencil_ref = static_cast<uint32_t>(stencilID),
|
||||||
/* .pad1 = */ 0,
|
.pad1 = 0,
|
||||||
/* .pad2 = */ 0,
|
.pad2 = 0,
|
||||||
/* .pad3 = */ 0});
|
.pad3 = 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tileUBOs.empty()) {
|
if (!tileUBOs.empty()) {
|
||||||
@@ -347,12 +343,12 @@ gfx::StencilMode PaintParameters::stencilModeForClipping(const UnwrappedTileID&
|
|||||||
auto it = tileClippingMaskIDs.find(tileID);
|
auto it = tileClippingMaskIDs.find(tileID);
|
||||||
assert(it != tileClippingMaskIDs.end());
|
assert(it != tileClippingMaskIDs.end());
|
||||||
const int32_t id = it != tileClippingMaskIDs.end() ? it->second : 0b00000000;
|
const int32_t id = it != tileClippingMaskIDs.end() ? it->second : 0b00000000;
|
||||||
return gfx::StencilMode{gfx::StencilMode::Equal{0b11111111},
|
return gfx::StencilMode{.test = gfx::StencilMode::Equal{0b11111111},
|
||||||
id,
|
.ref = id,
|
||||||
0b00000000,
|
.mask = 0b00000000,
|
||||||
gfx::StencilOpType::Keep,
|
.fail = gfx::StencilOpType::Keep,
|
||||||
gfx::StencilOpType::Keep,
|
.depthFail = gfx::StencilOpType::Keep,
|
||||||
gfx::StencilOpType::Replace};
|
.pass = gfx::StencilOpType::Replace};
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::StencilMode PaintParameters::stencilModeFor3D() {
|
gfx::StencilMode PaintParameters::stencilModeFor3D() {
|
||||||
@@ -365,21 +361,21 @@ gfx::StencilMode PaintParameters::stencilModeFor3D() {
|
|||||||
tileClippingMaskIDs.clear();
|
tileClippingMaskIDs.clear();
|
||||||
|
|
||||||
const int32_t id = nextStencilID++;
|
const int32_t id = nextStencilID++;
|
||||||
return gfx::StencilMode{gfx::StencilMode::NotEqual{0b11111111},
|
return gfx::StencilMode{.test = gfx::StencilMode::NotEqual{0b11111111},
|
||||||
id,
|
.ref = id,
|
||||||
0b11111111,
|
.mask = 0b11111111,
|
||||||
gfx::StencilOpType::Keep,
|
.fail = gfx::StencilOpType::Keep,
|
||||||
gfx::StencilOpType::Keep,
|
.depthFail = gfx::StencilOpType::Keep,
|
||||||
gfx::StencilOpType::Replace};
|
.pass = gfx::StencilOpType::Replace};
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::ColorMode PaintParameters::colorModeForRenderPass() const {
|
gfx::ColorMode PaintParameters::colorModeForRenderPass() const {
|
||||||
if (debugOptions & MapDebugOptions::Overdraw) {
|
if (debugOptions & MapDebugOptions::Overdraw) {
|
||||||
constexpr float overdraw = 1.0f / 8.0f;
|
constexpr float overdraw = 1.0f / 8.0f;
|
||||||
return gfx::ColorMode{
|
return gfx::ColorMode{.blendFunction = gfx::ColorMode::Add{gfx::ColorBlendFactorType::ConstantColor,
|
||||||
gfx::ColorMode::Add{gfx::ColorBlendFactorType::ConstantColor, gfx::ColorBlendFactorType::One},
|
gfx::ColorBlendFactorType::One},
|
||||||
Color{overdraw, overdraw, overdraw, 0.0f},
|
.blendColor = Color{overdraw, overdraw, overdraw, 0.0f},
|
||||||
gfx::ColorMode::Mask{true, true, true, true}};
|
.mask = gfx::ColorMode::Mask{.r = true, .g = true, .b = true, .a = true}};
|
||||||
} else if (pass == RenderPass::Translucent) {
|
} else if (pass == RenderPass::Translucent) {
|
||||||
return gfx::ColorMode::alphaBlended();
|
return gfx::ColorMode::alphaBlended();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ std::optional<ImagePosition> PatternAtlas::getPattern(const std::string& id) con
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ImagePosition> PatternAtlas::addPattern(const style::Image::Impl& image) {
|
std::optional<ImagePosition> PatternAtlas::addPattern(const style::Image::Impl& image) {
|
||||||
if (patterns.find(image.id) != patterns.end()) {
|
if (patterns.contains(image.id)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
const uint16_t width = image.image.size.width + padding * 2;
|
const uint16_t width = image.image.size.width + padding * 2;
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include <mbgl/util/string.hpp>
|
#include <mbgl/util/string.hpp>
|
||||||
#include <mbgl/util/logging.hpp>
|
#include <mbgl/util/logging.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
using namespace style;
|
using namespace style;
|
||||||
@@ -585,10 +587,8 @@ void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, st
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<std::string, const RenderLayer*> crossTileSymbolIndexLayers;
|
std::unordered_map<std::string, const RenderLayer*> crossTileSymbolIndexLayers;
|
||||||
std::copy_if(layers.begin(),
|
std::ranges::copy_if(
|
||||||
layers.end(),
|
layers, std::inserter(crossTileSymbolIndexLayers, crossTileSymbolIndexLayers.begin()), hasCrossTileIndex);
|
||||||
std::inserter(crossTileSymbolIndexLayers, crossTileSymbolIndexLayers.begin()),
|
|
||||||
hasCrossTileIndex);
|
|
||||||
|
|
||||||
if (crossTileSymbolIndexLayers.empty()) {
|
if (crossTileSymbolIndexLayers.empty()) {
|
||||||
return;
|
return;
|
||||||
@@ -603,11 +603,10 @@ void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, st
|
|||||||
// Although symbol query is global, symbol results are only sortable within
|
// Although symbol query is global, symbol results are only sortable within
|
||||||
// a bucket For a predictable global sort renderItems, we sort the buckets
|
// a bucket For a predictable global sort renderItems, we sort the buckets
|
||||||
// based on their corresponding tile position
|
// based on their corresponding tile position
|
||||||
std::sort(
|
std::ranges::sort(bucketQueryData, [](const RetainedQueryData& a, const RetainedQueryData& b) {
|
||||||
bucketQueryData.begin(), bucketQueryData.end(), [](const RetainedQueryData& a, const RetainedQueryData& b) {
|
return std::tie(a.tileID.canonical.z, a.tileID.canonical.y, a.tileID.wrap, a.tileID.canonical.x) <
|
||||||
return std::tie(a.tileID.canonical.z, a.tileID.canonical.y, a.tileID.wrap, a.tileID.canonical.x) <
|
std::tie(b.tileID.canonical.z, b.tileID.canonical.y, b.tileID.wrap, b.tileID.canonical.x);
|
||||||
std::tie(b.tileID.canonical.z, b.tileID.canonical.y, b.tileID.wrap, b.tileID.canonical.x);
|
});
|
||||||
});
|
|
||||||
|
|
||||||
for (auto wrappedQueryData : bucketQueryData) {
|
for (auto wrappedQueryData : bucketQueryData) {
|
||||||
auto& queryData = wrappedQueryData.get();
|
auto& queryData = wrappedQueryData.get();
|
||||||
@@ -619,7 +618,7 @@ void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, st
|
|||||||
|
|
||||||
for (auto layer : bucketSymbols) {
|
for (auto layer : bucketSymbols) {
|
||||||
auto& resultFeatures = resultsByLayer[layer.first];
|
auto& resultFeatures = resultsByLayer[layer.first];
|
||||||
std::move(layer.second.begin(), layer.second.end(), std::inserter(resultFeatures, resultFeatures.end()));
|
std::ranges::move(layer.second, std::inserter(resultFeatures, resultFeatures.end()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -648,8 +647,7 @@ std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(
|
|||||||
if (RenderSource* renderSource = getRenderSource(sourceID)) {
|
if (RenderSource* renderSource = getRenderSource(sourceID)) {
|
||||||
auto sourceResults = renderSource->queryRenderedFeatures(
|
auto sourceResults = renderSource->queryRenderedFeatures(
|
||||||
geometry, transformState, filteredLayers, options, projMatrix);
|
geometry, transformState, filteredLayers, options, projMatrix);
|
||||||
std::move(
|
std::ranges::move(sourceResults, std::inserter(resultsByLayer, resultsByLayer.begin()));
|
||||||
sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -991,7 +989,7 @@ void RenderOrchestrator::processChanges() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RenderOrchestrator::addRenderTarget(RenderTargetPtr renderTarget) {
|
bool RenderOrchestrator::addRenderTarget(RenderTargetPtr renderTarget) {
|
||||||
auto it = std::find(renderTargets.begin(), renderTargets.end(), renderTarget);
|
auto it = std::ranges::find(renderTargets, renderTarget);
|
||||||
if (it == renderTargets.end()) {
|
if (it == renderTargets.end()) {
|
||||||
renderTargets.emplace_back(renderTarget);
|
renderTargets.emplace_back(renderTarget);
|
||||||
return true;
|
return true;
|
||||||
@@ -1001,7 +999,7 @@ bool RenderOrchestrator::addRenderTarget(RenderTargetPtr renderTarget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RenderOrchestrator::removeRenderTarget(const RenderTargetPtr& renderTarget) {
|
bool RenderOrchestrator::removeRenderTarget(const RenderTargetPtr& renderTarget) {
|
||||||
auto it = std::find(renderTargets.begin(), renderTargets.end(), renderTarget);
|
auto it = std::ranges::find(renderTargets, renderTarget);
|
||||||
if (it != renderTargets.end()) {
|
if (it != renderTargets.end()) {
|
||||||
renderTargets.erase(it);
|
renderTargets.erase(it);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ void RenderTarget::render(RenderOrchestrator& orchestrator, const RenderTree& re
|
|||||||
|
|
||||||
const gfx::ScissorRect prevSicssorRect = parameters.scissorRect;
|
const gfx::ScissorRect prevSicssorRect = parameters.scissorRect;
|
||||||
const auto& size = getTexture()->getSize();
|
const auto& size = getTexture()->getSize();
|
||||||
parameters.scissorRect = {0, 0, size.width, size.height};
|
parameters.scissorRect = {.x = 0, .y = 0, .width = size.width, .height = size.height};
|
||||||
|
|
||||||
// Run layer tweakers to update any dynamic elements
|
// Run layer tweakers to update any dynamic elements
|
||||||
parameters.currentLayer = 0;
|
parameters.currentLayer = 0;
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include <mbgl/renderer/update_parameters.hpp>
|
#include <mbgl/renderer/update_parameters.hpp>
|
||||||
#include <mbgl/util/instrumentation.hpp>
|
#include <mbgl/util/instrumentation.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
Renderer::Renderer(gfx::RendererBackend& backend, float pixelRatio_, const std::optional<std::string>& localFontFamily_)
|
Renderer::Renderer(gfx::RendererBackend& backend, float pixelRatio_, const std::optional<std::string>& localFontFamily_)
|
||||||
@@ -91,7 +93,7 @@ AnnotationIDs Renderer::getAnnotationIDs(const std::vector<Feature>& features) c
|
|||||||
}
|
}
|
||||||
AnnotationIDs ids;
|
AnnotationIDs ids;
|
||||||
ids.reserve(set.size());
|
ids.reserve(set.size());
|
||||||
std::move(set.begin(), set.end(), std::back_inserter(ids));
|
std::ranges::move(set, std::back_inserter(ids));
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ void Renderer::Impl::render(const RenderTree& renderTree, const std::shared_ptr<
|
|||||||
if (!commandCaptureScope) {
|
if (!commandCaptureScope) {
|
||||||
if (const auto& cmdQueue = mtlBackend.getCommandQueue()) {
|
if (const auto& cmdQueue = mtlBackend.getCommandQueue()) {
|
||||||
if (const auto captureManager = NS::RetainPtr(MTL::CaptureManager::sharedCaptureManager())) {
|
if (const auto captureManager = NS::RetainPtr(MTL::CaptureManager::sharedCaptureManager())) {
|
||||||
|
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
|
||||||
if ((commandCaptureScope = NS::TransferPtr(captureManager->newCaptureScope(cmdQueue.get())))) {
|
if ((commandCaptureScope = NS::TransferPtr(captureManager->newCaptureScope(cmdQueue.get())))) {
|
||||||
const auto label = "Renderer::Impl frame=" + util::toString(frameCount);
|
const auto label = "Renderer::Impl frame=" + util::toString(frameCount);
|
||||||
commandCaptureScope->setLabel(NS::String::string(label.c_str(), NS::UTF8StringEncoding));
|
commandCaptureScope->setLabel(NS::String::string(label.c_str(), NS::UTF8StringEncoding));
|
||||||
|
|||||||
@@ -133,9 +133,11 @@ void RenderImageSource::update(Immutable<style::Source::Impl> baseImpl_,
|
|||||||
|
|
||||||
bool hasVisibleTile = false;
|
bool hasVisibleTile = false;
|
||||||
// Add additional wrapped tile ids if neccessary
|
// Add additional wrapped tile ids if neccessary
|
||||||
auto idealTiles = util::tileCover(
|
auto idealTiles = util::tileCover({.transformState = transformState,
|
||||||
{transformState, parameters.tileLodMinRadius, parameters.tileLodScale, parameters.tileLodPitchThreshold},
|
.tileLodMinRadius = parameters.tileLodMinRadius,
|
||||||
static_cast<uint8_t>(transformState.getZoom()));
|
.tileLodScale = parameters.tileLodScale,
|
||||||
|
.tileLodPitchThreshold = parameters.tileLodPitchThreshold},
|
||||||
|
static_cast<uint8_t>(transformState.getZoom()));
|
||||||
for (auto tile : idealTiles) {
|
for (auto tile : idealTiles) {
|
||||||
if (tile.wrap != 0 && tileCover[0].canonical.isChildOf(tile.canonical)) {
|
if (tile.wrap != 0 && tileCover[0].canonical.isChildOf(tile.canonical)) {
|
||||||
tileIds.emplace_back(tile.wrap, tileCover[0].canonical);
|
tileIds.emplace_back(tile.wrap, tileCover[0].canonical);
|
||||||
|
|||||||
@@ -90,13 +90,13 @@ public:
|
|||||||
assert(propsUBO.expressionMask == LineExpressionMask::None);
|
assert(propsUBO.expressionMask == LineExpressionMask::None);
|
||||||
|
|
||||||
const LineExpressionUBO exprUBO = {
|
const LineExpressionUBO exprUBO = {
|
||||||
/* .color = */ nullptr,
|
.color = nullptr,
|
||||||
/* .blur = */ nullptr,
|
.blur = nullptr,
|
||||||
/* .opacity = */ nullptr,
|
.opacity = nullptr,
|
||||||
/* .gapwidth = */ nullptr,
|
.gapwidth = nullptr,
|
||||||
/* .offset = */ nullptr,
|
.offset = nullptr,
|
||||||
/* .width = */ nullptr,
|
.width = nullptr,
|
||||||
/* .floorWidth = */ nullptr,
|
.floorWidth = nullptr,
|
||||||
};
|
};
|
||||||
layerUniforms.createOrUpdate(idLineExpressionUBO, &exprUBO, context);
|
layerUniforms.createOrUpdate(idLineExpressionUBO, &exprUBO, context);
|
||||||
|
|
||||||
@@ -122,16 +122,15 @@ public:
|
|||||||
#else
|
#else
|
||||||
const shaders::LineDrawableUBO drawableUBO = {
|
const shaders::LineDrawableUBO drawableUBO = {
|
||||||
#endif
|
#endif
|
||||||
/* .matrix = */ util::cast<float>(matrix),
|
.matrix = util::cast<float>(matrix),
|
||||||
/* .ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, zoom),
|
.ratio = 1.0f / tileID.pixelsToTileUnits(1.0f, zoom),
|
||||||
|
.color_t = 0.f,
|
||||||
/* .color_t = */ 0.f,
|
.blur_t = 0.f,
|
||||||
/* .blur_t = */ 0.f,
|
.opacity_t = 0.f,
|
||||||
/* .opacity_t = */ 0.f,
|
.gapwidth_t = 0.f,
|
||||||
/* .gapwidth_t = */ 0.f,
|
.offset_t = 0.f,
|
||||||
/* .offset_t = */ 0.f,
|
.width_t = 0.f,
|
||||||
/* .width_t = */ 0.f,
|
.pad1 = 0
|
||||||
/* .pad1 = */ 0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if MLN_UBO_CONSOLIDATION
|
#if MLN_UBO_CONSOLIDATION
|
||||||
@@ -255,8 +254,9 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
|||||||
std::array<uint8_t, 4> data{{0, 0, 0, 0}};
|
std::array<uint8_t, 4> data{{0, 0, 0, 0}};
|
||||||
auto emptyImage = std::make_shared<PremultipliedImage>(Size(1, 1), data.data(), data.size());
|
auto emptyImage = std::make_shared<PremultipliedImage>(Size(1, 1), data.data(), data.size());
|
||||||
texture->setImage(emptyImage);
|
texture->setImage(emptyImage);
|
||||||
texture->setSamplerConfiguration(
|
texture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
.wrapU = gfx::TextureWrapType::Clamp,
|
||||||
|
.wrapV = gfx::TextureWrapType::Clamp});
|
||||||
}
|
}
|
||||||
|
|
||||||
// function to update existing tile drawables with UBO value. return number of updated drawables
|
// function to update existing tile drawables with UBO value. return number of updated drawables
|
||||||
@@ -301,15 +301,15 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if MLN_ENABLE_POLYLINE_DRAWABLES
|
#if MLN_ENABLE_POLYLINE_DRAWABLES
|
||||||
const shaders::LineEvaluatedPropsUBO linePropertiesUBO = {/* .color = */ Color::red(),
|
const shaders::LineEvaluatedPropsUBO linePropertiesUBO = {.color = Color::red(),
|
||||||
/* .blur = */ 0.f,
|
.blur = 0.f,
|
||||||
/* .opacity = */ 1.f,
|
.opacity = 1.f,
|
||||||
/* .gapwidth = */ 0.f,
|
.gapwidth = 0.f,
|
||||||
/* .offset = */ 0.f,
|
.offset = 0.f,
|
||||||
/* .width = */ 4.f,
|
.width = 4.f,
|
||||||
/* .floorwidth = */ 0,
|
.floorwidth = 0,
|
||||||
/* .expressionMask = */ LineExpressionMask::None,
|
.expressionMask = LineExpressionMask::None,
|
||||||
/* .pad1 = */ 0};
|
.pad1 = 0};
|
||||||
|
|
||||||
// function to add polylines drawable
|
// function to add polylines drawable
|
||||||
const auto addPolylineDrawable = [&](TileLayerGroup* tileLayerGroup, const RenderTile& tile) {
|
const auto addPolylineDrawable = [&](TileLayerGroup* tileLayerGroup, const RenderTile& tile) {
|
||||||
@@ -358,12 +358,12 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
|||||||
const auto& debugBucket = tile.debugBucket;
|
const auto& debugBucket = tile.debugBucket;
|
||||||
if (!debugBucket) continue;
|
if (!debugBucket) continue;
|
||||||
|
|
||||||
const DebugUBO outlineUBO = {/* .matrix = */ util::cast<float>(tile.matrix),
|
const DebugUBO outlineUBO = {.matrix = util::cast<float>(tile.matrix),
|
||||||
/* .color = */ Color::white(),
|
.color = Color::white(),
|
||||||
/* .overlay_scale = */ 1.0f,
|
.overlay_scale = 1.0f,
|
||||||
/* .pad1 = */ 0,
|
.pad1 = 0,
|
||||||
/* .pad2 = */ 0,
|
.pad2 = 0,
|
||||||
/* .pad3 = */ 0};
|
.pad3 = 0};
|
||||||
if (0 == updateDrawables(outlineLayerGroup, tileID, outlineUBO)) {
|
if (0 == updateDrawables(outlineLayerGroup, tileID, outlineUBO)) {
|
||||||
addDrawable(outlineLayerGroup,
|
addDrawable(outlineLayerGroup,
|
||||||
tileID,
|
tileID,
|
||||||
@@ -374,12 +374,12 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
|||||||
debugBucket->segments);
|
debugBucket->segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
const DebugUBO textUBO = {/* .matrix = */ util::cast<float>(tile.matrix),
|
const DebugUBO textUBO = {.matrix = util::cast<float>(tile.matrix),
|
||||||
/* .color = */ Color::black(),
|
.color = Color::black(),
|
||||||
/* .overlay_scale = */ 1.0f,
|
.overlay_scale = 1.0f,
|
||||||
/* .pad1 = */ 0,
|
.pad1 = 0,
|
||||||
/* .pad2 = */ 0,
|
.pad2 = 0,
|
||||||
/* .pad3 = */ 0};
|
.pad3 = 0};
|
||||||
if (0 == updateDrawables(textLayerGroup, tileID, textUBO) && tile.getNeedsRendering()) {
|
if (0 == updateDrawables(textLayerGroup, tileID, textUBO) && tile.getNeedsRendering()) {
|
||||||
addDrawable(textLayerGroup,
|
addDrawable(textLayerGroup,
|
||||||
tileID,
|
tileID,
|
||||||
|
|||||||
@@ -110,12 +110,12 @@ void TilePyramid::update(const std::vector<Immutable<style::LayerProperties>>& l
|
|||||||
std::vector<OverscaledTileID> idealTiles;
|
std::vector<OverscaledTileID> idealTiles;
|
||||||
std::vector<OverscaledTileID> panTiles;
|
std::vector<OverscaledTileID> panTiles;
|
||||||
|
|
||||||
util::TileCoverParameters tileCoverParameters = {parameters.transformState,
|
util::TileCoverParameters tileCoverParameters = {.transformState = parameters.transformState,
|
||||||
parameters.tileLodMinRadius,
|
.tileLodMinRadius = parameters.tileLodMinRadius,
|
||||||
parameters.tileLodScale,
|
.tileLodScale = parameters.tileLodScale,
|
||||||
parameters.tileLodPitchThreshold};
|
.tileLodPitchThreshold = parameters.tileLodPitchThreshold};
|
||||||
|
|
||||||
if (overscaledZoom >= zoomRange.min) {
|
if (std::cmp_greater_equal(overscaledZoom, zoomRange.min)) {
|
||||||
int32_t idealZoom = std::min<int32_t>(zoomRange.max, overscaledZoom);
|
int32_t idealZoom = std::min<int32_t>(zoomRange.max, overscaledZoom);
|
||||||
|
|
||||||
// Make sure we're not reparsing overzoomed raster tiles.
|
// Make sure we're not reparsing overzoomed raster tiles.
|
||||||
@@ -158,7 +158,7 @@ void TilePyramid::update(const std::vector<Immutable<style::LayerProperties>>& l
|
|||||||
|
|
||||||
auto retainTileFn = [&](Tile& tile, TileNecessity necessity) -> void {
|
auto retainTileFn = [&](Tile& tile, TileNecessity necessity) -> void {
|
||||||
if (retain.emplace(tile.id).second) {
|
if (retain.emplace(tile.id).second) {
|
||||||
tile.setUpdateParameters({minimumUpdateInterval, isVolatile});
|
tile.setUpdateParameters({.minimumUpdateInterval = minimumUpdateInterval, .isVolatile = isVolatile});
|
||||||
tile.setNecessity(necessity);
|
tile.setNecessity(necessity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace mbgl {
|
|||||||
|
|
||||||
using namespace shaders;
|
using namespace shaders;
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(modernize-use-ranges)
|
||||||
MBGL_DEFINE_ENUM(BuiltIn,
|
MBGL_DEFINE_ENUM(BuiltIn,
|
||||||
{{BuiltIn::None, "None"},
|
{{BuiltIn::None, "None"},
|
||||||
{BuiltIn::Prelude, "Prelude"},
|
{BuiltIn::Prelude, "Prelude"},
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ void SpriteLoader::load(const std::optional<style::Sprite> sprite, FileSource& f
|
|||||||
|
|
||||||
dataMap[id] = std::make_unique<Data>();
|
dataMap[id] = std::make_unique<Data>();
|
||||||
dataMap[id]->jsonRequest = fileSource.request(Resource::spriteJSON(url, pixelRatio), [this, sprite](Response res) {
|
dataMap[id]->jsonRequest = fileSource.request(Resource::spriteJSON(url, pixelRatio), [this, sprite](Response res) {
|
||||||
std::lock_guard<std::mutex> lock(dataMapMutex);
|
std::scoped_lock lock(dataMapMutex);
|
||||||
Data* data = dataMap[sprite->id].get();
|
Data* data = dataMap[sprite->id].get();
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
observer->onSpriteError(sprite, std::make_exception_ptr(std::runtime_error(res.error->message)));
|
observer->onSpriteError(sprite, std::make_exception_ptr(std::runtime_error(res.error->message)));
|
||||||
@@ -68,7 +68,7 @@ void SpriteLoader::load(const std::optional<style::Sprite> sprite, FileSource& f
|
|||||||
|
|
||||||
dataMap[id]->spriteRequest = fileSource.request(
|
dataMap[id]->spriteRequest = fileSource.request(
|
||||||
Resource::spriteImage(url, pixelRatio), [this, sprite](Response res) {
|
Resource::spriteImage(url, pixelRatio), [this, sprite](Response res) {
|
||||||
std::lock_guard<std::mutex> lock(dataMapMutex);
|
std::scoped_lock lock(dataMapMutex);
|
||||||
Data* data = dataMap[sprite->id].get();
|
Data* data = dataMap[sprite->id].get();
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
observer->onSpriteError(sprite, std::make_exception_ptr(std::runtime_error(res.error->message)));
|
observer->onSpriteError(sprite, std::make_exception_ptr(std::runtime_error(res.error->message)));
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
@@ -31,7 +32,8 @@ std::unique_ptr<style::Image> createStyleImage(const std::string& id,
|
|||||||
const std::optional<style::TextFit>& textFitHeight) {
|
const std::optional<style::TextFit>& textFitHeight) {
|
||||||
// Disallow invalid parameter configurations.
|
// Disallow invalid parameter configurations.
|
||||||
if (width <= 0 || height <= 0 || width > 1024 || height > 1024 || ratio <= 0 || ratio > 10 || srcX < 0 ||
|
if (width <= 0 || height <= 0 || width > 1024 || height > 1024 || ratio <= 0 || ratio > 10 || srcX < 0 ||
|
||||||
srcY < 0 || srcX >= static_cast<int32_t>(image.size.width) || srcY >= static_cast<int32_t>(image.size.height) ||
|
srcY < 0 || std::cmp_greater_equal(srcX, static_cast<int32_t>(image.size.width)) ||
|
||||||
|
std::cmp_greater_equal(srcY, static_cast<int32_t>(image.size.height)) ||
|
||||||
srcX + width > static_cast<int32_t>(image.size.width) ||
|
srcX + width > static_cast<int32_t>(image.size.width) ||
|
||||||
srcY + height > static_cast<int32_t>(image.size.height)) {
|
srcY + height > static_cast<int32_t>(image.size.height)) {
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
@@ -145,10 +147,10 @@ std::optional<style::ImageContent> getContent(const JSValue& value, const char*
|
|||||||
if (content.IsArray() && content.Size() == 4 && content[rapidjson::SizeType(0)].IsNumber() &&
|
if (content.IsArray() && content.Size() == 4 && content[rapidjson::SizeType(0)].IsNumber() &&
|
||||||
content[rapidjson::SizeType(1)].IsNumber() && content[rapidjson::SizeType(2)].IsNumber() &&
|
content[rapidjson::SizeType(1)].IsNumber() && content[rapidjson::SizeType(2)].IsNumber() &&
|
||||||
content[rapidjson::SizeType(3)].IsNumber()) {
|
content[rapidjson::SizeType(3)].IsNumber()) {
|
||||||
return style::ImageContent{content[rapidjson::SizeType(0)].GetFloat(),
|
return style::ImageContent{.left = content[rapidjson::SizeType(0)].GetFloat(),
|
||||||
content[rapidjson::SizeType(1)].GetFloat(),
|
.top = content[rapidjson::SizeType(1)].GetFloat(),
|
||||||
content[rapidjson::SizeType(2)].GetFloat(),
|
.right = content[rapidjson::SizeType(2)].GetFloat(),
|
||||||
content[rapidjson::SizeType(3)].GetFloat()};
|
.bottom = content[rapidjson::SizeType(3)].GetFloat()};
|
||||||
} else {
|
} else {
|
||||||
Log::Warning(Event::Sprite,
|
Log::Warning(Event::Sprite,
|
||||||
"Invalid sprite image '" + std::string(name) + "': value of '" + property +
|
"Invalid sprite image '" + std::string(name) + "': value of '" + property +
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ FileSourceManager::~FileSourceManager() = default;
|
|||||||
std::shared_ptr<FileSource> FileSourceManager::getFileSource(FileSourceType type,
|
std::shared_ptr<FileSource> FileSourceManager::getFileSource(FileSourceType type,
|
||||||
const ResourceOptions& resourceOptions,
|
const ResourceOptions& resourceOptions,
|
||||||
const ClientOptions& clientOptions) noexcept {
|
const ClientOptions& clientOptions) noexcept {
|
||||||
std::lock_guard<std::recursive_mutex> lock(impl->mutex);
|
std::scoped_lock lock(impl->mutex);
|
||||||
|
|
||||||
// Remove released file sources.
|
// Remove released file sources.
|
||||||
for (auto it = impl->fileSources.begin(); it != impl->fileSources.end();) {
|
for (auto it = impl->fileSources.begin(); it != impl->fileSources.end();) {
|
||||||
@@ -71,12 +71,12 @@ std::shared_ptr<FileSource> FileSourceManager::getFileSource(FileSourceType type
|
|||||||
|
|
||||||
void FileSourceManager::registerFileSourceFactory(FileSourceType type, FileSourceFactory&& factory) noexcept {
|
void FileSourceManager::registerFileSourceFactory(FileSourceType type, FileSourceFactory&& factory) noexcept {
|
||||||
assert(factory);
|
assert(factory);
|
||||||
std::lock_guard<std::recursive_mutex> lock(impl->mutex);
|
std::scoped_lock lock(impl->mutex);
|
||||||
impl->fileSourceFactories[type] = std::move(factory);
|
impl->fileSourceFactories[type] = std::move(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSourceManager::FileSourceFactory FileSourceManager::unRegisterFileSourceFactory(FileSourceType type) noexcept {
|
FileSourceManager::FileSourceFactory FileSourceManager::unRegisterFileSourceFactory(FileSourceType type) noexcept {
|
||||||
std::lock_guard<std::recursive_mutex> lock(impl->mutex);
|
std::scoped_lock lock(impl->mutex);
|
||||||
auto it = impl->fileSourceFactories.find(type);
|
auto it = impl->fileSourceFactories.find(type);
|
||||||
FileSourceFactory factory;
|
FileSourceFactory factory;
|
||||||
if (it != impl->fileSourceFactories.end()) {
|
if (it != impl->fileSourceFactories.end()) {
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ void NetworkStatus::Set(Status status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NetworkStatus::Subscribe(util::AsyncTask *async) {
|
void NetworkStatus::Subscribe(util::AsyncTask *async) {
|
||||||
std::lock_guard<std::mutex> lock(NetworkStatus::mtx);
|
std::scoped_lock lock(NetworkStatus::mtx);
|
||||||
observers.insert(async);
|
observers.insert(async);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkStatus::Unsubscribe(util::AsyncTask *async) {
|
void NetworkStatus::Unsubscribe(util::AsyncTask *async) {
|
||||||
std::lock_guard<std::mutex> lock(NetworkStatus::mtx);
|
std::scoped_lock lock(NetworkStatus::mtx);
|
||||||
observers.erase(async);
|
observers.erase(async);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,8 +45,8 @@ void NetworkStatus::Reachable() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(NetworkStatus::mtx);
|
std::scoped_lock lock(NetworkStatus::mtx);
|
||||||
for (auto async : observers) {
|
for (auto async : observers) { // NOLINT(bugprone-nondeterministic-pointer-iteration-order)
|
||||||
async->send();
|
async->send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,11 @@ Resource Resource::tile(const std::string& urlTemplate,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Resource::TileData{urlTemplate, uint8_t(supportsRatio && pixelRatio > 1.0 ? 2 : 1), x, y, z},
|
Resource::TileData{.urlTemplate = urlTemplate,
|
||||||
|
.pixelRatio = uint8_t(supportsRatio && pixelRatio > 1.0 ? 2 : 1),
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.z = z},
|
||||||
loadingMethod};
|
loadingMethod};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <mbgl/style/expression/step.hpp>
|
#include <mbgl/style/expression/step.hpp>
|
||||||
#include <mbgl/util/string.hpp>
|
#include <mbgl/util/string.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -399,9 +400,7 @@ std::optional<std::map<double, std::unique_ptr<Expression>>> convertStops(const
|
|||||||
void omitFirstStop(std::map<double, std::unique_ptr<Expression>>& stops) {
|
void omitFirstStop(std::map<double, std::unique_ptr<Expression>>& stops) {
|
||||||
double min = std::numeric_limits<double>::max();
|
double min = std::numeric_limits<double>::max();
|
||||||
for (auto& s : stops) {
|
for (auto& s : stops) {
|
||||||
if (s.first < min) {
|
min = std::min(s.first, min);
|
||||||
min = s.first;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
stops.emplace(-std::numeric_limits<double>::infinity(), std::move(stops[min]));
|
stops.emplace(-std::numeric_limits<double>::infinity(), std::move(stops[min]));
|
||||||
stops.erase(min);
|
stops.erase(min);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ CustomTileLoader::CustomTileLoader(const TileFunction& fetchTileFn, const TileFu
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CustomTileLoader::fetchTile(const OverscaledTileID& tileID, const ActorRef<CustomGeometryTile>& tileRef) {
|
void CustomTileLoader::fetchTile(const OverscaledTileID& tileID, const ActorRef<CustomGeometryTile>& tileRef) {
|
||||||
std::lock_guard<std::mutex> guard(dataMutex);
|
std::scoped_lock guard(dataMutex);
|
||||||
auto cachedTileData = dataCache.find(tileID.canonical);
|
auto cachedTileData = dataCache.find(tileID.canonical);
|
||||||
if (cachedTileData != dataCache.end()) {
|
if (cachedTileData != dataCache.end()) {
|
||||||
tileRef.invoke(&CustomGeometryTile::setTileData, *(cachedTileData->second));
|
tileRef.invoke(&CustomGeometryTile::setTileData, *(cachedTileData->second));
|
||||||
@@ -35,14 +35,14 @@ void CustomTileLoader::fetchTile(const OverscaledTileID& tileID, const ActorRef<
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CustomTileLoader::cancelTile(const OverscaledTileID& tileID) {
|
void CustomTileLoader::cancelTile(const OverscaledTileID& tileID) {
|
||||||
std::lock_guard<std::mutex> guard(dataMutex);
|
std::scoped_lock guard(dataMutex);
|
||||||
if (tileCallbackMap.find(tileID.canonical) != tileCallbackMap.end()) {
|
if (tileCallbackMap.contains(tileID.canonical)) {
|
||||||
invokeTileCancel(tileID.canonical);
|
invokeTileCancel(tileID.canonical);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomTileLoader::removeTile(const OverscaledTileID& tileID) {
|
void CustomTileLoader::removeTile(const OverscaledTileID& tileID) {
|
||||||
std::lock_guard<std::mutex> guard(dataMutex);
|
std::scoped_lock guard(dataMutex);
|
||||||
auto tileCallbacks = tileCallbackMap.find(tileID.canonical);
|
auto tileCallbacks = tileCallbackMap.find(tileID.canonical);
|
||||||
if (tileCallbacks == tileCallbackMap.end()) return;
|
if (tileCallbacks == tileCallbackMap.end()) return;
|
||||||
for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) {
|
for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) {
|
||||||
@@ -59,7 +59,7 @@ void CustomTileLoader::removeTile(const OverscaledTileID& tileID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CustomTileLoader::setTileData(const CanonicalTileID& tileID, const GeoJSON& data) {
|
void CustomTileLoader::setTileData(const CanonicalTileID& tileID, const GeoJSON& data) {
|
||||||
std::lock_guard<std::mutex> guard(dataMutex);
|
std::scoped_lock guard(dataMutex);
|
||||||
auto iter = tileCallbackMap.find(tileID);
|
auto iter = tileCallbackMap.find(tileID);
|
||||||
if (iter == tileCallbackMap.end()) return;
|
if (iter == tileCallbackMap.end()) return;
|
||||||
auto dataPtr = std::make_unique<mapbox::geojson::geojson>(data);
|
auto dataPtr = std::make_unique<mapbox::geojson::geojson>(data);
|
||||||
@@ -71,7 +71,7 @@ void CustomTileLoader::setTileData(const CanonicalTileID& tileID, const GeoJSON&
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CustomTileLoader::invalidateTile(const CanonicalTileID& tileID) {
|
void CustomTileLoader::invalidateTile(const CanonicalTileID& tileID) {
|
||||||
std::lock_guard<std::mutex> guard(dataMutex);
|
std::scoped_lock guard(dataMutex);
|
||||||
auto tileCallbacks = tileCallbackMap.find(tileID);
|
auto tileCallbacks = tileCallbackMap.find(tileID);
|
||||||
if (tileCallbacks == tileCallbackMap.end()) {
|
if (tileCallbacks == tileCallbackMap.end()) {
|
||||||
return;
|
return;
|
||||||
@@ -86,7 +86,7 @@ void CustomTileLoader::invalidateTile(const CanonicalTileID& tileID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CustomTileLoader::invalidateRegion(const LatLngBounds& bounds, Range<uint8_t>) {
|
void CustomTileLoader::invalidateRegion(const LatLngBounds& bounds, Range<uint8_t>) {
|
||||||
std::lock_guard<std::mutex> guard(dataMutex);
|
std::scoped_lock guard(dataMutex);
|
||||||
std::map<uint8_t, util::TileRange> tileRanges;
|
std::map<uint8_t, util::TileRange> tileRanges;
|
||||||
for (auto& idtuple : tileCallbackMap) {
|
for (auto& idtuple : tileCallbackMap) {
|
||||||
auto zoom = idtuple.first.z;
|
auto zoom = idtuple.first.z;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include <mbgl/style/conversion_impl.hpp>
|
#include <mbgl/style/conversion_impl.hpp>
|
||||||
#include <mbgl/util/string.hpp>
|
#include <mbgl/util/string.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
namespace style {
|
namespace style {
|
||||||
namespace expression {
|
namespace expression {
|
||||||
@@ -51,9 +53,8 @@ EvaluationResult toColor(const Value& colorValue) {
|
|||||||
},
|
},
|
||||||
[&colorValue](const std::vector<Value>& components) -> EvaluationResult {
|
[&colorValue](const std::vector<Value>& components) -> EvaluationResult {
|
||||||
const std::size_t len = components.size();
|
const std::size_t len = components.size();
|
||||||
bool isNumeric = std::all_of(components.begin(), components.end(), [](const Value& item) -> bool {
|
bool isNumeric = std::ranges::all_of(components,
|
||||||
return item.template is<double>();
|
[](const Value& item) -> bool { return item.template is<double>(); });
|
||||||
});
|
|
||||||
if ((len == 3 || len == 4) && isNumeric) {
|
if ((len == 3 || len == 4) && isNumeric) {
|
||||||
Result<Color> c = {rgba(components[0].template get<double>(),
|
Result<Color> c = {rgba(components[0].template get<double>(),
|
||||||
components[1].template get<double>(),
|
components[1].template get<double>(),
|
||||||
|
|||||||
@@ -70,11 +70,14 @@ ZoomCurveOrError findZoomCurve(const expression::Expression& e) {
|
|||||||
result = childResult;
|
result = childResult;
|
||||||
} else if (!result && childResult) {
|
} else if (!result && childResult) {
|
||||||
result = {ParsingError{
|
result = {ParsingError{
|
||||||
R"("zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.)",
|
.message =
|
||||||
""}};
|
R"("zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.)",
|
||||||
|
.key = ""}};
|
||||||
} else if (result && childResult && result != childResult) {
|
} else if (result && childResult && result != childResult) {
|
||||||
result = {ParsingError{
|
result = {ParsingError{
|
||||||
R"(Only one zoom-based "step" or "interpolate" subexpression may be used in an expression.)", ""}};
|
.message =
|
||||||
|
R"(Only one zoom-based "step" or "interpolate" subexpression may be used in an expression.)",
|
||||||
|
.key = ""}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ namespace style {
|
|||||||
using namespace shaders;
|
using namespace shaders;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const LayerTypeInfo typeInfoCustomDrawable{"custom-drawable",
|
const LayerTypeInfo typeInfoCustomDrawable{.type = "custom-drawable",
|
||||||
LayerTypeInfo::Source::NotRequired,
|
.source = LayerTypeInfo::Source::NotRequired,
|
||||||
LayerTypeInfo::Pass3D::NotRequired,
|
.pass3d = LayerTypeInfo::Pass3D::NotRequired,
|
||||||
LayerTypeInfo::Layout::NotRequired,
|
.layout = LayerTypeInfo::Layout::NotRequired,
|
||||||
LayerTypeInfo::FadingTiles::NotRequired,
|
.fadingTiles = LayerTypeInfo::FadingTiles::NotRequired,
|
||||||
LayerTypeInfo::CrossTileIndex::NotRequired,
|
.crossTileIndex = LayerTypeInfo::CrossTileIndex::NotRequired,
|
||||||
LayerTypeInfo::TileKind::NotRequired};
|
.tileKind = LayerTypeInfo::TileKind::NotRequired};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
CustomDrawableLayer::CustomDrawableLayer(const std::string& layerID, std::unique_ptr<CustomDrawableLayerHost> host)
|
CustomDrawableLayer::CustomDrawableLayer(const std::string& layerID, std::unique_ptr<CustomDrawableLayerHost> host)
|
||||||
@@ -120,28 +120,28 @@ public:
|
|||||||
const auto matrix = LayerTweaker::getTileMatrix(
|
const auto matrix = LayerTweaker::getTileMatrix(
|
||||||
tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false);
|
tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false);
|
||||||
|
|
||||||
const shaders::LineEvaluatedPropsUBO propsUBO = {options.color,
|
const shaders::LineEvaluatedPropsUBO propsUBO = {.color = options.color,
|
||||||
options.blur,
|
.blur = options.blur,
|
||||||
options.opacity,
|
.opacity = options.opacity,
|
||||||
options.gapWidth,
|
.gapwidth = options.gapWidth,
|
||||||
options.offset,
|
.offset = options.offset,
|
||||||
options.width,
|
.width = options.width,
|
||||||
/*floorwidth=*/0.0f,
|
/*floorwidth=*/.floorwidth = 0.0f,
|
||||||
LineExpressionMask::None,
|
.expressionMask = LineExpressionMask::None,
|
||||||
0};
|
.pad1 = 0};
|
||||||
|
|
||||||
// We would need to set up `idLineExpressionUBO` if the expression mask isn't empty
|
// We would need to set up `idLineExpressionUBO` if the expression mask isn't empty
|
||||||
assert(propsUBO.expressionMask == LineExpressionMask::None);
|
assert(propsUBO.expressionMask == LineExpressionMask::None);
|
||||||
|
|
||||||
if (!expressionUniformBuffer) {
|
if (!expressionUniformBuffer) {
|
||||||
const LineExpressionUBO exprUBO = {
|
const LineExpressionUBO exprUBO = {
|
||||||
/* .color = */ nullptr,
|
/* .color = */ .color = nullptr,
|
||||||
/* .blur = */ nullptr,
|
/* .blur = */ .blur = nullptr,
|
||||||
/* .opacity = */ nullptr,
|
/* .opacity = */ .opacity = nullptr,
|
||||||
/* .gapwidth = */ nullptr,
|
/* .gapwidth = */ .gapwidth = nullptr,
|
||||||
/* .offset = */ nullptr,
|
/* .offset = */ .offset = nullptr,
|
||||||
/* .width = */ nullptr,
|
/* .width = */ .width = nullptr,
|
||||||
/* .floorWidth = */ nullptr,
|
/* .floorWidth = */ .floorWidth = nullptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
expressionUniformBuffer = parameters.context.createUniformBuffer(&exprUBO, sizeof(exprUBO));
|
expressionUniformBuffer = parameters.context.createUniformBuffer(&exprUBO, sizeof(exprUBO));
|
||||||
@@ -159,16 +159,16 @@ public:
|
|||||||
#else
|
#else
|
||||||
const shaders::LineDrawableUBO drawableUBO = {
|
const shaders::LineDrawableUBO drawableUBO = {
|
||||||
#endif
|
#endif
|
||||||
/* .matrix = */ util::cast<float>(matrix),
|
/* .matrix = */ .matrix = util::cast<float>(matrix),
|
||||||
/* .ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, zoom),
|
/* .ratio = */ .ratio = 1.0f / tileID.pixelsToTileUnits(1.0f, zoom),
|
||||||
|
|
||||||
/* .color_t = */ 0.f,
|
/* .color_t = */ .color_t = 0.f,
|
||||||
/* .blur_t = */ 0.f,
|
/* .blur_t = */ .blur_t = 0.f,
|
||||||
/* .opacity_t = */ 0.f,
|
/* .opacity_t = */ .opacity_t = 0.f,
|
||||||
/* .gapwidth_t = */ 0.f,
|
/* .gapwidth_t = */ .gapwidth_t = 0.f,
|
||||||
/* .offset_t = */ 0.f,
|
/* .offset_t = */ .offset_t = 0.f,
|
||||||
/* .width_t = */ 0.f,
|
/* .width_t = */ .width_t = 0.f,
|
||||||
/* .pad1 = */ 0
|
/* .pad1 = */ .pad1 = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#if MLN_UBO_CONSOLIDATION
|
#if MLN_UBO_CONSOLIDATION
|
||||||
@@ -240,30 +240,30 @@ public:
|
|||||||
|
|
||||||
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
|
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
|
||||||
shaders::WideVectorUniformsUBO uniform = {
|
shaders::WideVectorUniformsUBO uniform = {
|
||||||
/* .mvpMatrix = */ mvpMatrix,
|
/* .mvpMatrix = */ .mvpMatrix = mvpMatrix,
|
||||||
/* .mvpMatrixDiff = */ mvpMatrixDiff,
|
/* .mvpMatrixDiff = */ .mvpMatrixDiff = mvpMatrixDiff,
|
||||||
/* .mvMatrix = */ mvMatrix,
|
/* .mvMatrix = */ .mvMatrix = mvMatrix,
|
||||||
/* .mvMatrixDiff = */ mvMatrixDiff,
|
/* .mvMatrixDiff = */ .mvMatrixDiff = mvMatrixDiff,
|
||||||
/* .pMatrix = */ pMatrix,
|
/* .pMatrix = */ .pMatrix = pMatrix,
|
||||||
/* .pMatrixDiff = */ pMatrixDiff,
|
/* .pMatrixDiff = */ .pMatrixDiff = pMatrixDiff,
|
||||||
/* .frameSize = */ {(float)renderableSize.width, (float)renderableSize.height},
|
/* .frameSize = */ .frameSize = {(float)renderableSize.width, (float)renderableSize.height},
|
||||||
/* .pad1 = */ 0,
|
/* .pad1 = */ .pad1 = 0,
|
||||||
/* .pad2 = */ 0};
|
/* .pad2 = */ .pad2 = 0};
|
||||||
|
|
||||||
shaders::WideVectorUniformWideVecUBO wideVec = {
|
shaders::WideVectorUniformWideVecUBO wideVec = {
|
||||||
/* .color = */ options.color,
|
/* .color = */ .color = options.color,
|
||||||
/* .w2 = */ options.width,
|
/* .w2 = */ .w2 = options.width,
|
||||||
/* .offset = */ options.offset,
|
/* .offset = */ .offset = options.offset,
|
||||||
/* .edge = */ 0.0f, // TODO: MLN does not provide a value. Analyze impact.
|
/* .edge = */ .edge = 0.0f, // TODO: MLN does not provide a value. Analyze impact.
|
||||||
/* .texRepeat = */ 0.0f, // N/A
|
/* .texRepeat = */ .texRepeat = 0.0f, // N/A
|
||||||
/* .texOffset = */ {}, // N/A
|
/* .texOffset = */ .texOffset = {}, // N/A
|
||||||
/* .miterLimit = */ options.geometry.miterLimit,
|
/* .miterLimit = */ .miterLimit = options.geometry.miterLimit,
|
||||||
/* .join = */ static_cast<int32_t>(options.geometry.joinType),
|
/* .join = */ .join = static_cast<int32_t>(options.geometry.joinType),
|
||||||
/* .cap = */ static_cast<int32_t>(options.geometry.beginCap), // TODO: MLN option for endCap to be
|
/* .cap = */ .cap = static_cast<int32_t>(options.geometry.beginCap), // TODO: MLN option for endCap to be
|
||||||
// implemented in the shader!
|
// implemented in the shader!
|
||||||
/* .hasExp = */ false, // N/A
|
/* .hasExp = */ .hasExp = false, // N/A
|
||||||
/* .interClipLimit = */ 0.0f, // N/A
|
/* .interClipLimit = */ .interClipLimit = 0.0f, // N/A
|
||||||
/* .pad1 = */ 0};
|
/* .pad1 = */ .pad1 = 0};
|
||||||
|
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||||
drawableUniforms.createOrUpdate(idWideVectorUniformsUBO, &uniform, parameters.context);
|
drawableUniforms.createOrUpdate(idWideVectorUniformsUBO, &uniform, parameters.context);
|
||||||
@@ -305,12 +305,12 @@ public:
|
|||||||
const auto matrix = LayerTweaker::getTileMatrix(
|
const auto matrix = LayerTweaker::getTileMatrix(
|
||||||
tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false);
|
tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false);
|
||||||
|
|
||||||
const shaders::FillEvaluatedPropsUBO propsUBO = {/* .color = */ options.color,
|
const shaders::FillEvaluatedPropsUBO propsUBO = {/* .color = */ .color = options.color,
|
||||||
/* .outline_color = */ Color::white(),
|
/* .outline_color = */ .outline_color = Color::white(),
|
||||||
/* .opacity = */ options.opacity,
|
/* .opacity = */ .opacity = options.opacity,
|
||||||
/* .fade = */ 0.f,
|
/* .fade = */ .fade = 0.f,
|
||||||
/* .from_scale = */ 0.f,
|
/* .from_scale = */ .from_scale = 0.f,
|
||||||
/* .to_scale = */ 0.f};
|
/* .to_scale = */ .to_scale = 0.f};
|
||||||
|
|
||||||
#if MLN_UBO_CONSOLIDATION
|
#if MLN_UBO_CONSOLIDATION
|
||||||
FillDrawableUnionUBO drawableUBO;
|
FillDrawableUnionUBO drawableUBO;
|
||||||
@@ -318,12 +318,12 @@ public:
|
|||||||
#else
|
#else
|
||||||
const shaders::FillDrawableUBO drawableUBO = {
|
const shaders::FillDrawableUBO drawableUBO = {
|
||||||
#endif
|
#endif
|
||||||
/* .matrix = */ util::cast<float>(matrix),
|
/* .matrix = */ .matrix = util::cast<float>(matrix),
|
||||||
|
|
||||||
/* .color_t = */ 0.f,
|
/* .color_t = */ .color_t = 0.f,
|
||||||
/* .opacity_t = */ 0.f,
|
/* .opacity_t = */ .opacity_t = 0.f,
|
||||||
/* .pad1 = */ 0,
|
/* .pad1 = */ .pad1 = 0,
|
||||||
/* .pad2 = */ 0
|
/* .pad2 = */ .pad2 = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#if MLN_UBO_CONSOLIDATION
|
#if MLN_UBO_CONSOLIDATION
|
||||||
@@ -390,17 +390,19 @@ public:
|
|||||||
parameters.pixelsToGLUnits[1] * factor};
|
parameters.pixelsToGLUnits[1] * factor};
|
||||||
|
|
||||||
const shaders::CustomSymbolIconDrawableUBO drawableUBO = {
|
const shaders::CustomSymbolIconDrawableUBO drawableUBO = {
|
||||||
/* .matrix = */ util::cast<float>(matrix),
|
/* .matrix = */ .matrix = util::cast<float>(matrix),
|
||||||
/* .extrude_scale = */ {extrudeScale[0] * options.size.width, extrudeScale[1] * options.size.height},
|
/* .extrude_scale = */ .extrude_scale = {extrudeScale[0] * options.size.width,
|
||||||
/* .anchor = */ options.anchor,
|
extrudeScale[1] * options.size.height},
|
||||||
/* .angle_degrees = */ options.angleDegrees,
|
/* .anchor = */ .anchor = options.anchor,
|
||||||
/* .scale_with_map = */ options.scaleWithMap,
|
/* .angle_degrees = */ .angle_degrees = options.angleDegrees,
|
||||||
/* .pitch_with_map = */ options.pitchWithMap,
|
/* .scale_with_map = */ .scale_with_map = options.scaleWithMap,
|
||||||
/* .camera_to_center_distance = */ parameters.state.getCameraToCenterDistance(),
|
/* .pitch_with_map = */ .pitch_with_map = options.pitchWithMap,
|
||||||
/* .aspect_ratio = */ parameters.pixelsToGLUnits[0] / parameters.pixelsToGLUnits[1],
|
/* .camera_to_center_distance = */ .camera_to_center_distance =
|
||||||
/* .pad1 = */ 0,
|
parameters.state.getCameraToCenterDistance(),
|
||||||
/* .pad2 = */ 0,
|
/* .aspect_ratio = */ .aspect_ratio = parameters.pixelsToGLUnits[0] / parameters.pixelsToGLUnits[1],
|
||||||
/* .pad3 = */ 0};
|
/* .pad1 = */ .pad1 = 0,
|
||||||
|
/* .pad2 = */ .pad2 = 0,
|
||||||
|
/* .pad3 = */ .pad3 = 0};
|
||||||
|
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||||
drawableUniforms.createOrUpdate(idCustomSymbolDrawableUBO, &drawableUBO, parameters.context);
|
drawableUniforms.createOrUpdate(idCustomSymbolDrawableUBO, &drawableUBO, parameters.context);
|
||||||
@@ -430,8 +432,8 @@ public:
|
|||||||
callback(drawable, parameters, options);
|
callback(drawable, parameters, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomGeometryDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(options.matrix),
|
CustomGeometryDrawableUBO drawableUBO = {/* .matrix = */ .matrix = util::cast<float>(options.matrix),
|
||||||
/* .color = */ options.color};
|
/* .color = */ .color = options.color};
|
||||||
|
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||||
drawableUniforms.createOrUpdate(idCustomGeometryDrawableUBO, &drawableUBO, parameters.context);
|
drawableUniforms.createOrUpdate(idCustomGeometryDrawableUBO, &drawableUBO, parameters.context);
|
||||||
@@ -644,8 +646,8 @@ util::SimpleIdentity CustomDrawableLayerHost::Interface::addSymbol(
|
|||||||
for (int y = 0; y <= 1; ++y) {
|
for (int y = 0; y <= 1; ++y) {
|
||||||
for (int x = 0; x <= 1; ++x) {
|
for (int x = 0; x <= 1; ++x) {
|
||||||
vertices.emplace_back(
|
vertices.emplace_back(
|
||||||
CustomSymbolIcon{{static_cast<float>(point.x * 2 + x), static_cast<float>(point.y * 2 + y)},
|
CustomSymbolIcon{.a_pos = {static_cast<float>(point.x * 2 + x), static_cast<float>(point.y * 2 + y)},
|
||||||
{textureCoordinates[x][0], textureCoordinates[y][1]}});
|
.a_tex = {textureCoordinates[x][0], textureCoordinates[y][1]}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ namespace mbgl {
|
|||||||
namespace style {
|
namespace style {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const LayerTypeInfo typeInfoCustom{"custom",
|
const LayerTypeInfo typeInfoCustom{.type = "custom",
|
||||||
LayerTypeInfo::Source::NotRequired,
|
.source = LayerTypeInfo::Source::NotRequired,
|
||||||
LayerTypeInfo::Pass3D::NotRequired,
|
.pass3d = LayerTypeInfo::Pass3D::NotRequired,
|
||||||
LayerTypeInfo::Layout::NotRequired,
|
.layout = LayerTypeInfo::Layout::NotRequired,
|
||||||
LayerTypeInfo::FadingTiles::NotRequired,
|
.fadingTiles = LayerTypeInfo::FadingTiles::NotRequired,
|
||||||
LayerTypeInfo::CrossTileIndex::NotRequired,
|
.crossTileIndex = LayerTypeInfo::CrossTileIndex::NotRequired,
|
||||||
LayerTypeInfo::TileKind::NotRequired};
|
.tileKind = LayerTypeInfo::TileKind::NotRequired};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
CustomLayer::CustomLayer(const std::string& layerID, std::unique_ptr<CustomLayerHost> host)
|
CustomLayer::CustomLayer(const std::string& layerID, std::unique_ptr<CustomLayerHost> host)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include <mbgl/text/glyph.hpp>
|
#include <mbgl/text/glyph.hpp>
|
||||||
#include <mbgl/util/i18n.hpp>
|
#include <mbgl/util/i18n.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
GlyphRange::GlyphRange(uint32_t first_, uint32_t second_, GlyphIDType type_)
|
GlyphRange::GlyphRange(uint32_t first_, uint32_t second_, GlyphIDType type_)
|
||||||
@@ -57,8 +59,8 @@ GlyphIDType genNewGlyphIDType(const std::string &url,
|
|||||||
GlyphRange getGlyphRange(GlyphID glyph) {
|
GlyphRange getGlyphRange(GlyphID glyph) {
|
||||||
unsigned start = (glyph.complex.code / 256) * 256;
|
unsigned start = (glyph.complex.code / 256) * 256;
|
||||||
unsigned end = (start + 255);
|
unsigned end = (start + 255);
|
||||||
if (start > 65280) start = 65280;
|
start = std::min<unsigned int>(start, 65280);
|
||||||
if (end > 65535) end = 65535;
|
end = std::min<unsigned int>(end, 65535);
|
||||||
return {start, end, glyph.complex.type};
|
return {start, end, glyph.complex.type};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ GlyphManager::~GlyphManager() {
|
|||||||
void GlyphManager::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphDependencies, FileSource& fileSource) {
|
void GlyphManager::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphDependencies, FileSource& fileSource) {
|
||||||
auto dependencies = std::make_shared<GlyphDependencies>(std::move(glyphDependencies));
|
auto dependencies = std::make_shared<GlyphDependencies>(std::move(glyphDependencies));
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
// Figure out which glyph ranges need to be fetched. For each range that
|
// Figure out which glyph ranges need to be fetched. For each range that
|
||||||
// does need to be fetched, record an entry mapping the requestor to a
|
// does need to be fetched, record an entry mapping the requestor to a
|
||||||
// shared pointer containing the dependencies. When the shared pointer
|
// shared pointer containing the dependencies. When the shared pointer
|
||||||
@@ -115,7 +115,7 @@ void GlyphManager::processResponse(const Response& res, const FontStack& fontSta
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
|
|
||||||
Entry& entry = entries[fontStack];
|
Entry& entry = entries[fontStack];
|
||||||
GlyphRequest& request = entry.ranges[range];
|
GlyphRequest& request = entry.ranges[range];
|
||||||
@@ -191,7 +191,7 @@ void GlyphManager::notify(GlyphRequestor& requestor, const GlyphDependencies& gl
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GlyphManager::removeRequestor(GlyphRequestor& requestor) {
|
void GlyphManager::removeRequestor(GlyphRequestor& requestor) {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
for (auto& entry : entries) {
|
for (auto& entry : entries) {
|
||||||
for (auto& range : entry.second.ranges) {
|
for (auto& range : entry.second.ranges) {
|
||||||
range.second.requestors.erase(&requestor);
|
range.second.requestors.erase(&requestor);
|
||||||
@@ -200,7 +200,7 @@ void GlyphManager::removeRequestor(GlyphRequestor& requestor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GlyphManager::evict(const std::set<FontStack>& keep) {
|
void GlyphManager::evict(const std::set<FontStack>& keep) {
|
||||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
std::scoped_lock readWriteLock(rwLock);
|
||||||
util::erase_if(entries, [&](const auto& entry) { return keep.count(entry.first) == 0; });
|
util::erase_if(entries, [&](const auto& entry) { return keep.count(entry.first) == 0; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const CollisionGroups::CollisionGroup& CollisionGroups::get(const std::string& s
|
|||||||
// but the current interface defines one source == one group when
|
// but the current interface defines one source == one group when
|
||||||
// crossSourceCollisions == true.
|
// crossSourceCollisions == true.
|
||||||
if (!crossSourceCollisions) {
|
if (!crossSourceCollisions) {
|
||||||
if (collisionGroups.find(sourceID) == collisionGroups.end()) {
|
if (!collisionGroups.contains(sourceID)) {
|
||||||
uint16_t nextGroupID = ++maxGroupID;
|
uint16_t nextGroupID = ++maxGroupID;
|
||||||
collisionGroups.emplace(
|
collisionGroups.emplace(
|
||||||
sourceID,
|
sourceID,
|
||||||
@@ -474,9 +474,13 @@ JointPlacement Placement::placeSymbol(const SymbolInstance& symbolInstance, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variableOffsets.insert(std::make_pair(
|
variableOffsets.insert(std::make_pair(symbolInstance.getCrossTileID(),
|
||||||
symbolInstance.getCrossTileID(),
|
VariableOffset{.offset = variableTextOffset,
|
||||||
VariableOffset{variableTextOffset, width, height, anchor, textBoxScale, prevAnchor}));
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.anchor = anchor,
|
||||||
|
.textBoxScale = textBoxScale,
|
||||||
|
.prevAnchor = prevAnchor}));
|
||||||
|
|
||||||
if (bucket.allowVerticalPlacement) {
|
if (bucket.allowVerticalPlacement) {
|
||||||
placedOrientations.emplace(symbolInstance.getCrossTileID(), orientation);
|
placedOrientations.emplace(symbolInstance.getCrossTileID(), orientation);
|
||||||
@@ -712,7 +716,7 @@ void Placement::commit() {
|
|||||||
// copy and update values from the previous placement that aren't in the
|
// copy and update values from the previous placement that aren't in the
|
||||||
// current placement but haven't finished fading
|
// current placement but haven't finished fading
|
||||||
for (auto& prevOpacity : getPrevPlacement()->opacities) {
|
for (auto& prevOpacity : getPrevPlacement()->opacities) {
|
||||||
if (opacities.find(prevOpacity.first) == opacities.end()) {
|
if (!opacities.contains(prevOpacity.first)) {
|
||||||
JointOpacityState jointOpacity(prevOpacity.second, increment, false, false);
|
JointOpacityState jointOpacity(prevOpacity.second, increment, false, false);
|
||||||
if (!jointOpacity.isHidden()) {
|
if (!jointOpacity.isHidden()) {
|
||||||
opacities.emplace(prevOpacity.first, jointOpacity);
|
opacities.emplace(prevOpacity.first, jointOpacity);
|
||||||
@@ -1655,14 +1659,14 @@ void TilePlacement::newSymbolPlaced(const SymbolInstance& symbol,
|
|||||||
assert(box.isBox());
|
assert(box.isBox());
|
||||||
iconCollisionBox = box.box();
|
iconCollisionBox = box.box();
|
||||||
}
|
}
|
||||||
PlacedSymbolData symbolData{symbol.getKey(),
|
PlacedSymbolData symbolData{.key = symbol.getKey(),
|
||||||
textCollisionBox,
|
.textCollisionBox = textCollisionBox,
|
||||||
iconCollisionBox,
|
.iconCollisionBox = iconCollisionBox,
|
||||||
placement.text,
|
.textPlaced = placement.text,
|
||||||
placement.icon,
|
.iconPlaced = placement.icon,
|
||||||
!placement.skipFade && populateIntersections,
|
.intersectsTileBorder = !placement.skipFade && populateIntersections,
|
||||||
collisionIndex.getViewportPadding(),
|
.viewportPadding = collisionIndex.getViewportPadding(),
|
||||||
ctx.getBucket().bucketLeaderID};
|
.layer = ctx.getBucket().bucketLeaderID};
|
||||||
placedSymbolsData.emplace_back(std::move(symbolData));
|
placedSymbolsData.emplace_back(std::move(symbolData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ Cuts stretchZonesToCuts(const ImageStretches& stretchZones, const float fixedSiz
|
|||||||
const auto c1 = zone.first;
|
const auto c1 = zone.first;
|
||||||
const auto c2 = zone.second;
|
const auto c2 = zone.second;
|
||||||
const auto lastStretch = cuts.back().stretch;
|
const auto lastStretch = cuts.back().stretch;
|
||||||
cuts.emplace_back(Cut{c1 - lastStretch, lastStretch});
|
cuts.emplace_back(Cut{.fixed = c1 - lastStretch, .stretch = lastStretch});
|
||||||
cuts.emplace_back(Cut{c1 - lastStretch, lastStretch + (c2 - c1)});
|
cuts.emplace_back(Cut{.fixed = c1 - lastStretch, .stretch = lastStretch + (c2 - c1)});
|
||||||
}
|
}
|
||||||
cuts.emplace_back(Cut{fixedSize + border, stretchSize});
|
cuts.emplace_back(Cut{.fixed = fixedSize + border, .stretch = stretchSize});
|
||||||
return cuts;
|
return cuts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +184,10 @@ SymbolQuads getIconQuads(const PositionedIcon& shapedIcon,
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!hasIconTextFit || (image.stretchX.empty() && image.stretchY.empty())) {
|
if (!hasIconTextFit || (image.stretchX.empty() && image.stretchY.empty())) {
|
||||||
makeBox({0, -1}, {0, -1}, {0, static_cast<float>(imageWidth + 1)}, {0, static_cast<float>(imageHeight + 1)});
|
makeBox({.fixed = 0, .stretch = -1},
|
||||||
|
{.fixed = 0, .stretch = -1},
|
||||||
|
{.fixed = 0, .stretch = static_cast<float>(imageWidth + 1)},
|
||||||
|
{.fixed = 0, .stretch = static_cast<float>(imageHeight + 1)});
|
||||||
} else {
|
} else {
|
||||||
const auto xCuts = stretchZonesToCuts(stretchX, fixedWidth, stretchWidth);
|
const auto xCuts = stretchZonesToCuts(stretchX, fixedWidth, stretchWidth);
|
||||||
const auto yCuts = stretchZonesToCuts(stretchY, fixedHeight, stretchHeight);
|
const auto yCuts = stretchZonesToCuts(stretchY, fixedHeight, stretchHeight);
|
||||||
|
|||||||
@@ -400,9 +400,9 @@ void GeometryTile::onGlyphsAvailable(GlyphMap glyphMap, [[maybe_unused]] HBShape
|
|||||||
|
|
||||||
auto fontStackHash = FontStackHasher()(fontStack);
|
auto fontStackHash = FontStackHasher()(fontStack);
|
||||||
bool needShape = true;
|
bool needShape = true;
|
||||||
if (glyphMap.find(fontStackHash) != glyphMap.end()) {
|
if (glyphMap.contains(fontStackHash)) {
|
||||||
auto& glyphs = glyphMap[fontStackHash];
|
auto& glyphs = glyphMap[fontStackHash];
|
||||||
if (glyphs.find(glyphID) != glyphs.end()) needShape = false;
|
if (glyphs.contains(glyphID)) needShape = false;
|
||||||
}
|
}
|
||||||
if (needShape) {
|
if (needShape) {
|
||||||
auto glyph = glyphManager->getGlyph(fontStack, glyphID);
|
auto glyph = glyphManager->getGlyph(fontStack, glyphID);
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ void GeometryTileWorker::requestNewGlyphs(const GlyphDependencies& glyphDependen
|
|||||||
for (auto& fontDependencies : glyphDependencies.glyphs) {
|
for (auto& fontDependencies : glyphDependencies.glyphs) {
|
||||||
auto fontGlyphs = glyphMap.find(FontStackHasher()(fontDependencies.first));
|
auto fontGlyphs = glyphMap.find(FontStackHasher()(fontDependencies.first));
|
||||||
for (auto glyphID : fontDependencies.second) {
|
for (auto glyphID : fontDependencies.second) {
|
||||||
if (fontGlyphs == glyphMap.end() || fontGlyphs->second.find(glyphID) == fontGlyphs->second.end()) {
|
if (fontGlyphs == glyphMap.end() || !fontGlyphs->second.contains(glyphID)) {
|
||||||
pendingGlyphDependencies.glyphs[fontDependencies.first].insert(glyphID);
|
pendingGlyphDependencies.glyphs[fontDependencies.first].insert(glyphID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,7 +449,8 @@ void GeometryTileWorker::parse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const style::Layer::Impl& leaderImpl = *(group.at(0)->baseImpl);
|
const style::Layer::Impl& leaderImpl = *(group.at(0)->baseImpl);
|
||||||
BucketParameters parameters{id, mode, pixelRatio, leaderImpl.getTypeInfo()};
|
BucketParameters parameters{
|
||||||
|
.tileID = id, .mode = mode, .pixelRatio = pixelRatio, .layerType = leaderImpl.getTypeInfo()};
|
||||||
|
|
||||||
auto geometryLayer = (*data)->getLayer(leaderImpl.sourceLayer);
|
auto geometryLayer = (*data)->getLayer(leaderImpl.sourceLayer);
|
||||||
if (!geometryLayer) {
|
if (!geometryLayer) {
|
||||||
@@ -471,10 +472,13 @@ void GeometryTileWorker::parse() {
|
|||||||
// images/glyphs are used, or the Layout is stored until the
|
// images/glyphs are used, or the Layout is stored until the
|
||||||
// images/glyphs are available to add the features to the buckets.
|
// images/glyphs are available to add the features to the buckets.
|
||||||
if (leaderImpl.getTypeInfo()->layout == LayerTypeInfo::Layout::Required) {
|
if (leaderImpl.getTypeInfo()->layout == LayerTypeInfo::Layout::Required) {
|
||||||
std::unique_ptr<Layout> layout = LayerManager::get()->createLayout(
|
std::unique_ptr<Layout> layout = LayerManager::get()->createLayout({.bucketParameters = parameters,
|
||||||
{parameters, fontFaces, glyphDependencies, imageDependencies, availableImages},
|
.fontFaces = fontFaces,
|
||||||
std::move(geometryLayer),
|
.glyphDependencies = glyphDependencies,
|
||||||
group);
|
.imageDependencies = imageDependencies,
|
||||||
|
.availableImages = availableImages},
|
||||||
|
std::move(geometryLayer),
|
||||||
|
group);
|
||||||
if (layout->hasDependencies()) {
|
if (layout->hasDependencies()) {
|
||||||
layouts.push_back(std::move(layout));
|
layouts.push_back(std::move(layout));
|
||||||
} else {
|
} else {
|
||||||
@@ -502,7 +506,7 @@ void GeometryTileWorker::parse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& layer : group) {
|
for (const auto& layer : group) {
|
||||||
renderData.emplace(layer->baseImpl->id, LayerRenderData{bucket, layer});
|
renderData.emplace(layer->baseImpl->id, LayerRenderData{.bucket = bucket, .layerProperties = layer});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ void TileCache::deferPendingReleases() {
|
|||||||
|
|
||||||
// Block destruction until the cleanup task is complete
|
// Block destruction until the cleanup task is complete
|
||||||
{
|
{
|
||||||
std::lock_guard counterLock{deferredSignalLock};
|
std::scoped_lock counterLock{deferredSignalLock};
|
||||||
deferredDeletionsPending++;
|
deferredDeletionsPending++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ void TileCache::deferPendingReleases() {
|
|||||||
MLN_ZONE_VALUE(tile_.items.size());
|
MLN_ZONE_VALUE(tile_.items.size());
|
||||||
tile_.items.clear();
|
tile_.items.clear();
|
||||||
|
|
||||||
std::lock_guard<std::mutex> counterLock(deferredSignalLock);
|
std::scoped_lock counterLock(deferredSignalLock);
|
||||||
deferredDeletionsPending--;
|
deferredDeletionsPending--;
|
||||||
deferredSignal.notify_all();
|
deferredSignal.notify_all();
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ private:
|
|||||||
Resource resource;
|
Resource resource;
|
||||||
std::shared_ptr<FileSource> fileSource;
|
std::shared_ptr<FileSource> fileSource;
|
||||||
std::unique_ptr<AsyncRequest> request;
|
std::unique_ptr<AsyncRequest> request;
|
||||||
TileUpdateParameters updateParameters{Duration::zero(), false};
|
TileUpdateParameters updateParameters{.minimumUpdateInterval = Duration::zero(), .isVolatile = false};
|
||||||
|
|
||||||
/// @brief It's possible for async requests in flight to mess with the request
|
/// @brief It's possible for async requests in flight to mess with the request
|
||||||
/// object at the same time as the loader's destructor. This construct is shared
|
/// object at the same time as the loader's destructor. This construct is shared
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#include <rapidjson/stringbuffer.h>
|
#include <rapidjson/stringbuffer.h>
|
||||||
#include <rapidjson/writer.h>
|
#include <rapidjson/writer.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <mutex>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@@ -175,7 +177,7 @@ std::vector<std::string> ActionJournal::Impl::getLogFiles() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> ActionJournal::Impl::getLog() {
|
std::vector<std::string> ActionJournal::Impl::getLog() {
|
||||||
std::lock_guard lock(fileMutex);
|
std::scoped_lock lock(fileMutex);
|
||||||
std::vector<std::string> logEvents;
|
std::vector<std::string> logEvents;
|
||||||
|
|
||||||
const auto readFile = [&](std::fstream& file) {
|
const auto readFile = [&](std::fstream& file) {
|
||||||
@@ -215,7 +217,7 @@ std::vector<std::string> ActionJournal::Impl::getLog() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ActionJournal::Impl::clearLog() {
|
void ActionJournal::Impl::clearLog() {
|
||||||
std::lock_guard lock(fileMutex);
|
std::scoped_lock lock(fileMutex);
|
||||||
|
|
||||||
// close current file
|
// close current file
|
||||||
currentFile.close();
|
currentFile.close();
|
||||||
@@ -277,21 +279,13 @@ void ActionJournal::Impl::onDidFinishRenderingFrame(const RenderFrameStatus& fra
|
|||||||
previousFrameTime = currentFrameTime;
|
previousFrameTime = currentFrameTime;
|
||||||
|
|
||||||
// update rendering stats
|
// update rendering stats
|
||||||
if (renderingStats.encodingMin > frame.renderingStats.encodingTime) {
|
renderingStats.encodingMin = std::min(renderingStats.encodingMin, frame.renderingStats.encodingTime);
|
||||||
renderingStats.encodingMin = frame.renderingStats.encodingTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderingStats.encodingMax < frame.renderingStats.encodingTime) {
|
renderingStats.encodingMax = std::max(renderingStats.encodingMax, frame.renderingStats.encodingTime);
|
||||||
renderingStats.encodingMax = frame.renderingStats.encodingTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderingStats.renderingMin > frame.renderingStats.renderingTime) {
|
renderingStats.renderingMin = std::min(renderingStats.renderingMin, frame.renderingStats.renderingTime);
|
||||||
renderingStats.renderingMin = frame.renderingStats.renderingTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderingStats.renderingMax < frame.renderingStats.renderingTime) {
|
renderingStats.renderingMax = std::max(renderingStats.renderingMax, frame.renderingStats.renderingTime);
|
||||||
renderingStats.renderingMax = frame.renderingStats.renderingTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderingStats.encodingTotal += frame.renderingStats.encodingTime;
|
renderingStats.encodingTotal += frame.renderingStats.encodingTime;
|
||||||
renderingStats.renderingTotal += frame.renderingStats.renderingTime;
|
renderingStats.renderingTotal += frame.renderingStats.renderingTime;
|
||||||
@@ -617,7 +611,7 @@ void ActionJournal::Impl::logToFile(const std::string& value) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(fileMutex);
|
std::scoped_lock lock(fileMutex);
|
||||||
|
|
||||||
if (!prepareFile(value.size() + 1)) {
|
if (!prepareFile(value.size() + 1)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -131,8 +131,8 @@ Frustum::Frustum(const std::array<vec3, 8>& points_, const std::array<vec4, 6>&
|
|||||||
const vec3 axis0 = {{0.0, -frustumEdges[i][2], frustumEdges[i][1]}};
|
const vec3 axis0 = {{0.0, -frustumEdges[i][2], frustumEdges[i][1]}};
|
||||||
const vec3 axis1 = {{frustumEdges[i][2], 0.0, -frustumEdges[i][0]}};
|
const vec3 axis1 = {{frustumEdges[i][2], 0.0, -frustumEdges[i][0]}};
|
||||||
|
|
||||||
projections[i * 2] = {axis0, ProjectPointsToAxis(points, points[0], axis0)};
|
projections[i * 2] = {.axis = axis0, .projection = ProjectPointsToAxis(points, points[0], axis0)};
|
||||||
projections[i * 2 + 1] = {axis1, ProjectPointsToAxis(points, points[0], axis1)};
|
projections[i * 2 + 1] = {.axis = axis1, .projection = ProjectPointsToAxis(points, points[0], axis1)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,9 +165,7 @@ Frustum Frustum::fromInvProjMatrix(const mat4& invProj, double worldSize, double
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
if (flippedY) {
|
if (flippedY) {
|
||||||
std::for_each(frustumPlanePointIndices.begin(), frustumPlanePointIndices.end(), [](vec3i& tri) {
|
std::ranges::for_each(frustumPlanePointIndices, [](vec3i& tri) { std::swap(tri[1], tri[2]); });
|
||||||
std::swap(tri[1], tri[2]);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<vec4, 6> frustumPlanes;
|
std::array<vec4, 6> frustumPlanes;
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ std::optional<LatLngAltitude> FreeCameraOptions::getLocation() const noexcept {
|
|||||||
const double worldSize = Projection::worldSize(std::pow(2.0, 0.0));
|
const double worldSize = Projection::worldSize(std::pow(2.0, 0.0));
|
||||||
const double altitude = positionValue[2] * worldSize * metersPerPixel;
|
const double altitude = positionValue[2] * worldSize * metersPerPixel;
|
||||||
|
|
||||||
return LatLngAltitude{location, altitude};
|
return LatLngAltitude{.location = location, .altitude = altitude};
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeCameraOptions::lookAtPoint(const LatLng& location, const std::optional<vec3>& upVector) noexcept {
|
void FreeCameraOptions::lookAtPoint(const LatLng& location, const std::optional<vec3>& upVector) noexcept {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
@@ -68,12 +69,12 @@ void Log::useLogThread(bool enable, std::optional<EventSeverity> severity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Log::setObserver(std::unique_ptr<Observer> observer) {
|
void Log::setObserver(std::unique_ptr<Observer> observer) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
currentObserver = std::move(observer);
|
currentObserver = std::move(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Log::Observer> Log::removeObserver() {
|
std::unique_ptr<Log::Observer> Log::removeObserver() {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
std::unique_ptr<Observer> observer;
|
std::unique_ptr<Observer> observer;
|
||||||
std::swap(observer, currentObserver);
|
std::swap(observer, currentObserver);
|
||||||
return observer;
|
return observer;
|
||||||
@@ -92,7 +93,7 @@ void Log::record(EventSeverity severity,
|
|||||||
int64_t code,
|
int64_t code,
|
||||||
const std::string& msg,
|
const std::string& msg,
|
||||||
const std::optional<std::string>& threadName) {
|
const std::optional<std::string>& threadName) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
if (currentObserver && severity != EventSeverity::Debug && currentObserver->onRecord(severity, event, code, msg)) {
|
if (currentObserver && severity != EventSeverity::Debug && currentObserver->onRecord(severity, event, code, msg)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ bool isCanonicalURL(const TileServerOptions& tileServerOptions, const std::strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& protocol = tileServerOptions.uriSchemeAlias() + "://";
|
const auto& protocol = tileServerOptions.uriSchemeAlias() + "://";
|
||||||
return url.compare(0, protocol.length(), protocol) == 0;
|
return url.starts_with(protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::string> createTokenMap(const std::string& urlTemplate, const std::string& url) {
|
std::map<std::string, std::string> createTokenMap(const std::string& urlTemplate, const std::string& url) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ ThreadedSchedulerBase::~ThreadedSchedulerBase() = default;
|
|||||||
|
|
||||||
void ThreadedSchedulerBase::terminate() {
|
void ThreadedSchedulerBase::terminate() {
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(workerMutex);
|
std::scoped_lock lock(workerMutex);
|
||||||
terminated = true;
|
terminated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ std::thread ThreadedSchedulerBase::makeSchedulerThread(size_t index) {
|
|||||||
std::vector<std::shared_ptr<Queue>> pending;
|
std::vector<std::shared_ptr<Queue>> pending;
|
||||||
{
|
{
|
||||||
// 1. Gather buckets for us to visit this iteration
|
// 1. Gather buckets for us to visit this iteration
|
||||||
std::lock_guard<std::mutex> lock(taggedQueueLock);
|
std::scoped_lock lock(taggedQueueLock);
|
||||||
for (const auto& [tag, queue] : taggedQueue) {
|
for (const auto& [tag, queue] : taggedQueue) {
|
||||||
pending.push_back(queue);
|
pending.push_back(queue);
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ std::thread ThreadedSchedulerBase::makeSchedulerThread(size_t index) {
|
|||||||
for (auto& q : pending) {
|
for (auto& q : pending) {
|
||||||
std::function<void()> tasklet;
|
std::function<void()> tasklet;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(q->lock);
|
std::scoped_lock lock(q->lock);
|
||||||
if (q->queue.size()) {
|
if (q->queue.size()) {
|
||||||
q->runningCount++;
|
q->runningCount++;
|
||||||
tasklet = std::move(q->queue.front());
|
tasklet = std::move(q->queue.front());
|
||||||
@@ -78,13 +78,13 @@ std::thread ThreadedSchedulerBase::makeSchedulerThread(size_t index) {
|
|||||||
tasklet = {}; // destroy the function and release its captures before unblocking `waitForEmpty`
|
tasklet = {}; // destroy the function and release its captures before unblocking `waitForEmpty`
|
||||||
|
|
||||||
if (!--q->runningCount) {
|
if (!--q->runningCount) {
|
||||||
std::lock_guard<std::mutex> lock(q->lock);
|
std::scoped_lock lock(q->lock);
|
||||||
if (q->queue.empty()) {
|
if (q->queue.empty()) {
|
||||||
q->cv.notify_all();
|
q->cv.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
std::lock_guard<std::mutex> lock(q->lock);
|
std::scoped_lock lock(q->lock);
|
||||||
if (handler) {
|
if (handler) {
|
||||||
handler(std::current_exception());
|
handler(std::current_exception());
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ void ThreadedSchedulerBase::schedule(const util::SimpleIdentity tag, std::functi
|
|||||||
std::shared_ptr<Queue> q;
|
std::shared_ptr<Queue> q;
|
||||||
{
|
{
|
||||||
MLN_TRACE_ZONE(queue);
|
MLN_TRACE_ZONE(queue);
|
||||||
std::lock_guard<std::mutex> lock(taggedQueueLock);
|
std::scoped_lock lock(taggedQueueLock);
|
||||||
|
|
||||||
// find or insert
|
// find or insert
|
||||||
auto result = taggedQueue.insert(std::make_pair(tag, std::shared_ptr<Queue>{}));
|
auto result = taggedQueue.insert(std::make_pair(tag, std::shared_ptr<Queue>{}));
|
||||||
@@ -132,13 +132,13 @@ void ThreadedSchedulerBase::schedule(const util::SimpleIdentity tag, std::functi
|
|||||||
|
|
||||||
{
|
{
|
||||||
MLN_TRACE_ZONE(push);
|
MLN_TRACE_ZONE(push);
|
||||||
std::lock_guard<std::mutex> lock(q->lock);
|
std::scoped_lock lock(q->lock);
|
||||||
q->queue.push(std::move(fn));
|
q->queue.push(std::move(fn));
|
||||||
taskCount++;
|
taskCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take the worker lock before notifying to prevent threads from waiting while we try to wake them
|
// Take the worker lock before notifying to prevent threads from waiting while we try to wake them
|
||||||
std::lock_guard<std::mutex> workerLock(workerMutex);
|
std::scoped_lock workerLock(workerMutex);
|
||||||
cvAvailable.notify_one();
|
cvAvailable.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ void ThreadedSchedulerBase::waitForEmpty(const util::SimpleIdentity tag) {
|
|||||||
|
|
||||||
std::shared_ptr<Queue> q;
|
std::shared_ptr<Queue> q;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(taggedQueueLock);
|
std::scoped_lock lock(taggedQueueLock);
|
||||||
auto it = taggedQueue.find(tagToFind);
|
auto it = taggedQueue.find(tagToFind);
|
||||||
if (it == taggedQueue.end()) {
|
if (it == taggedQueue.end()) {
|
||||||
return;
|
return;
|
||||||
@@ -165,7 +165,7 @@ void ThreadedSchedulerBase::waitForEmpty(const util::SimpleIdentity tag) {
|
|||||||
|
|
||||||
// After waiting for the queue to empty, go ahead and erase it from the map.
|
// After waiting for the queue to empty, go ahead and erase it from the map.
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(taggedQueueLock);
|
std::scoped_lock lock(taggedQueueLock);
|
||||||
taggedQueue.erase(tagToFind);
|
taggedQueue.erase(tagToFind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public:
|
|||||||
void runOnRenderThread(const util::SimpleIdentity tag, std::function<void()>&& fn) override {
|
void runOnRenderThread(const util::SimpleIdentity tag, std::function<void()>&& fn) override {
|
||||||
std::shared_ptr<RenderQueue> queue;
|
std::shared_ptr<RenderQueue> queue;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(taggedRenderQueueLock);
|
std::scoped_lock lock(taggedRenderQueueLock);
|
||||||
auto it = taggedRenderQueue.find(tag);
|
auto it = taggedRenderQueue.find(tag);
|
||||||
if (it != taggedRenderQueue.end()) {
|
if (it != taggedRenderQueue.end()) {
|
||||||
queue = it->second;
|
queue = it->second;
|
||||||
@@ -101,14 +101,14 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(queue->mutex);
|
std::scoped_lock lock(queue->mutex);
|
||||||
queue->queue.push(std::move(fn));
|
queue->queue.push(std::move(fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
void runRenderJobs(const util::SimpleIdentity tag, bool closeQueue = false) override {
|
void runRenderJobs(const util::SimpleIdentity tag, bool closeQueue = false) override {
|
||||||
MLN_TRACE_FUNC();
|
MLN_TRACE_FUNC();
|
||||||
std::shared_ptr<RenderQueue> queue;
|
std::shared_ptr<RenderQueue> queue;
|
||||||
std::unique_lock<std::mutex> lock(taggedRenderQueueLock);
|
std::unique_lock lock(taggedRenderQueueLock);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto it = taggedRenderQueue.find(tag);
|
auto it = taggedRenderQueue.find(tag);
|
||||||
@@ -125,7 +125,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> taskLock(queue->mutex);
|
std::scoped_lock taskLock(queue->mutex);
|
||||||
while (queue->queue.size()) {
|
while (queue->queue.size()) {
|
||||||
auto fn = std::move(queue->queue.front());
|
auto fn = std::move(queue->queue.front());
|
||||||
queue->queue.pop();
|
queue->queue.pop();
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ std::vector<UnwrappedTileID> tileCover(const Point<double>& tl,
|
|||||||
for (x = x0; x < x1; ++x) {
|
for (x = x0; x < x1; ++x) {
|
||||||
const auto dx = x + 0.5 - c.x;
|
const auto dx = x + 0.5 - c.x;
|
||||||
const auto dy = y + 0.5 - c.y;
|
const auto dy = y + 0.5 - c.y;
|
||||||
t.emplace_back(ID{x, y, dx * dx + dy * dy});
|
t.emplace_back(ID{.x = x, .y = y, .sqDist = dx * dx + dy * dy});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -193,12 +193,12 @@ std::vector<OverscaledTileID> tileCover(const TileCoverParameters& state,
|
|||||||
const double radiusOfMaxLvlLodInTiles = std::max(1.0, state.tileLodMinRadius);
|
const double radiusOfMaxLvlLodInTiles = std::max(1.0, state.tileLodMinRadius);
|
||||||
|
|
||||||
const auto newRootTile = [&](int16_t wrap) -> Node {
|
const auto newRootTile = [&](int16_t wrap) -> Node {
|
||||||
return {AABB({{wrap * numTiles, 0.0, 0.0}}, {{(wrap + 1) * numTiles, numTiles, 0.0}}),
|
return {.aabb = AABB({{wrap * numTiles, 0.0, 0.0}}, {{(wrap + 1) * numTiles, numTiles, 0.0}}),
|
||||||
uint8_t(0),
|
.zoom = uint8_t(0),
|
||||||
uint16_t(0),
|
.x = uint16_t(0),
|
||||||
uint16_t(0),
|
.y = uint16_t(0),
|
||||||
wrap,
|
.wrap = wrap,
|
||||||
false};
|
.fullyVisible = false};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Perform depth-first traversal on tile tree to find visible tiles
|
// Perform depth-first traversal on tile tree to find visible tiles
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ std::vector<TileSpan> scan_row(uint32_t y, Bounds& activeBounds) {
|
|||||||
tile_range.reserve(activeBounds.size());
|
tile_range.reserve(activeBounds.size());
|
||||||
|
|
||||||
for (Bound& b : activeBounds) {
|
for (Bound& b : activeBounds) {
|
||||||
TileSpan xp = {INT_MAX, 0, b.winding};
|
TileSpan xp = {.xmin = INT_MAX, .xmax = 0, .winding = b.winding};
|
||||||
double x;
|
double x;
|
||||||
const auto numEdges = b.points.size() - 1;
|
const auto numEdges = b.points.size() - 1;
|
||||||
while (b.currentPoint < numEdges) {
|
while (b.currentPoint < numEdges) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Checks: >
|
|||||||
-modernize-use-constraints,
|
-modernize-use-constraints,
|
||||||
-modernize-use-trailing-return-type,
|
-modernize-use-trailing-return-type,
|
||||||
misc-static-assert,
|
misc-static-assert,
|
||||||
|
-clang-analyzer-security.ArrayBound,
|
||||||
-clang-analyzer-security.insecureAPI.rand,
|
-clang-analyzer-security.insecureAPI.rand,
|
||||||
-clang-analyzer-core.uninitialized.UndefReturn,
|
-clang-analyzer-core.uninitialized.UndefReturn,
|
||||||
-clang-analyzer-core.StackAddressEscape,
|
-clang-analyzer-core.StackAddressEscape,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include <mbgl/test/util.hpp>
|
#include <mbgl/test/util.hpp>
|
||||||
#include <mbgl/algorithm/update_tile_masks.hpp>
|
#include <mbgl/algorithm/update_tile_masks.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace mbgl;
|
using namespace mbgl;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -23,7 +25,7 @@ bool operator==(const FakeTile& lhs, const FakeTile& rhs) {
|
|||||||
|
|
||||||
void validate(std::map<UnwrappedTileID, FakeTile> expected) {
|
void validate(std::map<UnwrappedTileID, FakeTile> expected) {
|
||||||
auto actual = expected;
|
auto actual = expected;
|
||||||
std::for_each(actual.begin(), actual.end(), [](auto& renderable) { renderable.second.mask.clear(); });
|
std::ranges::for_each(actual, [](auto& renderable) { renderable.second.mask.clear(); });
|
||||||
|
|
||||||
algorithm::updateTileMasks(actual);
|
algorithm::updateTileMasks(actual);
|
||||||
EXPECT_EQ(expected, actual);
|
EXPECT_EQ(expected, actual);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <algorithm>
|
||||||
#include <mbgl/test/util.hpp>
|
#include <mbgl/test/util.hpp>
|
||||||
#include <mbgl/test/stub_file_source.hpp>
|
#include <mbgl/test/stub_file_source.hpp>
|
||||||
#include <mbgl/test/map_adapter.hpp>
|
#include <mbgl/test/map_adapter.hpp>
|
||||||
@@ -12,6 +13,8 @@
|
|||||||
#include <mbgl/renderer/renderer.hpp>
|
#include <mbgl/renderer/renderer.hpp>
|
||||||
#include <mbgl/gfx/headless_frontend.hpp>
|
#include <mbgl/gfx/headless_frontend.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace mbgl;
|
using namespace mbgl;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -416,8 +419,9 @@ TEST(Annotations, QueryFractionalZoomLevels) {
|
|||||||
auto sameID = [](const Feature& lhs, const Feature& rhs) {
|
auto sameID = [](const Feature& lhs, const Feature& rhs) {
|
||||||
return lhs.id == rhs.id;
|
return lhs.id == rhs.id;
|
||||||
};
|
};
|
||||||
std::sort(features.begin(), features.end(), sortID);
|
std::ranges::sort(features, sortID);
|
||||||
features.erase(std::unique(features.begin(), features.end(), sameID), features.end());
|
features.erase(std::unique(features.begin(), features.end(), sameID),
|
||||||
|
features.end()); // NOLINT(modernize-use-ranges)
|
||||||
EXPECT_EQ(features.size(), ids.size());
|
EXPECT_EQ(features.size(), ids.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -451,15 +455,17 @@ TEST(Annotations, VisibleFeatures) {
|
|||||||
auto sameID = [](const Feature& lhs, const Feature& rhs) {
|
auto sameID = [](const Feature& lhs, const Feature& rhs) {
|
||||||
return lhs.id == rhs.id;
|
return lhs.id == rhs.id;
|
||||||
};
|
};
|
||||||
std::sort(features.begin(), features.end(), sortID);
|
std::ranges::sort(features, sortID);
|
||||||
features.erase(std::unique(features.begin(), features.end(), sameID), features.end());
|
features.erase(std::unique(features.begin(), features.end(), sameID),
|
||||||
|
features.end()); // NOLINT(modernize-use-ranges)
|
||||||
EXPECT_EQ(features.size(), ids.size());
|
EXPECT_EQ(features.size(), ids.size());
|
||||||
|
|
||||||
test.map.jumpTo(CameraOptions().withZoom(4.0).withBearing(0.0));
|
test.map.jumpTo(CameraOptions().withZoom(4.0).withBearing(0.0));
|
||||||
test.frontend.render(test.map);
|
test.frontend.render(test.map);
|
||||||
features = test.frontend.getRenderer()->queryRenderedFeatures(box);
|
features = test.frontend.getRenderer()->queryRenderedFeatures(box);
|
||||||
std::sort(features.begin(), features.end(), sortID);
|
std::ranges::sort(features, sortID);
|
||||||
features.erase(std::unique(features.begin(), features.end(), sameID), features.end());
|
features.erase(std::unique(features.begin(), features.end(), sameID),
|
||||||
|
features.end()); // NOLINT(modernize-use-ranges)
|
||||||
EXPECT_EQ(features.size(), ids.size());
|
EXPECT_EQ(features.size(), ids.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,9 +547,9 @@ TEST(Annotations, ViewFrustumCulling) {
|
|||||||
test.frontend.render(test.map);
|
test.frontend.render(test.map);
|
||||||
auto features = test.frontend.getRenderer()->queryRenderedFeatures(box, {});
|
auto features = test.frontend.getRenderer()->queryRenderedFeatures(box, {});
|
||||||
for (uint64_t id : testCase.second) { // testCase.second is vector of ids expected.
|
for (uint64_t id : testCase.second) { // testCase.second is vector of ids expected.
|
||||||
EXPECT_NE(std::find_if(features.begin(),
|
EXPECT_NE(std::ranges::find_if(features,
|
||||||
features.end(),
|
|
||||||
[&id](auto feature) { return id == feature.id.template get<uint64_t>(); }),
|
[&id](auto feature) { return id == feature.id.template get<uint64_t>(); }),
|
||||||
features.end())
|
features.end())
|
||||||
<< "Point with id " << id << " is missing in test case " << i;
|
<< "Point with id " << id << " is missing in test case " << i;
|
||||||
EXPECT_EQ(features.size(), testCase.second.size()) << " in test case " << i;
|
EXPECT_EQ(features.size(), testCase.second.size()) << " in test case " << i;
|
||||||
|
|||||||
@@ -1794,17 +1794,19 @@ TEST(Map, ObserveTileLifecycle) {
|
|||||||
StubMapObserver observer;
|
StubMapObserver observer;
|
||||||
observer.onTileActionCallback = [&](TileOperation op, const OverscaledTileID& id, const std::string& sourceID) {
|
observer.onTileActionCallback = [&](TileOperation op, const OverscaledTileID& id, const std::string& sourceID) {
|
||||||
if (sourceID != "mapbox") return;
|
if (sourceID != "mapbox") return;
|
||||||
std::lock_guard<std::mutex> lock(tileMutex);
|
std::scoped_lock lock(tileMutex);
|
||||||
tileOps.push_back(TileEntry{id, sourceID, op});
|
tileOps.push_back(TileEntry{.id = id, .sourceID = sourceID, .op = op});
|
||||||
|
};
|
||||||
|
observer.onPreCompileShaderCallback = [&](shaders::BuiltIn id,
|
||||||
|
gfx::Backend::Type type,
|
||||||
|
const std::string& additionalDefines) {
|
||||||
|
shaderOps.push_back(ShaderEntry{.id = id, .type = type, .defines = additionalDefines, .isPostCompile = false});
|
||||||
|
};
|
||||||
|
observer.onPostCompileShaderCallback = [&](shaders::BuiltIn id,
|
||||||
|
gfx::Backend::Type type,
|
||||||
|
const std::string& additionalDefines) {
|
||||||
|
shaderOps.push_back(ShaderEntry{.id = id, .type = type, .defines = additionalDefines, .isPostCompile = true});
|
||||||
};
|
};
|
||||||
observer.onPreCompileShaderCallback =
|
|
||||||
[&](shaders::BuiltIn id, gfx::Backend::Type type, const std::string& additionalDefines) {
|
|
||||||
shaderOps.push_back(ShaderEntry{id, type, additionalDefines, false});
|
|
||||||
};
|
|
||||||
observer.onPostCompileShaderCallback =
|
|
||||||
[&](shaders::BuiltIn id, gfx::Backend::Type type, const std::string& additionalDefines) {
|
|
||||||
shaderOps.push_back(ShaderEntry{id, type, additionalDefines, true});
|
|
||||||
};
|
|
||||||
|
|
||||||
HeadlessFrontend frontend{{512, 512}, 1};
|
HeadlessFrontend frontend{{512, 512}, 1};
|
||||||
MapAdapter map(
|
MapAdapter map(
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user