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-string-init,
|
||||
-readability-simplify-boolean-expr,
|
||||
-readability-static-accessed-through-instance
|
||||
-readability-static-accessed-through-instance,
|
||||
-readability-static-definition-in-anonymous-namespace,
|
||||
-readability-suspicious-call-argument,
|
||||
-readability-uppercase-literal-suffix,
|
||||
@@ -118,7 +118,17 @@ Checks: [
|
||||
-readability-enum-initial-value,
|
||||
-boost-use-ranges,
|
||||
-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: '*'
|
||||
HeaderFilterRegex: '.*'
|
||||
|
||||
2
.github/workflows/linux-ci.yml
vendored
2
.github/workflows/linux-ci.yml
vendored
@@ -29,7 +29,7 @@ env:
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
should_skip: ${{ github.event_name != 'workflow_dispatch' && steps.changed-files.outputs.linux_any_modified != 'true' }}
|
||||
steps:
|
||||
|
||||
@@ -51,14 +51,16 @@ public:
|
||||
|
||||
// Construct the `Object` from a tuple containing the constructor arguments
|
||||
// (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)
|
||||
: parent(parent_) {
|
||||
emplaceObject(std::forward<ArgsTuple>(args), std::make_index_sequence<ArgCount>{});
|
||||
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(*scheduler.get(), parent_, std::forward<ArgsTuple>(args));
|
||||
}
|
||||
@@ -98,7 +100,7 @@ private:
|
||||
// Used to expand a tuple holding the constructor arguments
|
||||
template <class ArgsTuple, std::size_t... 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.
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
gfx::RenderingStats& renderingStats() { return stats; }
|
||||
const gfx::RenderingStats& renderingStats() const { return stats; }
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#ifndef NDEBUG
|
||||
virtual void visualizeStencilBuffer() = 0;
|
||||
virtual void visualizeDepthBuffer(float depthRangeSize) = 0;
|
||||
#endif
|
||||
|
||||
@@ -91,7 +91,7 @@ struct RenderingStats {
|
||||
|
||||
RenderingStats& operator+=(const RenderingStats&);
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#ifndef NDEBUG
|
||||
std::string toString(std::string_view separator) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -126,10 +126,10 @@ public:
|
||||
const gfx::StencilMode&,
|
||||
const gfx::Renderable&) const;
|
||||
|
||||
virtual bool emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr&,
|
||||
const void* data,
|
||||
std::size_t size,
|
||||
bool persistent) override;
|
||||
bool emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr&,
|
||||
const void* data,
|
||||
std::size_t size,
|
||||
bool persistent) override;
|
||||
|
||||
/// Get a reusable buffer containing the standard fixed tile vertices (+/- `util::EXTENT`)
|
||||
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;
|
||||
|
||||
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);
|
||||
} 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);
|
||||
} 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);
|
||||
} 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);
|
||||
}
|
||||
|
||||
@@ -74,13 +75,13 @@ std::enable_if_t<std::is_floating_point_v<T>, std::optional<T>> parse(std::strin
|
||||
errno = 0;
|
||||
|
||||
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;
|
||||
} 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;
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ private:
|
||||
|
||||
// Adds a WorkTask to the queue, and wakes it up.
|
||||
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) {
|
||||
highPriorityQueue.emplace(std::move(task));
|
||||
} else {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// will be defined as hidden by default.
|
||||
|
||||
// clang-format off
|
||||
#if defined WIN32
|
||||
#ifdef WIN32
|
||||
#ifdef MBGL_BUILDING_LIB
|
||||
#ifdef __GNUC__
|
||||
#define MBGL_EXPORT __attribute__((dllexport))
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
|
||||
void operator()() override {
|
||||
// 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)) {
|
||||
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
|
||||
/// do nothing.
|
||||
void cancel() override {
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
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
|
||||
std::lock_guard<std::mutex> lock(initialisationMutex);
|
||||
std::scoped_lock lock(initialisationMutex);
|
||||
rendererObserver.reset();
|
||||
} catch (const std::exception& exception) {
|
||||
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) {
|
||||
try {
|
||||
// Lock on the parameters
|
||||
std::lock_guard<std::mutex> lock(updateMutex);
|
||||
std::scoped_lock lock(updateMutex);
|
||||
updateParameters = std::move(params);
|
||||
} catch (const std::exception& exception) {
|
||||
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) {
|
||||
try {
|
||||
// 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);
|
||||
|
||||
@@ -246,7 +246,7 @@ void MapRenderer::render(JNIEnv&) {
|
||||
|
||||
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
|
||||
std::lock_guard<std::mutex> lock(initialisationMutex);
|
||||
std::scoped_lock lock(initialisationMutex);
|
||||
|
||||
// The android system will have already destroyed the underlying
|
||||
// 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) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
runnables.push_back(runnable);
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ void RunLoop::Impl::addRunnable(Runnable* runnable) {
|
||||
}
|
||||
|
||||
void RunLoop::Impl::removeRunnable(Runnable* runnable) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
runnables.remove(runnable);
|
||||
if (runnables.empty()) {
|
||||
cvEmpty.notify_all();
|
||||
@@ -178,7 +178,7 @@ Milliseconds RunLoop::Impl::processRunnables() {
|
||||
auto nextDue = TimePoint::max();
|
||||
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
|
||||
// of messages, the size of the list is usually 1~2.
|
||||
@@ -220,7 +220,7 @@ void RunLoop::Impl::waitForEmpty() {
|
||||
while (true) {
|
||||
std::size_t remaining;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
remaining = runnables.size();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
}
|
||||
|
||||
void notify(const Response& response_) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
if (!cancelled) {
|
||||
response = response_;
|
||||
async.send();
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ void RunLoop::waitForEmpty([[maybe_unused]] const SimpleIdentity tag) {
|
||||
while (true) {
|
||||
std::size_t remaining;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
remaining = defaultQueue.size() + highPriorityQueue.size();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,22 +42,22 @@ public:
|
||||
}
|
||||
|
||||
void setResourceOptions(ResourceOptions options) {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
resourceOptions = options;
|
||||
}
|
||||
|
||||
ResourceOptions getResourceOptions() {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return resourceOptions.clone();
|
||||
}
|
||||
|
||||
void setClientOptions(ClientOptions options) {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
clientOptions = options;
|
||||
}
|
||||
|
||||
ClientOptions getClientOptions() {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
return clientOptions.clone();
|
||||
}
|
||||
|
||||
|
||||
@@ -176,22 +176,22 @@ public:
|
||||
void resume() { thread->resume(); }
|
||||
|
||||
void setResourceOptions(ResourceOptions options) {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
resourceOptions = options;
|
||||
}
|
||||
|
||||
ResourceOptions getResourceOptions() {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return resourceOptions.clone();
|
||||
}
|
||||
|
||||
void setClientOptions(ClientOptions options) {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
clientOptions = options;
|
||||
}
|
||||
|
||||
ClientOptions getClientOptions() {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
return clientOptions.clone();
|
||||
}
|
||||
|
||||
|
||||
@@ -245,22 +245,22 @@ int HTTPFileSource::Impl::startTimeout(CURLM * /* multi */, long timeout_ms, voi
|
||||
}
|
||||
|
||||
void HTTPFileSource::Impl::setResourceOptions(ResourceOptions options) {
|
||||
std::lock_guard lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
resourceOptions = options;
|
||||
}
|
||||
|
||||
ResourceOptions HTTPFileSource::Impl::getResourceOptions() {
|
||||
std::lock_guard lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return resourceOptions.clone();
|
||||
}
|
||||
|
||||
void HTTPFileSource::Impl::setClientOptions(ClientOptions options) {
|
||||
std::lock_guard lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
clientOptions = options;
|
||||
}
|
||||
|
||||
ClientOptions HTTPFileSource::Impl::getClientOptions() {
|
||||
std::lock_guard lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
return clientOptions.clone();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,22 +40,22 @@ public:
|
||||
}
|
||||
|
||||
void setResourceOptions(ResourceOptions options) {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
resourceOptions = options;
|
||||
}
|
||||
|
||||
ResourceOptions getResourceOptions() {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return resourceOptions.clone();
|
||||
}
|
||||
|
||||
void setClientOptions(ClientOptions options) {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
clientOptions = options;
|
||||
}
|
||||
|
||||
ClientOptions getClientOptions() {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
return clientOptions.clone();
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ public:
|
||||
void resume() { thread->resume(); }
|
||||
|
||||
void setResourceOptions(ResourceOptions options) {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
resourceOptions = options;
|
||||
assetFileSource->setResourceOptions(options.clone());
|
||||
databaseFileSource->setResourceOptions(options.clone());
|
||||
@@ -206,12 +206,12 @@ public:
|
||||
}
|
||||
|
||||
ResourceOptions getResourceOptions() {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return resourceOptions.clone();
|
||||
}
|
||||
|
||||
void setClientOptions(ClientOptions options) {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
clientOptions = options;
|
||||
assetFileSource->setClientOptions(options.clone());
|
||||
databaseFileSource->setClientOptions(options.clone());
|
||||
@@ -222,7 +222,7 @@ public:
|
||||
}
|
||||
|
||||
ClientOptions getClientOptions() {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
return clientOptions.clone();
|
||||
}
|
||||
|
||||
|
||||
@@ -223,22 +223,22 @@ public:
|
||||
}
|
||||
|
||||
void setResourceOptions(ResourceOptions options) {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
resourceOptions = options;
|
||||
}
|
||||
|
||||
ResourceOptions getResourceOptions() {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return resourceOptions.clone();
|
||||
}
|
||||
|
||||
void setClientOptions(ClientOptions options) {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
clientOptions = options;
|
||||
}
|
||||
|
||||
ClientOptions getClientOptions() {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
return clientOptions.clone();
|
||||
}
|
||||
|
||||
|
||||
@@ -124,8 +124,8 @@ public:
|
||||
}
|
||||
|
||||
void activateOrQueueRequest(OnlineFileRequest* req) {
|
||||
assert(allRequests.find(req) != allRequests.end());
|
||||
assert(activeRequests.find(req) == activeRequests.end());
|
||||
assert(allRequests.contains(req));
|
||||
assert(!activeRequests.contains(req));
|
||||
assert(!req->request);
|
||||
|
||||
if (activeRequests.size() >= getMaximumConcurrentRequests()) {
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
|
||||
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); }
|
||||
|
||||
@@ -339,26 +339,26 @@ public:
|
||||
void setResourceOptions(ResourceOptions options) {
|
||||
thread->actor().invoke(&OnlineFileSourceThread::setResourceOptions, options.clone());
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
cachedResourceOptions = options;
|
||||
}
|
||||
}
|
||||
|
||||
ResourceOptions getResourceOptions() {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return cachedResourceOptions.clone();
|
||||
}
|
||||
|
||||
void setClientOptions(ClientOptions options) {
|
||||
thread->actor().invoke(&OnlineFileSourceThread::setClientOptions, options.clone());
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
cachedClientOptions = options;
|
||||
}
|
||||
}
|
||||
|
||||
ClientOptions getClientOptions() {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
return cachedClientOptions.clone();
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ public:
|
||||
const auto maxConcurrentRequests = static_cast<uint32_t>(*maximumConcurrentRequests);
|
||||
thread->actor().invoke(&OnlineFileSourceThread::setMaximumConcurrentRequests, maxConcurrentRequests);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(maximumConcurrentRequestsMutex);
|
||||
std::scoped_lock lock(maximumConcurrentRequestsMutex);
|
||||
cachedMaximumConcurrentRequests = maxConcurrentRequests;
|
||||
}
|
||||
} else {
|
||||
@@ -379,7 +379,7 @@ public:
|
||||
}
|
||||
|
||||
uint32_t getMaximumConcurrentRequests() const {
|
||||
std::lock_guard<std::mutex> lock(maximumConcurrentRequestsMutex);
|
||||
std::scoped_lock lock(maximumConcurrentRequestsMutex);
|
||||
return cachedMaximumConcurrentRequests;
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ public:
|
||||
if (auto* apiKey = value.getString()) {
|
||||
thread->actor().invoke(&OnlineFileSourceThread::setApiKey, *apiKey);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
cachedResourceOptions.withApiKey(*apiKey);
|
||||
}
|
||||
} else {
|
||||
@@ -396,7 +396,7 @@ public:
|
||||
}
|
||||
|
||||
std::string getApiKey() const {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return cachedResourceOptions.apiKey();
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ public:
|
||||
if (auto* baseURL = value.getString()) {
|
||||
thread->actor().invoke(&OnlineFileSourceThread::setAPIBaseURL, *baseURL);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
cachedResourceOptions.withTileServerOptions(
|
||||
cachedResourceOptions.tileServerOptions().clone().withBaseURL(*baseURL));
|
||||
}
|
||||
@@ -414,7 +414,7 @@ public:
|
||||
}
|
||||
|
||||
std::string getAPIBaseURL() const {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return cachedResourceOptions.tileServerOptions().baseURL();
|
||||
}
|
||||
|
||||
|
||||
@@ -177,22 +177,22 @@ public:
|
||||
}
|
||||
|
||||
void setResourceOptions(ResourceOptions options) {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
resourceOptions = options;
|
||||
}
|
||||
|
||||
ResourceOptions getResourceOptions() {
|
||||
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
|
||||
std::scoped_lock lock(resourceOptionsMutex);
|
||||
return resourceOptions.clone();
|
||||
}
|
||||
|
||||
void setClientOptions(ClientOptions options) {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
clientOptions = options;
|
||||
}
|
||||
|
||||
ClientOptions getClientOptions() {
|
||||
std::lock_guard<std::mutex> lock(clientOptionsMutex);
|
||||
std::scoped_lock lock(clientOptionsMutex);
|
||||
return clientOptions.clone();
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ private:
|
||||
}
|
||||
|
||||
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>());
|
||||
}
|
||||
|
||||
@@ -229,191 +229,197 @@ private:
|
||||
resource.dataRange = std::make_pair<uint64_t, uint64_t>(pmtilesHeaderOffset,
|
||||
pmtilesHeaderOffset + pmtilesHeaderLength - 1);
|
||||
|
||||
tasks[req] = getFileSource()->request(resource, [=, this](const Response& response) {
|
||||
if (response.error) {
|
||||
std::string message = std::string("Error fetching PMTiles header: ") + response.error->message;
|
||||
tasks[req] = getFileSource()->request(
|
||||
resource, [=, this](const Response& response) { // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
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 (url.starts_with(mbgl::util::FILE_PROTOCOL)) {
|
||||
message += "path not found: " +
|
||||
url.substr(std::char_traits<char>::length(mbgl::util::FILE_PROTOCOL));
|
||||
} else {
|
||||
message += "url not found: " + url;
|
||||
if (response.error->message.empty() &&
|
||||
response.error->reason == Response::Error::Reason::NotFound) {
|
||||
if (url.starts_with(mbgl::util::FILE_PROTOCOL)) {
|
||||
message += "path not found: " +
|
||||
url.substr(std::char_traits<char>::length(mbgl::util::FILE_PROTOCOL));
|
||||
} 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 {
|
||||
pmtiles::headerv3 header = pmtiles::deserialize_header(response.data->substr(0, 127));
|
||||
header_cache.emplace(url, header);
|
||||
|
||||
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");
|
||||
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()));
|
||||
}
|
||||
|
||||
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) {
|
||||
if (metadata_cache.find(url) != metadata_cache.end()) {
|
||||
if (metadata_cache.contains(url)) {
|
||||
callback(std::unique_ptr<Response::Error>());
|
||||
}
|
||||
|
||||
getHeader(url, req, [=, this](std::unique_ptr<Response::Error> error) {
|
||||
if (error) {
|
||||
callback(std::move(error));
|
||||
return;
|
||||
}
|
||||
|
||||
pmtiles::headerv3 header = header_cache.at(url);
|
||||
|
||||
auto parse_callback = [=, this](const std::string& data) {
|
||||
Document doc;
|
||||
|
||||
auto& allocator = doc.GetAllocator();
|
||||
|
||||
if (!data.empty()) {
|
||||
doc.Parse(data);
|
||||
getHeader(
|
||||
url,
|
||||
req,
|
||||
[=, this](std::unique_ptr<Response::Error> error) { // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
if (error) {
|
||||
callback(std::move(error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!doc.IsObject()) {
|
||||
doc.SetObject();
|
||||
}
|
||||
pmtiles::headerv3 header = header_cache.at(url);
|
||||
|
||||
doc.AddMember("tilejson", "3.0.0", allocator);
|
||||
auto parse_callback = [=, this](const std::string& data) {
|
||||
Document doc;
|
||||
|
||||
if (!doc.HasMember("scheme")) {
|
||||
doc.AddMember("scheme", rapidjson::Value(), allocator);
|
||||
}
|
||||
auto& allocator = doc.GetAllocator();
|
||||
|
||||
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;
|
||||
if (!data.empty()) {
|
||||
doc.Parse(data);
|
||||
}
|
||||
|
||||
std::string data = *responseMetadata.data;
|
||||
|
||||
if (header.internal_compression == pmtiles::COMPRESSION_GZIP) {
|
||||
data = util::decompress(data);
|
||||
if (!doc.IsObject()) {
|
||||
doc.SetObject();
|
||||
}
|
||||
|
||||
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,
|
||||
uint64_t directoryOffset,
|
||||
uint64_t directoryLength,
|
||||
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_control.emplace(url, std::vector<std::string>());
|
||||
}
|
||||
@@ -437,8 +443,7 @@ private:
|
||||
std::string directory_cache_key = url + "|" + std::to_string(directoryOffset) + "|" +
|
||||
std::to_string(directoryLength);
|
||||
|
||||
if (directory_cache.find(url) != directory_cache.end() &&
|
||||
directory_cache.at(url).find(directory_cache_key) != directory_cache.at(url).end()) {
|
||||
if (directory_cache.contains(url) && directory_cache.at(url).contains(directory_cache_key)) {
|
||||
if (directory_cache_control.at(url).back() != directory_cache_key) {
|
||||
directory_cache_control.at(url).emplace_back(directory_cache_key);
|
||||
|
||||
@@ -511,36 +516,41 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
getDirectory(url, req, directoryOffset, directoryLength, [=, this](std::unique_ptr<Response::Error> error) {
|
||||
if (error) {
|
||||
callback(std::make_pair(0, 0), std::move(error));
|
||||
return;
|
||||
}
|
||||
|
||||
pmtiles::headerv3 header = header_cache.at(url);
|
||||
std::vector<pmtiles::entryv3> directory = directory_cache.at(url).at(
|
||||
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), {});
|
||||
getDirectory(
|
||||
url,
|
||||
req,
|
||||
directoryOffset,
|
||||
directoryLength,
|
||||
[=, this](std::unique_ptr<Response::Error> error) { // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
if (error) {
|
||||
callback(std::make_pair(0, 0), std::move(error));
|
||||
return;
|
||||
}
|
||||
|
||||
getTileAddress(url,
|
||||
req,
|
||||
tileID,
|
||||
header.leaf_dirs_offset + entry.offset,
|
||||
entry.length,
|
||||
directoryDepth + 1,
|
||||
std::move(callback));
|
||||
return;
|
||||
}
|
||||
pmtiles::headerv3 header = header_cache.at(url);
|
||||
std::vector<pmtiles::entryv3> directory = directory_cache.at(url).at(
|
||||
url + "|" + std::to_string(directoryOffset) + "|" + std::to_string(directoryLength));
|
||||
|
||||
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) {
|
||||
|
||||
@@ -161,7 +161,7 @@ void RunLoop::waitForEmpty([[maybe_unused]] const mbgl::util::SimpleIdentity tag
|
||||
while (true) {
|
||||
std::size_t remaining;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
remaining = defaultQueue.size() + highPriorityQueue.size();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,15 @@ namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
|
||||
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)));
|
||||
}
|
||||
uv_async_send(&async);
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
|
||||
void send(std::unique_ptr<T> data) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
queue.push(std::move(data));
|
||||
}
|
||||
uv_async_send(&async);
|
||||
|
||||
@@ -95,7 +95,7 @@ void RunLoop::waitForEmpty([[maybe_unused]] const mbgl::util::SimpleIdentity tag
|
||||
while (true) {
|
||||
std::size_t remaining;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
remaining = defaultQueue.size() + highPriorityQueue.size();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ private:
|
||||
};
|
||||
|
||||
void addToIndex(std::size_t sz, void* ptr) {
|
||||
std::lock_guard<std::mutex> mlk(indexMutex);
|
||||
std::scoped_lock mlk(indexMutex);
|
||||
FlagGuard flk(suppresIndexing);
|
||||
allocationsCount++;
|
||||
indexedMemorySize += sz;
|
||||
@@ -38,7 +38,7 @@ void addToIndex(std::size_t sz, void* ptr) {
|
||||
}
|
||||
|
||||
void removeFromIndex(void* ptr) {
|
||||
std::lock_guard<std::mutex> mlk(indexMutex);
|
||||
std::scoped_lock mlk(indexMutex);
|
||||
FlagGuard flk(suppresIndexing);
|
||||
auto it = memoryIndex.find(ptr);
|
||||
if (it == memoryIndex.end()) return;
|
||||
@@ -66,7 +66,7 @@ bool AllocationIndex::isActive() {
|
||||
|
||||
// static
|
||||
void AllocationIndex::reset() {
|
||||
std::lock_guard<std::mutex> mlk(indexMutex);
|
||||
std::scoped_lock mlk(indexMutex);
|
||||
FlagGuard flk(suppresIndexing);
|
||||
memoryIndex.clear();
|
||||
indexedMemorySize = 0;
|
||||
|
||||
@@ -28,8 +28,8 @@ void Mailbox::open(Scheduler& scheduler_) {
|
||||
|
||||
// As with close(), block until neither receive() nor push() are in
|
||||
// progress, and acquire the two mutexes in the same order.
|
||||
std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex);
|
||||
std::lock_guard<std::mutex> pushingLock(pushingMutex);
|
||||
std::scoped_lock receivingLock(receivingMutex);
|
||||
std::scoped_lock pushingLock(pushingMutex);
|
||||
|
||||
if (closed) {
|
||||
return;
|
||||
@@ -51,8 +51,8 @@ void Mailbox::close() {
|
||||
// will obtain them when it self-sends a message, and consistent lock
|
||||
// acquisition order prevents deadlocks. The receiving mutex is recursive to
|
||||
// allow a mailbox (and thus the actor) to close itself.
|
||||
std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex);
|
||||
std::lock_guard<std::mutex> pushingLock(pushingMutex);
|
||||
std::scoped_lock receivingLock(receivingMutex);
|
||||
std::scoped_lock pushingLock(pushingMutex);
|
||||
|
||||
closed = true;
|
||||
|
||||
@@ -89,7 +89,7 @@ void Mailbox::push(std::unique_ptr<Message> message) {
|
||||
|
||||
{
|
||||
MLN_TRACE_ZONE(push lock);
|
||||
std::lock_guard<std::mutex> pushingLock(pushingMutex);
|
||||
std::scoped_lock pushingLock(pushingMutex);
|
||||
|
||||
if (closed) {
|
||||
state = State::Abandoned;
|
||||
@@ -99,7 +99,7 @@ void Mailbox::push(std::unique_ptr<Message> message) {
|
||||
bool wasEmpty = false;
|
||||
{
|
||||
MLN_TRACE_ZONE(queue lock);
|
||||
std::lock_guard<std::mutex> queueLock(queueMutex);
|
||||
std::scoped_lock queueLock(queueMutex);
|
||||
wasEmpty = queue.empty();
|
||||
queue.push(std::move(message));
|
||||
}
|
||||
@@ -124,7 +124,7 @@ void Mailbox::receive() {
|
||||
state = State::Idle;
|
||||
}
|
||||
}};
|
||||
std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex);
|
||||
std::scoped_lock receivingLock(receivingMutex);
|
||||
|
||||
if (closed) {
|
||||
state = State::Abandoned;
|
||||
@@ -135,7 +135,7 @@ void Mailbox::receive() {
|
||||
bool wasEmpty = false;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> queueLock(queueMutex);
|
||||
std::scoped_lock queueLock(queueMutex);
|
||||
assert(!queue.empty());
|
||||
message = std::move(queue.front());
|
||||
queue.pop();
|
||||
|
||||
@@ -37,7 +37,7 @@ std::shared_ptr<Scheduler> Scheduler::GetBackground() {
|
||||
static std::weak_ptr<Scheduler> weak;
|
||||
static std::mutex mtx;
|
||||
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
std::scoped_lock lock(mtx);
|
||||
std::shared_ptr<Scheduler> scheduler = weak.lock();
|
||||
|
||||
if (!scheduler) {
|
||||
@@ -54,7 +54,7 @@ std::shared_ptr<Scheduler> Scheduler::GetSequenced() {
|
||||
static std::mutex mtx;
|
||||
static std::size_t lastUsedIndex = 0u;
|
||||
|
||||
std::lock_guard lock(mtx);
|
||||
std::scoped_lock lock(mtx);
|
||||
|
||||
lastUsedIndex = (lastUsedIndex + 1) % kSchedulersCount;
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ void updateRenderables(GetTileFn getTile,
|
||||
covered = true;
|
||||
parentOrChildTileFound = false;
|
||||
overscaledZ = idealDataTileID.overscaledZ + 1;
|
||||
if (overscaledZ > zoomRange.max) {
|
||||
if (std::cmp_greater(overscaledZ, zoomRange.max)) {
|
||||
// We're looking for an overzoomed child tile.
|
||||
const auto childDataTileID = idealDataTileID.scaledTo(overscaledZ);
|
||||
tile = getTile(childDataTileID);
|
||||
@@ -90,7 +90,8 @@ void updateRenderables(GetTileFn getTile,
|
||||
|
||||
if (!covered) {
|
||||
// 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);
|
||||
|
||||
// Request / render parent tile only if it's overscale
|
||||
|
||||
@@ -53,7 +53,7 @@ void AnnotationManager::onStyleLoaded() {
|
||||
|
||||
AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation) {
|
||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN(nextID++);
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
AnnotationID id = nextID++;
|
||||
Annotation::visit(annotation, [&](const auto& annotation_) { this->add(id, annotation_); });
|
||||
dirty = true;
|
||||
@@ -62,14 +62,14 @@ AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation) {
|
||||
|
||||
bool AnnotationManager::updateAnnotation(const AnnotationID& id, const Annotation& annotation) {
|
||||
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_); });
|
||||
return dirty;
|
||||
}
|
||||
|
||||
void AnnotationManager::removeAnnotation(const AnnotationID& id) {
|
||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
remove(id);
|
||||
dirty = true;
|
||||
}
|
||||
@@ -192,7 +192,7 @@ void AnnotationManager::updateStyle() {
|
||||
style.get().impl->addLayer(std::move(layer));
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
|
||||
for (const auto& shape : shapeAnnotations) {
|
||||
shape.second->updateStyle(*style.get().impl);
|
||||
@@ -212,7 +212,7 @@ void AnnotationManager::updateStyle() {
|
||||
|
||||
void AnnotationManager::updateData() {
|
||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
if (dirty) {
|
||||
for (auto& tile : tiles) {
|
||||
tile->setData(getTileData(tile->id.canonical));
|
||||
@@ -223,14 +223,14 @@ void AnnotationManager::updateData() {
|
||||
|
||||
void AnnotationManager::addTile(AnnotationTile& tile) {
|
||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
tiles.insert(&tile);
|
||||
tile.setData(getTileData(tile.id.canonical));
|
||||
}
|
||||
|
||||
void AnnotationManager::removeTile(AnnotationTile& tile) {
|
||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
tiles.erase(&tile);
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ std::string prefixedImageID(const std::string& id) {
|
||||
|
||||
void AnnotationManager::addImage(std::unique_ptr<style::Image> image) {
|
||||
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());
|
||||
images.erase(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_) {
|
||||
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
const std::string id = prefixedImageID(id_);
|
||||
images.erase(id);
|
||||
style.get().impl->removeImage(id);
|
||||
@@ -264,7 +264,7 @@ void AnnotationManager::removeImage(const std::string& id_) {
|
||||
|
||||
double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id_) {
|
||||
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_);
|
||||
auto it = images.find(id);
|
||||
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(
|
||||
{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();
|
||||
});
|
||||
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(),
|
||||
symbolFeatures.end());
|
||||
|
||||
std::sort(sortedFeatures.begin(),
|
||||
sortedFeatures.end(),
|
||||
[featureSortOrder](const RefIndexedSubfeature& a, const RefIndexedSubfeature& b) {
|
||||
// Same idea as the non-symbol sort order, but symbol features may
|
||||
// have changed their sort order since their corresponding
|
||||
// IndexedSubfeature was added to the CollisionIndex The
|
||||
// 'featureSortOrder' is relatively inefficient for querying but
|
||||
// cheap to build on every bucket sort
|
||||
if (featureSortOrder) {
|
||||
// queryRenderedSymbols documentation says we'll return features in
|
||||
// "top-to-bottom" rendering order (aka last-to-first).
|
||||
// Actually there can be multiple symbol instances per feature, so
|
||||
// we sort each feature based on the first matching symbol instance.
|
||||
auto sortedA = std::find(featureSortOrder->begin(), featureSortOrder->end(), a.getIndex());
|
||||
auto sortedB = std::find(featureSortOrder->begin(), featureSortOrder->end(), b.getIndex());
|
||||
assert(sortedA != featureSortOrder->end());
|
||||
assert(sortedB != featureSortOrder->end());
|
||||
return sortedA > sortedB;
|
||||
} else {
|
||||
// Bucket hasn't been re-sorted based on angle, so use same
|
||||
// "reverse of appearance in source data" logic as non-symboles
|
||||
return a.getSortIndex() > b.getSortIndex();
|
||||
}
|
||||
});
|
||||
std::ranges::sort(sortedFeatures, [featureSortOrder](const RefIndexedSubfeature& a, const RefIndexedSubfeature& b) {
|
||||
// Same idea as the non-symbol sort order, but symbol features may
|
||||
// have changed their sort order since their corresponding
|
||||
// IndexedSubfeature was added to the CollisionIndex The
|
||||
// 'featureSortOrder' is relatively inefficient for querying but
|
||||
// cheap to build on every bucket sort
|
||||
if (featureSortOrder) {
|
||||
// queryRenderedSymbols documentation says we'll return features in
|
||||
// "top-to-bottom" rendering order (aka last-to-first).
|
||||
// Actually there can be multiple symbol instances per feature, so
|
||||
// we sort each feature based on the first matching symbol instance.
|
||||
auto sortedA = std::find(featureSortOrder->begin(), featureSortOrder->end(), a.getIndex());
|
||||
auto sortedB = std::find(featureSortOrder->begin(), featureSortOrder->end(), b.getIndex());
|
||||
assert(sortedA != featureSortOrder->end());
|
||||
assert(sortedB != featureSortOrder->end());
|
||||
return sortedA > sortedB;
|
||||
} else {
|
||||
// Bucket hasn't been re-sorted based on angle, so use same
|
||||
// "reverse of appearance in source data" logic as non-symboles
|
||||
return a.getSortIndex() > b.getSortIndex();
|
||||
}
|
||||
});
|
||||
|
||||
for (const auto& symbolFeature : sortedFeatures) {
|
||||
mat4 unusedMatrix;
|
||||
|
||||
@@ -13,8 +13,9 @@ DynamicTexture::DynamicTexture(Context& context, Size size, TexturePixelType pix
|
||||
texture = context.createTexture2D();
|
||||
texture->setSize(size);
|
||||
texture->setFormat(pixelType, TextureChannelDataType::UnsignedByte);
|
||||
texture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
texture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||
.wrapU = gfx::TextureWrapType::Clamp,
|
||||
.wrapV = gfx::TextureWrapType::Clamp});
|
||||
#if MLN_DEFER_UPLOAD_ON_RENDER_THREAD
|
||||
deferredCreation = true;
|
||||
#else
|
||||
@@ -37,7 +38,7 @@ bool DynamicTexture::isEmpty() const {
|
||||
}
|
||||
|
||||
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);
|
||||
if (!bin) {
|
||||
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) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
const auto& rect = texHandle.getRectangle();
|
||||
const auto imageSize = Size(rect.w, rect.h);
|
||||
|
||||
@@ -75,7 +76,7 @@ std::optional<TextureHandle> DynamicTexture::addImage(const uint8_t* pixelData,
|
||||
}
|
||||
|
||||
void DynamicTexture::uploadDeferredImages() {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
if (deferredCreation) {
|
||||
texture->create();
|
||||
deferredCreation = false;
|
||||
@@ -88,7 +89,7 @@ void DynamicTexture::uploadDeferredImages() {
|
||||
}
|
||||
|
||||
void DynamicTexture::removeTexture(const TextureHandle& texHandle) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
auto* bin = shelfPack.getBin(texHandle.getId());
|
||||
if (!bin) {
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <mbgl/gfx/dynamic_texture_atlas.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -11,14 +12,16 @@ constexpr const uint16_t padding = ImagePosition::padding + extraPadding;
|
||||
constexpr const Size startSize = {512, 512};
|
||||
constexpr const Size dummySize = {1, 1};
|
||||
|
||||
namespace {
|
||||
Rect<uint16_t> rectWithoutExtraPadding(const Rect<uint16_t>& rect) {
|
||||
return Rect<uint16_t>(
|
||||
rect.x + extraPadding, rect.y + extraPadding, rect.w - 2 * extraPadding, rect.h - 2 * extraPadding);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
GlyphAtlas DynamicTextureAtlas::uploadGlyphs(const GlyphMap& glyphs) {
|
||||
using GlyphsToUpload = std::vector<std::tuple<TextureHandle, Immutable<Glyph>, FontStackHash>>;
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
|
||||
GlyphAtlas glyphAtlas;
|
||||
if (!glyphs.size()) {
|
||||
@@ -97,8 +100,8 @@ GlyphAtlas DynamicTextureAtlas::uploadGlyphs(const GlyphMap& glyphs) {
|
||||
glyphAtlas.dynamicTexture->uploadImage(paddedImage.data.get(), texHandle);
|
||||
}
|
||||
glyphAtlas.textureHandles.emplace_back(texHandle);
|
||||
glyphAtlas.glyphPositions[fontStack].emplace(glyph->id,
|
||||
GlyphPosition{rectWithoutExtraPadding(rect), glyph->metrics});
|
||||
glyphAtlas.glyphPositions[fontStack].emplace(
|
||||
glyph->id, GlyphPosition{.rect = rectWithoutExtraPadding(rect), .metrics = glyph->metrics});
|
||||
}
|
||||
return glyphAtlas;
|
||||
}
|
||||
@@ -107,7 +110,7 @@ ImageAtlas DynamicTextureAtlas::uploadIconsAndPatterns(const ImageMap& icons,
|
||||
const ImageMap& patterns,
|
||||
const ImageVersionMap& versionMap) {
|
||||
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;
|
||||
if (!icons.size() && !patterns.size()) {
|
||||
@@ -243,7 +246,7 @@ ImageAtlas DynamicTextureAtlas::uploadIconsAndPatterns(const ImageMap& icons,
|
||||
|
||||
void DynamicTextureAtlas::removeTextures(const std::vector<TextureHandle>& textureHandles,
|
||||
const DynamicTexturePtr& dynamicTexture) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
if (!dynamicTexture) {
|
||||
return;
|
||||
}
|
||||
@@ -252,7 +255,7 @@ void DynamicTextureAtlas::removeTextures(const std::vector<TextureHandle>& textu
|
||||
dynamicTexture->removeTexture(texHandle);
|
||||
}
|
||||
if (dynamicTexture->isEmpty()) {
|
||||
auto iterator = std::find(dynamicTextures.begin(), dynamicTextures.end(), dynamicTexture);
|
||||
auto iterator = std::ranges::find(dynamicTextures, dynamicTexture);
|
||||
if (iterator != dynamicTextures.end()) {
|
||||
dynamicTextures.erase(iterator);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@ public:
|
||||
const auto& sortKeyProperty = layout.template get<style::CircleSortKey>();
|
||||
float sortKey = sortKeyProperty.evaluate(*feature, zoom, style::CircleSortKey::defaultValue());
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -75,7 +76,7 @@ public:
|
||||
if (!bucket->hasData()) return;
|
||||
|
||||
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>
|
||||
|
||||
#if !defined(MLN_SYMBOL_GUARDS)
|
||||
#ifndef MLN_SYMBOL_GUARDS
|
||||
#define MLN_SYMBOL_GUARDS 1
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
// A temporary shim for partial C++20 support
|
||||
#if MLN_SYMBOL_GUARDS
|
||||
#if defined(__clang__)
|
||||
#ifdef __clang__
|
||||
#if __cplusplus <= 201703L || !__has_builtin(__builtin_source_location)
|
||||
namespace std {
|
||||
struct source_location {
|
||||
|
||||
@@ -153,10 +153,11 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
||||
auto modes = layout->get<TextWritingMode>();
|
||||
// Remove duplicates and preserve order.
|
||||
std::set<style::TextWritingModeType> seen;
|
||||
auto end = std::remove_if(modes.begin(), modes.end(), [&seen, this](const auto& placementMode) {
|
||||
allowVerticalPlacement = allowVerticalPlacement || placementMode == style::TextWritingModeType::Vertical;
|
||||
return !seen.insert(placementMode).second;
|
||||
});
|
||||
auto end = std::ranges::remove_if(modes, [&seen, this](const auto& placementMode) {
|
||||
allowVerticalPlacement = allowVerticalPlacement ||
|
||||
placementMode == style::TextWritingModeType::Vertical;
|
||||
return !seen.insert(placementMode).second;
|
||||
}).begin();
|
||||
modes.erase(end, modes.end());
|
||||
placementModes = std::move(modes);
|
||||
}
|
||||
@@ -299,7 +300,10 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
||||
if (ft.formattedText || ft.icon) {
|
||||
if (sortFeaturesByKey) {
|
||||
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));
|
||||
} else {
|
||||
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) {
|
||||
if (compareText.find(text) == compareText.end()) {
|
||||
if (!compareText.contains(text)) {
|
||||
compareText.emplace(text, Anchors());
|
||||
} else {
|
||||
const auto& otherAnchors = compareText.find(text)->second;
|
||||
@@ -1153,7 +1157,7 @@ void SymbolLayout::createBucket(const ImagePositions&,
|
||||
if (!firstLoad) {
|
||||
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;
|
||||
|
||||
// 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 {};
|
||||
}
|
||||
|
||||
|
||||
@@ -113,29 +113,29 @@ void Map::Impl::onUpdate() {
|
||||
|
||||
transform.updateTransitions(timePoint);
|
||||
|
||||
UpdateParameters params = {style->impl->isLoaded(),
|
||||
mode,
|
||||
pixelRatio,
|
||||
debugOptions,
|
||||
timePoint,
|
||||
transform.getState(),
|
||||
style->impl->getGlyphURL(),
|
||||
style->impl->getFontFaces(),
|
||||
style->impl->areSpritesLoaded(),
|
||||
style->impl->getTransitionOptions(),
|
||||
style->impl->getLight()->impl,
|
||||
style->impl->getImageImpls(),
|
||||
style->impl->getSourceImpls(),
|
||||
style->impl->getLayerImpls(),
|
||||
annotationManager.makeWeakPtr(),
|
||||
fileSource,
|
||||
prefetchZoomDelta,
|
||||
bool(stillImageRequest),
|
||||
crossSourceCollisions,
|
||||
tileLodMinRadius,
|
||||
tileLodScale,
|
||||
tileLodPitchThreshold,
|
||||
tileLodZoomShift};
|
||||
UpdateParameters params = {.styleLoaded = style->impl->isLoaded(),
|
||||
.mode = mode,
|
||||
.pixelRatio = pixelRatio,
|
||||
.debugOptions = debugOptions,
|
||||
.timePoint = timePoint,
|
||||
.transformState = transform.getState(),
|
||||
.glyphURL = style->impl->getGlyphURL(),
|
||||
.fontFaces = style->impl->getFontFaces(),
|
||||
.spriteLoaded = style->impl->areSpritesLoaded(),
|
||||
.transitionOptions = style->impl->getTransitionOptions(),
|
||||
.light = style->impl->getLight()->impl,
|
||||
.images = style->impl->getImageImpls(),
|
||||
.sources = style->impl->getSourceImpls(),
|
||||
.layers = style->impl->getLayerImpls(),
|
||||
.annotationManager = annotationManager.makeWeakPtr(),
|
||||
.fileSource = fileSource,
|
||||
.prefetchZoomDelta = prefetchZoomDelta,
|
||||
.stillImageRequest = bool(stillImageRequest),
|
||||
.crossSourceCollisions = crossSourceCollisions,
|
||||
.tileLodMinRadius = tileLodMinRadius,
|
||||
.tileLodScale = tileLodScale,
|
||||
.tileLodPitchThreshold = tileLodPitchThreshold,
|
||||
.tileLodZoomShift = tileLodZoomShift};
|
||||
|
||||
rendererFrontend.update(std::make_shared<UpdateParameters>(std::move(params)));
|
||||
}
|
||||
@@ -254,8 +254,10 @@ void Map::Impl::onDidFinishRenderingFrame(RenderMode renderMode,
|
||||
}
|
||||
|
||||
if (mode == MapMode::Continuous) {
|
||||
const MapObserver::RenderFrameStatus frameStatus{
|
||||
MapObserver::RenderMode(renderMode), needsRepaint, placemenChanged, stats};
|
||||
const MapObserver::RenderFrameStatus frameStatus{.mode = static_cast<MapObserver::RenderMode>(renderMode),
|
||||
.needsRepaint = needsRepaint,
|
||||
.placementChanged = placemenChanged,
|
||||
.renderingStats = stats};
|
||||
observer.onDidFinishRenderingFrame(frameStatus);
|
||||
|
||||
if (actionJournal) {
|
||||
@@ -272,7 +274,7 @@ void Map::Impl::onDidFinishRenderingFrame(RenderMode renderMode,
|
||||
}
|
||||
}
|
||||
} else if (stillImageRequest && rendererFullyLoaded) {
|
||||
auto request = std::move(stillImageRequest);
|
||||
const auto request = std::move(stillImageRequest);
|
||||
request->callback(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,8 @@ UniqueShaderProgram Context::createProgram(shaders::BuiltIn shaderID,
|
||||
// options->setOptimizationLevel(MTL::LibraryOptimizationLevelDefault);
|
||||
|
||||
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();
|
||||
auto library = NS::TransferPtr(device->newLibrary(nsSource, options.get(), &error));
|
||||
@@ -152,7 +153,8 @@ UniqueShaderProgram Context::createProgram(shaders::BuiltIn shaderID,
|
||||
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));
|
||||
if (!vertexFunction) {
|
||||
Log::Error(Event::Shader, name + " missing vertex function " + vertexName.data());
|
||||
@@ -164,7 +166,8 @@ UniqueShaderProgram Context::createProgram(shaders::BuiltIn shaderID,
|
||||
// fragment function is optional
|
||||
MTLFunctionPtr fragmentFunction;
|
||||
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));
|
||||
if (!fragmentFunction) {
|
||||
Log::Error(Event::Shader, name + " missing fragment function " + fragmentName.data());
|
||||
@@ -286,15 +289,15 @@ const UniqueVertexBufferResource& Context::getEmptyVertexBuffer() {
|
||||
|
||||
namespace {
|
||||
const auto clipMaskStencilMode = gfx::StencilMode{
|
||||
/*.test=*/gfx::StencilMode::Always(),
|
||||
/*.ref=*/0,
|
||||
/*.mask=*/0b11111111,
|
||||
/*.fail=*/gfx::StencilOpType::Keep,
|
||||
/*.depthFail=*/gfx::StencilOpType::Keep,
|
||||
/*.pass=*/gfx::StencilOpType::Replace,
|
||||
.test = gfx::StencilMode::Always(),
|
||||
.ref = 0,
|
||||
.mask = 0b11111111,
|
||||
.fail = gfx::StencilOpType::Keep,
|
||||
.depthFail = gfx::StencilOpType::Keep,
|
||||
.pass = gfx::StencilOpType::Replace,
|
||||
};
|
||||
const auto clipMaskDepthMode = gfx::DepthMode{/*.func=*/gfx::DepthFunctionType::Always,
|
||||
/*.mask=*/gfx::DepthMaskType::ReadOnly};
|
||||
const auto clipMaskDepthMode = gfx::DepthMode{.func = gfx::DepthFunctionType::Always,
|
||||
.mask = gfx::DepthMaskType::ReadOnly};
|
||||
} // namespace
|
||||
|
||||
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 {
|
||||
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
|
||||
@@ -181,8 +184,10 @@ void Drawable::draw(PaintParameters& parameters) const {
|
||||
if (impl->renderPassDescriptor && descriptor != *impl->renderPassDescriptor) {
|
||||
impl->pipelineState.reset();
|
||||
}
|
||||
impl->renderPassDescriptor.emplace(gfx::RenderPassDescriptor{
|
||||
descriptor.renderable, descriptor.clearColor, descriptor.clearDepth, descriptor.clearStencil});
|
||||
impl->renderPassDescriptor.emplace(gfx::RenderPassDescriptor{.renderable = descriptor.renderable,
|
||||
.clearColor = descriptor.clearColor,
|
||||
.clearDepth = descriptor.clearDepth,
|
||||
.clearStencil = descriptor.clearStencil});
|
||||
|
||||
const auto& shaderMTL = static_cast<const ShaderProgram&>(*shader);
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@ public:
|
||||
colorTexture = context.createTexture2D();
|
||||
colorTexture->setSize(size);
|
||||
colorTexture->setFormat(gfx::TexturePixelType::RGBA, type);
|
||||
colorTexture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
colorTexture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||
.wrapU = gfx::TextureWrapType::Clamp,
|
||||
.wrapV = gfx::TextureWrapType::Clamp});
|
||||
static_cast<Texture2D*>(colorTexture.get())
|
||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||
|
||||
@@ -32,8 +33,9 @@ public:
|
||||
depthTexture = context.createTexture2D();
|
||||
depthTexture->setSize(size);
|
||||
depthTexture->setFormat(gfx::TexturePixelType::Depth, gfx::TextureChannelDataType::Float);
|
||||
depthTexture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
depthTexture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||
.wrapU = gfx::TextureWrapType::Clamp,
|
||||
.wrapV = gfx::TextureWrapType::Clamp});
|
||||
static_cast<Texture2D*>(depthTexture.get())
|
||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||
}
|
||||
@@ -44,8 +46,9 @@ public:
|
||||
stencilTexture = context.createTexture2D();
|
||||
stencilTexture->setSize(size);
|
||||
stencilTexture->setFormat(gfx::TexturePixelType::Stencil, gfx::TextureChannelDataType::UnsignedByte);
|
||||
stencilTexture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
stencilTexture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||
.wrapU = gfx::TextureWrapType::Clamp,
|
||||
.wrapV = gfx::TextureWrapType::Clamp});
|
||||
static_cast<Texture2D*>(stencilTexture.get())
|
||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ void RenderPass::resetState() {
|
||||
|
||||
currentCullMode = MTL::CullModeNone;
|
||||
currentWinding = MTL::WindingClockwise;
|
||||
currentScissorRect = {0, 0, 0, 0};
|
||||
currentScissorRect = {.x = 0, .y = 0, .width = 0, .height = 0};
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -130,7 +130,7 @@ void RenderPass::bindVertex(const BufferResource& buf, std::size_t offset, std::
|
||||
return;
|
||||
}
|
||||
}
|
||||
vertexBinds[index] = BindInfo{&buf, actualSize, offset};
|
||||
vertexBinds[index] = BindInfo{.buf = &buf, .size = actualSize, .offset = offset};
|
||||
}
|
||||
buf.bindVertex(encoder, offset, index, actualSize);
|
||||
}
|
||||
@@ -156,7 +156,7 @@ void RenderPass::bindFragment(const BufferResource& buf, std::size_t offset, std
|
||||
return;
|
||||
}
|
||||
}
|
||||
fragmentBinds[index] = BindInfo{&buf, actualSize, offset};
|
||||
fragmentBinds[index] = BindInfo{.buf = &buf, .size = actualSize, .offset = offset};
|
||||
}
|
||||
buf.bindFragment(encoder, offset, index, actualSize);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ Texture2D::Texture2D(Context& context_)
|
||||
Texture2D::~Texture2D() {
|
||||
if (metalTexture) {
|
||||
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 {
|
||||
return size.width * size.height * getPixelStride();
|
||||
return size.width * size.height * getPixelStride(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
|
||||
}
|
||||
|
||||
size_t Texture2D::getPixelStride() const noexcept {
|
||||
switch (channelType) {
|
||||
case gfx::TextureChannelDataType::UnsignedByte:
|
||||
return 1 * numChannels();
|
||||
return 1 * numChannels(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
|
||||
case gfx::TextureChannelDataType::HalfFloat:
|
||||
return 2 * numChannels();
|
||||
return 2 * numChannels(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
|
||||
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.
|
||||
// 2D drawables will set their own stencil mode within `draw`.
|
||||
if (features3d) {
|
||||
const auto state = getDepthStencilState(drawable.getEnableDepth(), drawable.getEnableStencil());
|
||||
const auto& state = getDepthStencilState(drawable.getEnableDepth(), drawable.getEnableStencil());
|
||||
renderPass.setDepthStencilState(state);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ UniformBuffer::UniformBuffer(BufferResource&& buffer_)
|
||||
|
||||
UniformBuffer::UniformBuffer(UniformBuffer&& other)
|
||||
: gfx::UniformBuffer(std::move(other)),
|
||||
buffer(std::move(other.buffer)) {}
|
||||
buffer(std::move(other.buffer)) {} // NOLINT(bugprone-use-after-move)
|
||||
|
||||
UniformBuffer::~UniformBuffer() {
|
||||
buffer.getContext().renderingStats().numUniformBuffers--;
|
||||
@@ -43,7 +43,7 @@ void UniformBufferArray::bindMtl(RenderPass& renderPass) const noexcept {
|
||||
for (size_t id = 0; id < allocatedSize(); id++) {
|
||||
const auto& uniformBuffer = get(id);
|
||||
if (!uniformBuffer) continue;
|
||||
const auto& buffer = static_cast<UniformBuffer&>(*uniformBuffer.get());
|
||||
const auto& buffer = static_cast<UniformBuffer&>(*uniformBuffer);
|
||||
const auto& resource = buffer.getBufferResource();
|
||||
if (id != shaders::idDrawableReservedFragmentOnlyUBO) {
|
||||
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
|
||||
// attribute at compile time, regardless of whether it's ever used at runtime.
|
||||
bindings[index] = {
|
||||
/*.attribute = */ {defaultAttr.getDataType(), /*offset=*/0},
|
||||
/*.vertexStride = */ static_cast<uint32_t>(VertexAttribute::getStrideOf(defaultAttr.getDataType())),
|
||||
/*.vertexBufferResource = */ nullptr,
|
||||
/*.vertexOffset = */ 0,
|
||||
.attribute = {.dataType = defaultAttr.getDataType(), /*offset=*/.offset = 0},
|
||||
.vertexStride = static_cast<uint32_t>(VertexAttribute::getStrideOf(defaultAttr.getDataType())),
|
||||
.vertexBufferResource = nullptr,
|
||||
.vertexOffset = 0,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -30,19 +30,19 @@ Settings& Settings::getInstance() 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
impl->settings[pair.first] = pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
for (const auto& key : keys) {
|
||||
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 {
|
||||
std::lock_guard<std::mutex> lock(impl->mutex);
|
||||
std::scoped_lock lock(impl->mutex);
|
||||
return getValue(key, impl->settings);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ DebugBucket::DebugBucket(const OverscaledTileID& id,
|
||||
std::optional<Point<int16_t>> prev;
|
||||
|
||||
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) {
|
||||
prev = {};
|
||||
} else {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mbgl/text/cross_tile_symbol_index.hpp>
|
||||
#include <mbgl/text/placement.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -210,7 +211,7 @@ SymbolInstanceReferences SymbolBucket::getSortedSymbols(const float angle) const
|
||||
const float sin = std::sin(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 bRotated = std::lround(sin * b.getAnchor().point.x + cos * b.getAnchor().point.y);
|
||||
if (aRotated != bRotated) {
|
||||
|
||||
@@ -24,7 +24,7 @@ void ImageManager::setObserver(ImageManagerObserver* observer_) {
|
||||
}
|
||||
|
||||
void ImageManager::setLoaded(bool loaded_) {
|
||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
||||
std::scoped_lock readWriteLock(rwLock);
|
||||
if (loaded == loaded_) {
|
||||
return;
|
||||
}
|
||||
@@ -45,11 +45,11 @@ bool ImageManager::isLoaded() const {
|
||||
}
|
||||
|
||||
void ImageManager::addImage(Immutable<style::Image::Impl> image_) {
|
||||
std::lock_guard<std::recursive_mutex> readLock(rwLock);
|
||||
assert(images.find(image_->id) == images.end());
|
||||
std::scoped_lock readLock(rwLock);
|
||||
assert(!images.contains(image_->id));
|
||||
|
||||
// Increase cache size if requested image was provided.
|
||||
if (requestedImages.find(image_->id) != requestedImages.end()) {
|
||||
if (requestedImages.contains(image_->id)) {
|
||||
requestedImagesCacheSize += image_->image.bytes();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ void ImageManager::addImage(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);
|
||||
assert(oldImage != images.end());
|
||||
@@ -68,7 +68,7 @@ bool ImageManager::updateImage(Immutable<style::Image::Impl> image_) {
|
||||
|
||||
if (sizeChanged) {
|
||||
// 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();
|
||||
assert(static_cast<int64_t>(requestedImagesCacheSize + diff) >= 0ll);
|
||||
requestedImagesCacheSize += diff;
|
||||
@@ -84,7 +84,7 @@ bool ImageManager::updateImage(Immutable<style::Image::Impl> image_) {
|
||||
}
|
||||
|
||||
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);
|
||||
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 {
|
||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
||||
std::scoped_lock readWriteLock(rwLock);
|
||||
if (auto* image = getSharedImage(id)) {
|
||||
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 {
|
||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
||||
std::scoped_lock readWriteLock(rwLock);
|
||||
const auto it = images.find(id);
|
||||
if (it != images.end()) {
|
||||
return &(it->second);
|
||||
@@ -122,7 +122,7 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair)
|
||||
// remove previous requests from this tile
|
||||
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
|
||||
// runtime styling), then notify the requestor immediately. Otherwise, if the
|
||||
@@ -133,7 +133,7 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair)
|
||||
if (!isLoaded()) {
|
||||
bool hasAllDependencies = true;
|
||||
for (const auto& dependency : pair.first) {
|
||||
if (images.find(dependency.first) == images.end()) {
|
||||
if (!images.contains(dependency.first)) {
|
||||
hasAllDependencies = false;
|
||||
break;
|
||||
}
|
||||
@@ -150,7 +150,7 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair)
|
||||
}
|
||||
|
||||
void ImageManager::removeRequestor(ImageRequestor& requestor) {
|
||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
||||
std::scoped_lock readWriteLock(rwLock);
|
||||
|
||||
requestors.erase(&requestor);
|
||||
missingImageRequestors.erase(&requestor);
|
||||
@@ -160,7 +160,7 @@ void ImageManager::removeRequestor(ImageRequestor& requestor) {
|
||||
}
|
||||
|
||||
void ImageManager::notifyIfMissingImageAdded() {
|
||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
||||
std::scoped_lock readWriteLock(rwLock);
|
||||
|
||||
for (auto it = missingImageRequestors.begin(); it != missingImageRequestors.end();) {
|
||||
ImageRequestor& requestor = *it->first;
|
||||
@@ -174,13 +174,13 @@ void ImageManager::notifyIfMissingImageAdded() {
|
||||
}
|
||||
|
||||
void ImageManager::reduceMemoryUse() {
|
||||
std::lock_guard<std::recursive_mutex> readLock(rwLock);
|
||||
std::scoped_lock readLock(rwLock);
|
||||
|
||||
std::vector<std::string> unusedIDs;
|
||||
unusedIDs.reserve(requestedImages.size());
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -199,7 +199,7 @@ void ImageManager::reduceMemoryUseIfCacheSizeExceedsLimit() {
|
||||
|
||||
std::set<std::string> ImageManager::getAvailableImages() const {
|
||||
MLN_TRACE_FUNC();
|
||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
||||
std::scoped_lock readWriteLock(rwLock);
|
||||
|
||||
{
|
||||
MLN_TRACE_ZONE(copy);
|
||||
@@ -208,7 +208,7 @@ std::set<std::string> ImageManager::getAvailableImages() const {
|
||||
}
|
||||
|
||||
void ImageManager::clear() {
|
||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
||||
std::scoped_lock readWriteLock(rwLock);
|
||||
|
||||
assert(requestors.empty());
|
||||
assert(missingImageRequestors.empty());
|
||||
@@ -224,14 +224,14 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
|
||||
ImageDependencies missingDependencies;
|
||||
|
||||
for (const auto& dependency : pair.first) {
|
||||
if (images.find(dependency.first) == images.end()) {
|
||||
if (!images.contains(dependency.first)) {
|
||||
missingDependencies.emplace(dependency);
|
||||
}
|
||||
}
|
||||
|
||||
if (!missingDependencies.empty()) {
|
||||
ImageRequestor* requestorPtr = &requestor;
|
||||
assert(!missingImageRequestors.count(requestorPtr));
|
||||
assert(!missingImageRequestors.contains(requestorPtr));
|
||||
missingImageRequestors.emplace(requestorPtr, pair);
|
||||
|
||||
for (const auto& dependency : missingDependencies) {
|
||||
@@ -261,7 +261,7 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
|
||||
}
|
||||
|
||||
auto removePendingRequests = [this, missingImage] {
|
||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
||||
std::scoped_lock readWriteLock(rwLock);
|
||||
auto existingRequest = requestedImages.find(missingImage);
|
||||
if (existingRequest == requestedImages.end()) {
|
||||
return;
|
||||
@@ -277,7 +277,7 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
|
||||
} else {
|
||||
// Associate requestor with an image that was provided by the client.
|
||||
for (const auto& dependency : pair.first) {
|
||||
if (requestedImages.find(dependency.first) != requestedImages.end()) {
|
||||
if (requestedImages.contains(dependency.first)) {
|
||||
requestedImages[dependency.first].emplace(&requestor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace mbgl {
|
||||
using namespace style;
|
||||
using namespace shaders;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#ifndef NDEBUG
|
||||
constexpr auto BackgroundPatternShaderName = "BackgroundPatternShader";
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@ void BackgroundLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintPara
|
||||
const auto& state = parameters.state;
|
||||
auto& context = parameters.context;
|
||||
|
||||
#if defined(DEBUG)
|
||||
#ifdef DEBUG
|
||||
const auto label = layerGroup.getName() + "-update-uniforms";
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
|
||||
auto& context = parameters.context;
|
||||
const auto& evaluated = static_cast<const CircleLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#ifndef NDEBUG
|
||||
const auto label = layerGroup.getName() + "-update-uniforms";
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,7 @@ void HeatmapTextureLayerTweaker::execute(LayerGroupBase& layerGroup, const Paint
|
||||
|
||||
const auto& evaluated = static_cast<const HeatmapLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#ifndef NDEBUG
|
||||
const auto label = layerGroup.getName() + "-update-uniforms";
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,7 @@ void HillshadeLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParam
|
||||
|
||||
const auto& evaluated = static_cast<const HillshadeLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#ifndef NDEBUG
|
||||
const auto label = layerGroup.getName() + "-update-uniforms";
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <mbgl/renderer/update_parameters.hpp>
|
||||
#include <mbgl/shaders/shader_program_base.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
@@ -118,10 +120,10 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
|
||||
[[maybe_unused]] UniqueChangeRequestVec& changes) {
|
||||
assert(updateParameters);
|
||||
const auto zoom = state.getIntegerZoom();
|
||||
const auto tileCover = util::tileCover({state,
|
||||
updateParameters->tileLodMinRadius,
|
||||
updateParameters->tileLodScale,
|
||||
updateParameters->tileLodPitchThreshold},
|
||||
const auto tileCover = util::tileCover({.transformState = state,
|
||||
.tileLodMinRadius = updateParameters->tileLodMinRadius,
|
||||
.tileLodScale = updateParameters->tileLodScale,
|
||||
.tileLodPitchThreshold = updateParameters->tileLodPitchThreshold},
|
||||
zoom);
|
||||
|
||||
// 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.
|
||||
// (Note that `RenderTiles` is empty, and this layer does not use it)
|
||||
tileLayerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) -> bool {
|
||||
return drawable.getTileID() &&
|
||||
(std::find(tileCover.begin(), tileCover.end(), *drawable.getTileID()) == tileCover.end());
|
||||
return drawable.getTileID() && (std::ranges::find(tileCover, *drawable.getTileID()) == tileCover.end());
|
||||
});
|
||||
|
||||
// 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.texture) {
|
||||
info.textureInfo.texture = context.createTexture2D();
|
||||
info.textureInfo.texture->setSamplerConfiguration({gfx::TextureFilterType::Linear,
|
||||
gfx::TextureWrapType::Clamp,
|
||||
gfx::TextureWrapType::Clamp,
|
||||
16,
|
||||
true});
|
||||
info.textureInfo.texture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||
.wrapU = gfx::TextureWrapType::Clamp,
|
||||
.wrapV = gfx::TextureWrapType::Clamp,
|
||||
.maxAnisotropy = 16,
|
||||
.mipmapped = true});
|
||||
}
|
||||
|
||||
info.textureInfo.texture->upload(info.textureInfo.image->get()->image);
|
||||
|
||||
@@ -243,8 +243,11 @@ void RenderSymbolLayer::prepare(const LayerPrepareParameters& params) {
|
||||
.featureIndex = featureIndex,
|
||||
.sourceId = baseImpl->source,
|
||||
.sortKeyRange = sortKeyRange};
|
||||
auto sortPosition = std::upper_bound(
|
||||
placementData.cbegin(), placementData.cend(), layerData, [](const auto& lhs, const auto& rhs) {
|
||||
auto sortPosition = std::upper_bound( // NOLINT(modernize-use-ranges)
|
||||
placementData.cbegin(),
|
||||
placementData.cend(),
|
||||
layerData,
|
||||
[](const auto& lhs, const auto& rhs) {
|
||||
assert(lhs.sortKeyRange && rhs.sortKeyRange);
|
||||
return lhs.sortKeyRange->sortKey < rhs.sortKeyRange->sortKey;
|
||||
});
|
||||
@@ -546,7 +549,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
setRenderTileBucketID(tileID, bucket.getID());
|
||||
|
||||
assert(bucket.paintProperties.find(getID()) != bucket.paintProperties.end());
|
||||
assert(bucket.paintProperties.contains(getID()));
|
||||
const auto& bucketPaintProperties = bucket.paintProperties.at(getID());
|
||||
|
||||
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;
|
||||
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, mask, {depth, depth}};
|
||||
#else
|
||||
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, mask};
|
||||
return gfx::DepthMode{.func = gfx::DepthFunctionType::LessEqual, .mask = mask};
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ gfx::DepthMode PaintParameters::depthModeFor3D() const {
|
||||
#if MLN_RENDER_BACKEND_OPENGL
|
||||
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, gfx::DepthMaskType::ReadWrite, {0.0, depthRangeSize}};
|
||||
#else
|
||||
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, gfx::DepthMaskType::ReadWrite};
|
||||
return gfx::DepthMode{.func = gfx::DepthFunctionType::LessEqual, .mask = gfx::DepthMaskType::ReadWrite};
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -150,12 +150,8 @@ void PaintParameters::clearStencil() {
|
||||
const auto debugGroup = renderPass->createDebugGroup("tile-clip-mask-clear");
|
||||
#endif
|
||||
|
||||
const std::vector<shaders::ClipUBO> tileUBO = {
|
||||
shaders::ClipUBO{/* .matrix = */ util::cast<float>(matrixForTile({0, 0, 0})),
|
||||
/* .stencil_ref = */ 0,
|
||||
/* .pad1 = */ 0,
|
||||
/* .pad2 = */ 0,
|
||||
/* .pad3 = */ 0}};
|
||||
const std::vector<shaders::ClipUBO> tileUBO = {shaders::ClipUBO{
|
||||
.matrix = util::cast<float>(matrixForTile({0, 0, 0})), .stencil_ref = 0, .pad1 = 0, .pad2 = 0, .pad3 = 0}};
|
||||
mtlContext.renderTileClippingMasks(*renderPass, staticData, tileUBO);
|
||||
context.renderingStats().stencilClears++;
|
||||
#elif MLN_RENDER_BACKEND_VULKAN
|
||||
@@ -239,11 +235,11 @@ void PaintParameters::renderTileClippingMasks(const RenderTiles& renderTiles) {
|
||||
tileUBOs.reserve(count);
|
||||
}
|
||||
|
||||
tileUBOs.emplace_back(shaders::ClipUBO{/* .matrix = */ util::cast<float>(matrixForTile(tileID)),
|
||||
/* .stencil_ref = */ static_cast<uint32_t>(stencilID),
|
||||
/* .pad1 = */ 0,
|
||||
/* .pad2 = */ 0,
|
||||
/* .pad3 = */ 0});
|
||||
tileUBOs.emplace_back(shaders::ClipUBO{.matrix = util::cast<float>(matrixForTile(tileID)),
|
||||
.stencil_ref = static_cast<uint32_t>(stencilID),
|
||||
.pad1 = 0,
|
||||
.pad2 = 0,
|
||||
.pad3 = 0});
|
||||
}
|
||||
|
||||
if (!tileUBOs.empty()) {
|
||||
@@ -347,12 +343,12 @@ gfx::StencilMode PaintParameters::stencilModeForClipping(const UnwrappedTileID&
|
||||
auto it = tileClippingMaskIDs.find(tileID);
|
||||
assert(it != tileClippingMaskIDs.end());
|
||||
const int32_t id = it != tileClippingMaskIDs.end() ? it->second : 0b00000000;
|
||||
return gfx::StencilMode{gfx::StencilMode::Equal{0b11111111},
|
||||
id,
|
||||
0b00000000,
|
||||
gfx::StencilOpType::Keep,
|
||||
gfx::StencilOpType::Keep,
|
||||
gfx::StencilOpType::Replace};
|
||||
return gfx::StencilMode{.test = gfx::StencilMode::Equal{0b11111111},
|
||||
.ref = id,
|
||||
.mask = 0b00000000,
|
||||
.fail = gfx::StencilOpType::Keep,
|
||||
.depthFail = gfx::StencilOpType::Keep,
|
||||
.pass = gfx::StencilOpType::Replace};
|
||||
}
|
||||
|
||||
gfx::StencilMode PaintParameters::stencilModeFor3D() {
|
||||
@@ -365,21 +361,21 @@ gfx::StencilMode PaintParameters::stencilModeFor3D() {
|
||||
tileClippingMaskIDs.clear();
|
||||
|
||||
const int32_t id = nextStencilID++;
|
||||
return gfx::StencilMode{gfx::StencilMode::NotEqual{0b11111111},
|
||||
id,
|
||||
0b11111111,
|
||||
gfx::StencilOpType::Keep,
|
||||
gfx::StencilOpType::Keep,
|
||||
gfx::StencilOpType::Replace};
|
||||
return gfx::StencilMode{.test = gfx::StencilMode::NotEqual{0b11111111},
|
||||
.ref = id,
|
||||
.mask = 0b11111111,
|
||||
.fail = gfx::StencilOpType::Keep,
|
||||
.depthFail = gfx::StencilOpType::Keep,
|
||||
.pass = gfx::StencilOpType::Replace};
|
||||
}
|
||||
|
||||
gfx::ColorMode PaintParameters::colorModeForRenderPass() const {
|
||||
if (debugOptions & MapDebugOptions::Overdraw) {
|
||||
constexpr float overdraw = 1.0f / 8.0f;
|
||||
return gfx::ColorMode{
|
||||
gfx::ColorMode::Add{gfx::ColorBlendFactorType::ConstantColor, gfx::ColorBlendFactorType::One},
|
||||
Color{overdraw, overdraw, overdraw, 0.0f},
|
||||
gfx::ColorMode::Mask{true, true, true, true}};
|
||||
return gfx::ColorMode{.blendFunction = gfx::ColorMode::Add{gfx::ColorBlendFactorType::ConstantColor,
|
||||
gfx::ColorBlendFactorType::One},
|
||||
.blendColor = Color{overdraw, overdraw, overdraw, 0.0f},
|
||||
.mask = gfx::ColorMode::Mask{.r = true, .g = true, .b = true, .a = true}};
|
||||
} else if (pass == RenderPass::Translucent) {
|
||||
return gfx::ColorMode::alphaBlended();
|
||||
} 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) {
|
||||
if (patterns.find(image.id) != patterns.end()) {
|
||||
if (patterns.contains(image.id)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const uint16_t width = image.image.size.width + padding * 2;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
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::copy_if(layers.begin(),
|
||||
layers.end(),
|
||||
std::inserter(crossTileSymbolIndexLayers, crossTileSymbolIndexLayers.begin()),
|
||||
hasCrossTileIndex);
|
||||
std::ranges::copy_if(
|
||||
layers, std::inserter(crossTileSymbolIndexLayers, crossTileSymbolIndexLayers.begin()), hasCrossTileIndex);
|
||||
|
||||
if (crossTileSymbolIndexLayers.empty()) {
|
||||
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
|
||||
// a bucket For a predictable global sort renderItems, we sort the buckets
|
||||
// based on their corresponding tile position
|
||||
std::sort(
|
||||
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) <
|
||||
std::tie(b.tileID.canonical.z, b.tileID.canonical.y, b.tileID.wrap, b.tileID.canonical.x);
|
||||
});
|
||||
std::ranges::sort(bucketQueryData, [](const RetainedQueryData& a, const RetainedQueryData& b) {
|
||||
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);
|
||||
});
|
||||
|
||||
for (auto wrappedQueryData : bucketQueryData) {
|
||||
auto& queryData = wrappedQueryData.get();
|
||||
@@ -619,7 +618,7 @@ void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, st
|
||||
|
||||
for (auto layer : bucketSymbols) {
|
||||
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)) {
|
||||
auto sourceResults = renderSource->queryRenderedFeatures(
|
||||
geometry, transformState, filteredLayers, options, projMatrix);
|
||||
std::move(
|
||||
sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
|
||||
std::ranges::move(sourceResults, std::inserter(resultsByLayer, resultsByLayer.begin()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -991,7 +989,7 @@ void RenderOrchestrator::processChanges() {
|
||||
}
|
||||
|
||||
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()) {
|
||||
renderTargets.emplace_back(renderTarget);
|
||||
return true;
|
||||
@@ -1001,7 +999,7 @@ bool RenderOrchestrator::addRenderTarget(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()) {
|
||||
renderTargets.erase(it);
|
||||
return true;
|
||||
|
||||
@@ -73,7 +73,7 @@ void RenderTarget::render(RenderOrchestrator& orchestrator, const RenderTree& re
|
||||
|
||||
const gfx::ScissorRect prevSicssorRect = parameters.scissorRect;
|
||||
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
|
||||
parameters.currentLayer = 0;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <mbgl/renderer/update_parameters.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
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;
|
||||
ids.reserve(set.size());
|
||||
std::move(set.begin(), set.end(), std::back_inserter(ids));
|
||||
std::ranges::move(set, std::back_inserter(ids));
|
||||
return ids;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ void Renderer::Impl::render(const RenderTree& renderTree, const std::shared_ptr<
|
||||
if (!commandCaptureScope) {
|
||||
if (const auto& cmdQueue = mtlBackend.getCommandQueue()) {
|
||||
if (const auto captureManager = NS::RetainPtr(MTL::CaptureManager::sharedCaptureManager())) {
|
||||
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
|
||||
if ((commandCaptureScope = NS::TransferPtr(captureManager->newCaptureScope(cmdQueue.get())))) {
|
||||
const auto label = "Renderer::Impl frame=" + util::toString(frameCount);
|
||||
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;
|
||||
// Add additional wrapped tile ids if neccessary
|
||||
auto idealTiles = util::tileCover(
|
||||
{transformState, parameters.tileLodMinRadius, parameters.tileLodScale, parameters.tileLodPitchThreshold},
|
||||
static_cast<uint8_t>(transformState.getZoom()));
|
||||
auto idealTiles = util::tileCover({.transformState = transformState,
|
||||
.tileLodMinRadius = parameters.tileLodMinRadius,
|
||||
.tileLodScale = parameters.tileLodScale,
|
||||
.tileLodPitchThreshold = parameters.tileLodPitchThreshold},
|
||||
static_cast<uint8_t>(transformState.getZoom()));
|
||||
for (auto tile : idealTiles) {
|
||||
if (tile.wrap != 0 && tileCover[0].canonical.isChildOf(tile.canonical)) {
|
||||
tileIds.emplace_back(tile.wrap, tileCover[0].canonical);
|
||||
|
||||
@@ -90,13 +90,13 @@ public:
|
||||
assert(propsUBO.expressionMask == LineExpressionMask::None);
|
||||
|
||||
const LineExpressionUBO exprUBO = {
|
||||
/* .color = */ nullptr,
|
||||
/* .blur = */ nullptr,
|
||||
/* .opacity = */ nullptr,
|
||||
/* .gapwidth = */ nullptr,
|
||||
/* .offset = */ nullptr,
|
||||
/* .width = */ nullptr,
|
||||
/* .floorWidth = */ nullptr,
|
||||
.color = nullptr,
|
||||
.blur = nullptr,
|
||||
.opacity = nullptr,
|
||||
.gapwidth = nullptr,
|
||||
.offset = nullptr,
|
||||
.width = nullptr,
|
||||
.floorWidth = nullptr,
|
||||
};
|
||||
layerUniforms.createOrUpdate(idLineExpressionUBO, &exprUBO, context);
|
||||
|
||||
@@ -122,16 +122,15 @@ public:
|
||||
#else
|
||||
const shaders::LineDrawableUBO drawableUBO = {
|
||||
#endif
|
||||
/* .matrix = */ util::cast<float>(matrix),
|
||||
/* .ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, zoom),
|
||||
|
||||
/* .color_t = */ 0.f,
|
||||
/* .blur_t = */ 0.f,
|
||||
/* .opacity_t = */ 0.f,
|
||||
/* .gapwidth_t = */ 0.f,
|
||||
/* .offset_t = */ 0.f,
|
||||
/* .width_t = */ 0.f,
|
||||
/* .pad1 = */ 0
|
||||
.matrix = util::cast<float>(matrix),
|
||||
.ratio = 1.0f / tileID.pixelsToTileUnits(1.0f, zoom),
|
||||
.color_t = 0.f,
|
||||
.blur_t = 0.f,
|
||||
.opacity_t = 0.f,
|
||||
.gapwidth_t = 0.f,
|
||||
.offset_t = 0.f,
|
||||
.width_t = 0.f,
|
||||
.pad1 = 0
|
||||
};
|
||||
|
||||
#if MLN_UBO_CONSOLIDATION
|
||||
@@ -255,8 +254,9 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
||||
std::array<uint8_t, 4> data{{0, 0, 0, 0}};
|
||||
auto emptyImage = std::make_shared<PremultipliedImage>(Size(1, 1), data.data(), data.size());
|
||||
texture->setImage(emptyImage);
|
||||
texture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
texture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
|
||||
.wrapU = gfx::TextureWrapType::Clamp,
|
||||
.wrapV = gfx::TextureWrapType::Clamp});
|
||||
}
|
||||
|
||||
// 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
|
||||
const shaders::LineEvaluatedPropsUBO linePropertiesUBO = {/* .color = */ Color::red(),
|
||||
/* .blur = */ 0.f,
|
||||
/* .opacity = */ 1.f,
|
||||
/* .gapwidth = */ 0.f,
|
||||
/* .offset = */ 0.f,
|
||||
/* .width = */ 4.f,
|
||||
/* .floorwidth = */ 0,
|
||||
/* .expressionMask = */ LineExpressionMask::None,
|
||||
/* .pad1 = */ 0};
|
||||
const shaders::LineEvaluatedPropsUBO linePropertiesUBO = {.color = Color::red(),
|
||||
.blur = 0.f,
|
||||
.opacity = 1.f,
|
||||
.gapwidth = 0.f,
|
||||
.offset = 0.f,
|
||||
.width = 4.f,
|
||||
.floorwidth = 0,
|
||||
.expressionMask = LineExpressionMask::None,
|
||||
.pad1 = 0};
|
||||
|
||||
// function to add polylines drawable
|
||||
const auto addPolylineDrawable = [&](TileLayerGroup* tileLayerGroup, const RenderTile& tile) {
|
||||
@@ -358,12 +358,12 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
||||
const auto& debugBucket = tile.debugBucket;
|
||||
if (!debugBucket) continue;
|
||||
|
||||
const DebugUBO outlineUBO = {/* .matrix = */ util::cast<float>(tile.matrix),
|
||||
/* .color = */ Color::white(),
|
||||
/* .overlay_scale = */ 1.0f,
|
||||
/* .pad1 = */ 0,
|
||||
/* .pad2 = */ 0,
|
||||
/* .pad3 = */ 0};
|
||||
const DebugUBO outlineUBO = {.matrix = util::cast<float>(tile.matrix),
|
||||
.color = Color::white(),
|
||||
.overlay_scale = 1.0f,
|
||||
.pad1 = 0,
|
||||
.pad2 = 0,
|
||||
.pad3 = 0};
|
||||
if (0 == updateDrawables(outlineLayerGroup, tileID, outlineUBO)) {
|
||||
addDrawable(outlineLayerGroup,
|
||||
tileID,
|
||||
@@ -374,12 +374,12 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
||||
debugBucket->segments);
|
||||
}
|
||||
|
||||
const DebugUBO textUBO = {/* .matrix = */ util::cast<float>(tile.matrix),
|
||||
/* .color = */ Color::black(),
|
||||
/* .overlay_scale = */ 1.0f,
|
||||
/* .pad1 = */ 0,
|
||||
/* .pad2 = */ 0,
|
||||
/* .pad3 = */ 0};
|
||||
const DebugUBO textUBO = {.matrix = util::cast<float>(tile.matrix),
|
||||
.color = Color::black(),
|
||||
.overlay_scale = 1.0f,
|
||||
.pad1 = 0,
|
||||
.pad2 = 0,
|
||||
.pad3 = 0};
|
||||
if (0 == updateDrawables(textLayerGroup, tileID, textUBO) && tile.getNeedsRendering()) {
|
||||
addDrawable(textLayerGroup,
|
||||
tileID,
|
||||
|
||||
@@ -110,12 +110,12 @@ void TilePyramid::update(const std::vector<Immutable<style::LayerProperties>>& l
|
||||
std::vector<OverscaledTileID> idealTiles;
|
||||
std::vector<OverscaledTileID> panTiles;
|
||||
|
||||
util::TileCoverParameters tileCoverParameters = {parameters.transformState,
|
||||
parameters.tileLodMinRadius,
|
||||
parameters.tileLodScale,
|
||||
parameters.tileLodPitchThreshold};
|
||||
util::TileCoverParameters tileCoverParameters = {.transformState = parameters.transformState,
|
||||
.tileLodMinRadius = parameters.tileLodMinRadius,
|
||||
.tileLodScale = parameters.tileLodScale,
|
||||
.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);
|
||||
|
||||
// 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 {
|
||||
if (retain.emplace(tile.id).second) {
|
||||
tile.setUpdateParameters({minimumUpdateInterval, isVolatile});
|
||||
tile.setUpdateParameters({.minimumUpdateInterval = minimumUpdateInterval, .isVolatile = isVolatile});
|
||||
tile.setNecessity(necessity);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace mbgl {
|
||||
|
||||
using namespace shaders;
|
||||
|
||||
// NOLINTNEXTLINE(modernize-use-ranges)
|
||||
MBGL_DEFINE_ENUM(BuiltIn,
|
||||
{{BuiltIn::None, "None"},
|
||||
{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]->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();
|
||||
if (res.error) {
|
||||
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(
|
||||
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();
|
||||
if (res.error) {
|
||||
observer->onSpriteError(sprite, std::make_exception_ptr(std::runtime_error(res.error->message)));
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -31,7 +32,8 @@ std::unique_ptr<style::Image> createStyleImage(const std::string& id,
|
||||
const std::optional<style::TextFit>& textFitHeight) {
|
||||
// Disallow invalid parameter configurations.
|
||||
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) ||
|
||||
srcY + height > static_cast<int32_t>(image.size.height)) {
|
||||
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() &&
|
||||
content[rapidjson::SizeType(1)].IsNumber() && content[rapidjson::SizeType(2)].IsNumber() &&
|
||||
content[rapidjson::SizeType(3)].IsNumber()) {
|
||||
return style::ImageContent{content[rapidjson::SizeType(0)].GetFloat(),
|
||||
content[rapidjson::SizeType(1)].GetFloat(),
|
||||
content[rapidjson::SizeType(2)].GetFloat(),
|
||||
content[rapidjson::SizeType(3)].GetFloat()};
|
||||
return style::ImageContent{.left = content[rapidjson::SizeType(0)].GetFloat(),
|
||||
.top = content[rapidjson::SizeType(1)].GetFloat(),
|
||||
.right = content[rapidjson::SizeType(2)].GetFloat(),
|
||||
.bottom = content[rapidjson::SizeType(3)].GetFloat()};
|
||||
} else {
|
||||
Log::Warning(Event::Sprite,
|
||||
"Invalid sprite image '" + std::string(name) + "': value of '" + property +
|
||||
|
||||
@@ -37,7 +37,7 @@ FileSourceManager::~FileSourceManager() = default;
|
||||
std::shared_ptr<FileSource> FileSourceManager::getFileSource(FileSourceType type,
|
||||
const ResourceOptions& resourceOptions,
|
||||
const ClientOptions& clientOptions) noexcept {
|
||||
std::lock_guard<std::recursive_mutex> lock(impl->mutex);
|
||||
std::scoped_lock lock(impl->mutex);
|
||||
|
||||
// Remove released file sources.
|
||||
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 {
|
||||
assert(factory);
|
||||
std::lock_guard<std::recursive_mutex> lock(impl->mutex);
|
||||
std::scoped_lock lock(impl->mutex);
|
||||
impl->fileSourceFactories[type] = std::move(factory);
|
||||
}
|
||||
|
||||
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);
|
||||
FileSourceFactory factory;
|
||||
if (it != impl->fileSourceFactories.end()) {
|
||||
|
||||
@@ -31,12 +31,12 @@ void NetworkStatus::Set(Status status) {
|
||||
}
|
||||
|
||||
void NetworkStatus::Subscribe(util::AsyncTask *async) {
|
||||
std::lock_guard<std::mutex> lock(NetworkStatus::mtx);
|
||||
std::scoped_lock lock(NetworkStatus::mtx);
|
||||
observers.insert(async);
|
||||
}
|
||||
|
||||
void NetworkStatus::Unsubscribe(util::AsyncTask *async) {
|
||||
std::lock_guard<std::mutex> lock(NetworkStatus::mtx);
|
||||
std::scoped_lock lock(NetworkStatus::mtx);
|
||||
observers.erase(async);
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ void NetworkStatus::Reachable() {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(NetworkStatus::mtx);
|
||||
for (auto async : observers) {
|
||||
std::scoped_lock lock(NetworkStatus::mtx);
|
||||
for (auto async : observers) { // NOLINT(bugprone-nondeterministic-pointer-iteration-order)
|
||||
async->send();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,11 @@ Resource Resource::tile(const std::string& urlTemplate,
|
||||
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};
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <mbgl/style/expression/step.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#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) {
|
||||
double min = std::numeric_limits<double>::max();
|
||||
for (auto& s : stops) {
|
||||
if (s.first < min) {
|
||||
min = s.first;
|
||||
}
|
||||
min = std::min(s.first, min);
|
||||
}
|
||||
stops.emplace(-std::numeric_limits<double>::infinity(), std::move(stops[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) {
|
||||
std::lock_guard<std::mutex> guard(dataMutex);
|
||||
std::scoped_lock guard(dataMutex);
|
||||
auto cachedTileData = dataCache.find(tileID.canonical);
|
||||
if (cachedTileData != dataCache.end()) {
|
||||
tileRef.invoke(&CustomGeometryTile::setTileData, *(cachedTileData->second));
|
||||
@@ -35,14 +35,14 @@ void CustomTileLoader::fetchTile(const OverscaledTileID& tileID, const ActorRef<
|
||||
}
|
||||
|
||||
void CustomTileLoader::cancelTile(const OverscaledTileID& tileID) {
|
||||
std::lock_guard<std::mutex> guard(dataMutex);
|
||||
if (tileCallbackMap.find(tileID.canonical) != tileCallbackMap.end()) {
|
||||
std::scoped_lock guard(dataMutex);
|
||||
if (tileCallbackMap.contains(tileID.canonical)) {
|
||||
invokeTileCancel(tileID.canonical);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomTileLoader::removeTile(const OverscaledTileID& tileID) {
|
||||
std::lock_guard<std::mutex> guard(dataMutex);
|
||||
std::scoped_lock guard(dataMutex);
|
||||
auto tileCallbacks = tileCallbackMap.find(tileID.canonical);
|
||||
if (tileCallbacks == tileCallbackMap.end()) return;
|
||||
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) {
|
||||
std::lock_guard<std::mutex> guard(dataMutex);
|
||||
std::scoped_lock guard(dataMutex);
|
||||
auto iter = tileCallbackMap.find(tileID);
|
||||
if (iter == tileCallbackMap.end()) return;
|
||||
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) {
|
||||
std::lock_guard<std::mutex> guard(dataMutex);
|
||||
std::scoped_lock guard(dataMutex);
|
||||
auto tileCallbacks = tileCallbackMap.find(tileID);
|
||||
if (tileCallbacks == tileCallbackMap.end()) {
|
||||
return;
|
||||
@@ -86,7 +86,7 @@ void CustomTileLoader::invalidateTile(const CanonicalTileID& tileID) {
|
||||
}
|
||||
|
||||
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;
|
||||
for (auto& idtuple : tileCallbackMap) {
|
||||
auto zoom = idtuple.first.z;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
@@ -51,9 +53,8 @@ EvaluationResult toColor(const Value& colorValue) {
|
||||
},
|
||||
[&colorValue](const std::vector<Value>& components) -> EvaluationResult {
|
||||
const std::size_t len = components.size();
|
||||
bool isNumeric = std::all_of(components.begin(), components.end(), [](const Value& item) -> bool {
|
||||
return item.template is<double>();
|
||||
});
|
||||
bool isNumeric = std::ranges::all_of(components,
|
||||
[](const Value& item) -> bool { return item.template is<double>(); });
|
||||
if ((len == 3 || len == 4) && isNumeric) {
|
||||
Result<Color> c = {rgba(components[0].template get<double>(),
|
||||
components[1].template get<double>(),
|
||||
|
||||
@@ -70,11 +70,14 @@ ZoomCurveOrError findZoomCurve(const expression::Expression& e) {
|
||||
result = childResult;
|
||||
} else if (!result && childResult) {
|
||||
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) {
|
||||
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;
|
||||
|
||||
namespace {
|
||||
const LayerTypeInfo typeInfoCustomDrawable{"custom-drawable",
|
||||
LayerTypeInfo::Source::NotRequired,
|
||||
LayerTypeInfo::Pass3D::NotRequired,
|
||||
LayerTypeInfo::Layout::NotRequired,
|
||||
LayerTypeInfo::FadingTiles::NotRequired,
|
||||
LayerTypeInfo::CrossTileIndex::NotRequired,
|
||||
LayerTypeInfo::TileKind::NotRequired};
|
||||
const LayerTypeInfo typeInfoCustomDrawable{.type = "custom-drawable",
|
||||
.source = LayerTypeInfo::Source::NotRequired,
|
||||
.pass3d = LayerTypeInfo::Pass3D::NotRequired,
|
||||
.layout = LayerTypeInfo::Layout::NotRequired,
|
||||
.fadingTiles = LayerTypeInfo::FadingTiles::NotRequired,
|
||||
.crossTileIndex = LayerTypeInfo::CrossTileIndex::NotRequired,
|
||||
.tileKind = LayerTypeInfo::TileKind::NotRequired};
|
||||
} // namespace
|
||||
|
||||
CustomDrawableLayer::CustomDrawableLayer(const std::string& layerID, std::unique_ptr<CustomDrawableLayerHost> host)
|
||||
@@ -120,28 +120,28 @@ public:
|
||||
const auto matrix = LayerTweaker::getTileMatrix(
|
||||
tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false);
|
||||
|
||||
const shaders::LineEvaluatedPropsUBO propsUBO = {options.color,
|
||||
options.blur,
|
||||
options.opacity,
|
||||
options.gapWidth,
|
||||
options.offset,
|
||||
options.width,
|
||||
/*floorwidth=*/0.0f,
|
||||
LineExpressionMask::None,
|
||||
0};
|
||||
const shaders::LineEvaluatedPropsUBO propsUBO = {.color = options.color,
|
||||
.blur = options.blur,
|
||||
.opacity = options.opacity,
|
||||
.gapwidth = options.gapWidth,
|
||||
.offset = options.offset,
|
||||
.width = options.width,
|
||||
/*floorwidth=*/.floorwidth = 0.0f,
|
||||
.expressionMask = LineExpressionMask::None,
|
||||
.pad1 = 0};
|
||||
|
||||
// We would need to set up `idLineExpressionUBO` if the expression mask isn't empty
|
||||
assert(propsUBO.expressionMask == LineExpressionMask::None);
|
||||
|
||||
if (!expressionUniformBuffer) {
|
||||
const LineExpressionUBO exprUBO = {
|
||||
/* .color = */ nullptr,
|
||||
/* .blur = */ nullptr,
|
||||
/* .opacity = */ nullptr,
|
||||
/* .gapwidth = */ nullptr,
|
||||
/* .offset = */ nullptr,
|
||||
/* .width = */ nullptr,
|
||||
/* .floorWidth = */ nullptr,
|
||||
/* .color = */ .color = nullptr,
|
||||
/* .blur = */ .blur = nullptr,
|
||||
/* .opacity = */ .opacity = nullptr,
|
||||
/* .gapwidth = */ .gapwidth = nullptr,
|
||||
/* .offset = */ .offset = nullptr,
|
||||
/* .width = */ .width = nullptr,
|
||||
/* .floorWidth = */ .floorWidth = nullptr,
|
||||
};
|
||||
|
||||
expressionUniformBuffer = parameters.context.createUniformBuffer(&exprUBO, sizeof(exprUBO));
|
||||
@@ -159,16 +159,16 @@ public:
|
||||
#else
|
||||
const shaders::LineDrawableUBO drawableUBO = {
|
||||
#endif
|
||||
/* .matrix = */ util::cast<float>(matrix),
|
||||
/* .ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, zoom),
|
||||
/* .matrix = */ .matrix = util::cast<float>(matrix),
|
||||
/* .ratio = */ .ratio = 1.0f / tileID.pixelsToTileUnits(1.0f, zoom),
|
||||
|
||||
/* .color_t = */ 0.f,
|
||||
/* .blur_t = */ 0.f,
|
||||
/* .opacity_t = */ 0.f,
|
||||
/* .gapwidth_t = */ 0.f,
|
||||
/* .offset_t = */ 0.f,
|
||||
/* .width_t = */ 0.f,
|
||||
/* .pad1 = */ 0
|
||||
/* .color_t = */ .color_t = 0.f,
|
||||
/* .blur_t = */ .blur_t = 0.f,
|
||||
/* .opacity_t = */ .opacity_t = 0.f,
|
||||
/* .gapwidth_t = */ .gapwidth_t = 0.f,
|
||||
/* .offset_t = */ .offset_t = 0.f,
|
||||
/* .width_t = */ .width_t = 0.f,
|
||||
/* .pad1 = */ .pad1 = 0
|
||||
};
|
||||
|
||||
#if MLN_UBO_CONSOLIDATION
|
||||
@@ -240,30 +240,30 @@ public:
|
||||
|
||||
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
|
||||
shaders::WideVectorUniformsUBO uniform = {
|
||||
/* .mvpMatrix = */ mvpMatrix,
|
||||
/* .mvpMatrixDiff = */ mvpMatrixDiff,
|
||||
/* .mvMatrix = */ mvMatrix,
|
||||
/* .mvMatrixDiff = */ mvMatrixDiff,
|
||||
/* .pMatrix = */ pMatrix,
|
||||
/* .pMatrixDiff = */ pMatrixDiff,
|
||||
/* .frameSize = */ {(float)renderableSize.width, (float)renderableSize.height},
|
||||
/* .pad1 = */ 0,
|
||||
/* .pad2 = */ 0};
|
||||
/* .mvpMatrix = */ .mvpMatrix = mvpMatrix,
|
||||
/* .mvpMatrixDiff = */ .mvpMatrixDiff = mvpMatrixDiff,
|
||||
/* .mvMatrix = */ .mvMatrix = mvMatrix,
|
||||
/* .mvMatrixDiff = */ .mvMatrixDiff = mvMatrixDiff,
|
||||
/* .pMatrix = */ .pMatrix = pMatrix,
|
||||
/* .pMatrixDiff = */ .pMatrixDiff = pMatrixDiff,
|
||||
/* .frameSize = */ .frameSize = {(float)renderableSize.width, (float)renderableSize.height},
|
||||
/* .pad1 = */ .pad1 = 0,
|
||||
/* .pad2 = */ .pad2 = 0};
|
||||
|
||||
shaders::WideVectorUniformWideVecUBO wideVec = {
|
||||
/* .color = */ options.color,
|
||||
/* .w2 = */ options.width,
|
||||
/* .offset = */ options.offset,
|
||||
/* .edge = */ 0.0f, // TODO: MLN does not provide a value. Analyze impact.
|
||||
/* .texRepeat = */ 0.0f, // N/A
|
||||
/* .texOffset = */ {}, // N/A
|
||||
/* .miterLimit = */ options.geometry.miterLimit,
|
||||
/* .join = */ static_cast<int32_t>(options.geometry.joinType),
|
||||
/* .cap = */ static_cast<int32_t>(options.geometry.beginCap), // TODO: MLN option for endCap to be
|
||||
// implemented in the shader!
|
||||
/* .hasExp = */ false, // N/A
|
||||
/* .interClipLimit = */ 0.0f, // N/A
|
||||
/* .pad1 = */ 0};
|
||||
/* .color = */ .color = options.color,
|
||||
/* .w2 = */ .w2 = options.width,
|
||||
/* .offset = */ .offset = options.offset,
|
||||
/* .edge = */ .edge = 0.0f, // TODO: MLN does not provide a value. Analyze impact.
|
||||
/* .texRepeat = */ .texRepeat = 0.0f, // N/A
|
||||
/* .texOffset = */ .texOffset = {}, // N/A
|
||||
/* .miterLimit = */ .miterLimit = options.geometry.miterLimit,
|
||||
/* .join = */ .join = static_cast<int32_t>(options.geometry.joinType),
|
||||
/* .cap = */ .cap = static_cast<int32_t>(options.geometry.beginCap), // TODO: MLN option for endCap to be
|
||||
// implemented in the shader!
|
||||
/* .hasExp = */ .hasExp = false, // N/A
|
||||
/* .interClipLimit = */ .interClipLimit = 0.0f, // N/A
|
||||
/* .pad1 = */ .pad1 = 0};
|
||||
|
||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||
drawableUniforms.createOrUpdate(idWideVectorUniformsUBO, &uniform, parameters.context);
|
||||
@@ -305,12 +305,12 @@ public:
|
||||
const auto matrix = LayerTweaker::getTileMatrix(
|
||||
tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false);
|
||||
|
||||
const shaders::FillEvaluatedPropsUBO propsUBO = {/* .color = */ options.color,
|
||||
/* .outline_color = */ Color::white(),
|
||||
/* .opacity = */ options.opacity,
|
||||
/* .fade = */ 0.f,
|
||||
/* .from_scale = */ 0.f,
|
||||
/* .to_scale = */ 0.f};
|
||||
const shaders::FillEvaluatedPropsUBO propsUBO = {/* .color = */ .color = options.color,
|
||||
/* .outline_color = */ .outline_color = Color::white(),
|
||||
/* .opacity = */ .opacity = options.opacity,
|
||||
/* .fade = */ .fade = 0.f,
|
||||
/* .from_scale = */ .from_scale = 0.f,
|
||||
/* .to_scale = */ .to_scale = 0.f};
|
||||
|
||||
#if MLN_UBO_CONSOLIDATION
|
||||
FillDrawableUnionUBO drawableUBO;
|
||||
@@ -318,12 +318,12 @@ public:
|
||||
#else
|
||||
const shaders::FillDrawableUBO drawableUBO = {
|
||||
#endif
|
||||
/* .matrix = */ util::cast<float>(matrix),
|
||||
/* .matrix = */ .matrix = util::cast<float>(matrix),
|
||||
|
||||
/* .color_t = */ 0.f,
|
||||
/* .opacity_t = */ 0.f,
|
||||
/* .pad1 = */ 0,
|
||||
/* .pad2 = */ 0
|
||||
/* .color_t = */ .color_t = 0.f,
|
||||
/* .opacity_t = */ .opacity_t = 0.f,
|
||||
/* .pad1 = */ .pad1 = 0,
|
||||
/* .pad2 = */ .pad2 = 0
|
||||
};
|
||||
|
||||
#if MLN_UBO_CONSOLIDATION
|
||||
@@ -390,17 +390,19 @@ public:
|
||||
parameters.pixelsToGLUnits[1] * factor};
|
||||
|
||||
const shaders::CustomSymbolIconDrawableUBO drawableUBO = {
|
||||
/* .matrix = */ util::cast<float>(matrix),
|
||||
/* .extrude_scale = */ {extrudeScale[0] * options.size.width, extrudeScale[1] * options.size.height},
|
||||
/* .anchor = */ options.anchor,
|
||||
/* .angle_degrees = */ options.angleDegrees,
|
||||
/* .scale_with_map = */ options.scaleWithMap,
|
||||
/* .pitch_with_map = */ options.pitchWithMap,
|
||||
/* .camera_to_center_distance = */ parameters.state.getCameraToCenterDistance(),
|
||||
/* .aspect_ratio = */ parameters.pixelsToGLUnits[0] / parameters.pixelsToGLUnits[1],
|
||||
/* .pad1 = */ 0,
|
||||
/* .pad2 = */ 0,
|
||||
/* .pad3 = */ 0};
|
||||
/* .matrix = */ .matrix = util::cast<float>(matrix),
|
||||
/* .extrude_scale = */ .extrude_scale = {extrudeScale[0] * options.size.width,
|
||||
extrudeScale[1] * options.size.height},
|
||||
/* .anchor = */ .anchor = options.anchor,
|
||||
/* .angle_degrees = */ .angle_degrees = options.angleDegrees,
|
||||
/* .scale_with_map = */ .scale_with_map = options.scaleWithMap,
|
||||
/* .pitch_with_map = */ .pitch_with_map = options.pitchWithMap,
|
||||
/* .camera_to_center_distance = */ .camera_to_center_distance =
|
||||
parameters.state.getCameraToCenterDistance(),
|
||||
/* .aspect_ratio = */ .aspect_ratio = parameters.pixelsToGLUnits[0] / parameters.pixelsToGLUnits[1],
|
||||
/* .pad1 = */ .pad1 = 0,
|
||||
/* .pad2 = */ .pad2 = 0,
|
||||
/* .pad3 = */ .pad3 = 0};
|
||||
|
||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||
drawableUniforms.createOrUpdate(idCustomSymbolDrawableUBO, &drawableUBO, parameters.context);
|
||||
@@ -430,8 +432,8 @@ public:
|
||||
callback(drawable, parameters, options);
|
||||
}
|
||||
|
||||
CustomGeometryDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(options.matrix),
|
||||
/* .color = */ options.color};
|
||||
CustomGeometryDrawableUBO drawableUBO = {/* .matrix = */ .matrix = util::cast<float>(options.matrix),
|
||||
/* .color = */ .color = options.color};
|
||||
|
||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||
drawableUniforms.createOrUpdate(idCustomGeometryDrawableUBO, &drawableUBO, parameters.context);
|
||||
@@ -644,8 +646,8 @@ util::SimpleIdentity CustomDrawableLayerHost::Interface::addSymbol(
|
||||
for (int y = 0; y <= 1; ++y) {
|
||||
for (int x = 0; x <= 1; ++x) {
|
||||
vertices.emplace_back(
|
||||
CustomSymbolIcon{{static_cast<float>(point.x * 2 + x), static_cast<float>(point.y * 2 + y)},
|
||||
{textureCoordinates[x][0], textureCoordinates[y][1]}});
|
||||
CustomSymbolIcon{.a_pos = {static_cast<float>(point.x * 2 + x), static_cast<float>(point.y * 2 + y)},
|
||||
.a_tex = {textureCoordinates[x][0], textureCoordinates[y][1]}});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@ namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
namespace {
|
||||
const LayerTypeInfo typeInfoCustom{"custom",
|
||||
LayerTypeInfo::Source::NotRequired,
|
||||
LayerTypeInfo::Pass3D::NotRequired,
|
||||
LayerTypeInfo::Layout::NotRequired,
|
||||
LayerTypeInfo::FadingTiles::NotRequired,
|
||||
LayerTypeInfo::CrossTileIndex::NotRequired,
|
||||
LayerTypeInfo::TileKind::NotRequired};
|
||||
const LayerTypeInfo typeInfoCustom{.type = "custom",
|
||||
.source = LayerTypeInfo::Source::NotRequired,
|
||||
.pass3d = LayerTypeInfo::Pass3D::NotRequired,
|
||||
.layout = LayerTypeInfo::Layout::NotRequired,
|
||||
.fadingTiles = LayerTypeInfo::FadingTiles::NotRequired,
|
||||
.crossTileIndex = LayerTypeInfo::CrossTileIndex::NotRequired,
|
||||
.tileKind = LayerTypeInfo::TileKind::NotRequired};
|
||||
} // namespace
|
||||
|
||||
CustomLayer::CustomLayer(const std::string& layerID, std::unique_ptr<CustomLayerHost> host)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <mbgl/text/glyph.hpp>
|
||||
#include <mbgl/util/i18n.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
GlyphRange::GlyphRange(uint32_t first_, uint32_t second_, GlyphIDType type_)
|
||||
@@ -57,8 +59,8 @@ GlyphIDType genNewGlyphIDType(const std::string &url,
|
||||
GlyphRange getGlyphRange(GlyphID glyph) {
|
||||
unsigned start = (glyph.complex.code / 256) * 256;
|
||||
unsigned end = (start + 255);
|
||||
if (start > 65280) start = 65280;
|
||||
if (end > 65535) end = 65535;
|
||||
start = std::min<unsigned int>(start, 65280);
|
||||
end = std::min<unsigned int>(end, 65535);
|
||||
return {start, end, glyph.complex.type};
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ GlyphManager::~GlyphManager() {
|
||||
void GlyphManager::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphDependencies, FileSource& fileSource) {
|
||||
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
|
||||
// does need to be fetched, record an entry mapping the requestor to a
|
||||
// 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];
|
||||
GlyphRequest& request = entry.ranges[range];
|
||||
@@ -191,7 +191,7 @@ void GlyphManager::notify(GlyphRequestor& requestor, const GlyphDependencies& gl
|
||||
}
|
||||
|
||||
void GlyphManager::removeRequestor(GlyphRequestor& requestor) {
|
||||
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
|
||||
std::scoped_lock readWriteLock(rwLock);
|
||||
for (auto& entry : entries) {
|
||||
for (auto& range : entry.second.ranges) {
|
||||
range.second.requestors.erase(&requestor);
|
||||
@@ -200,7 +200,7 @@ void GlyphManager::removeRequestor(GlyphRequestor& requestor) {
|
||||
}
|
||||
|
||||
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; });
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ const CollisionGroups::CollisionGroup& CollisionGroups::get(const std::string& s
|
||||
// but the current interface defines one source == one group when
|
||||
// crossSourceCollisions == true.
|
||||
if (!crossSourceCollisions) {
|
||||
if (collisionGroups.find(sourceID) == collisionGroups.end()) {
|
||||
if (!collisionGroups.contains(sourceID)) {
|
||||
uint16_t nextGroupID = ++maxGroupID;
|
||||
collisionGroups.emplace(
|
||||
sourceID,
|
||||
@@ -474,9 +474,13 @@ JointPlacement Placement::placeSymbol(const SymbolInstance& symbolInstance, cons
|
||||
}
|
||||
}
|
||||
|
||||
variableOffsets.insert(std::make_pair(
|
||||
symbolInstance.getCrossTileID(),
|
||||
VariableOffset{variableTextOffset, width, height, anchor, textBoxScale, prevAnchor}));
|
||||
variableOffsets.insert(std::make_pair(symbolInstance.getCrossTileID(),
|
||||
VariableOffset{.offset = variableTextOffset,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.anchor = anchor,
|
||||
.textBoxScale = textBoxScale,
|
||||
.prevAnchor = prevAnchor}));
|
||||
|
||||
if (bucket.allowVerticalPlacement) {
|
||||
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
|
||||
// current placement but haven't finished fading
|
||||
for (auto& prevOpacity : getPrevPlacement()->opacities) {
|
||||
if (opacities.find(prevOpacity.first) == opacities.end()) {
|
||||
if (!opacities.contains(prevOpacity.first)) {
|
||||
JointOpacityState jointOpacity(prevOpacity.second, increment, false, false);
|
||||
if (!jointOpacity.isHidden()) {
|
||||
opacities.emplace(prevOpacity.first, jointOpacity);
|
||||
@@ -1655,14 +1659,14 @@ void TilePlacement::newSymbolPlaced(const SymbolInstance& symbol,
|
||||
assert(box.isBox());
|
||||
iconCollisionBox = box.box();
|
||||
}
|
||||
PlacedSymbolData symbolData{symbol.getKey(),
|
||||
textCollisionBox,
|
||||
iconCollisionBox,
|
||||
placement.text,
|
||||
placement.icon,
|
||||
!placement.skipFade && populateIntersections,
|
||||
collisionIndex.getViewportPadding(),
|
||||
ctx.getBucket().bucketLeaderID};
|
||||
PlacedSymbolData symbolData{.key = symbol.getKey(),
|
||||
.textCollisionBox = textCollisionBox,
|
||||
.iconCollisionBox = iconCollisionBox,
|
||||
.textPlaced = placement.text,
|
||||
.iconPlaced = placement.icon,
|
||||
.intersectsTileBorder = !placement.skipFade && populateIntersections,
|
||||
.viewportPadding = collisionIndex.getViewportPadding(),
|
||||
.layer = ctx.getBucket().bucketLeaderID};
|
||||
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 c2 = zone.second;
|
||||
const auto lastStretch = cuts.back().stretch;
|
||||
cuts.emplace_back(Cut{c1 - lastStretch, lastStretch});
|
||||
cuts.emplace_back(Cut{c1 - lastStretch, lastStretch + (c2 - c1)});
|
||||
cuts.emplace_back(Cut{.fixed = c1 - lastStretch, .stretch = lastStretch});
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -184,7 +184,10 @@ SymbolQuads getIconQuads(const PositionedIcon& shapedIcon,
|
||||
};
|
||||
|
||||
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 {
|
||||
const auto xCuts = stretchZonesToCuts(stretchX, fixedWidth, stretchWidth);
|
||||
const auto yCuts = stretchZonesToCuts(stretchY, fixedHeight, stretchHeight);
|
||||
|
||||
@@ -400,9 +400,9 @@ void GeometryTile::onGlyphsAvailable(GlyphMap glyphMap, [[maybe_unused]] HBShape
|
||||
|
||||
auto fontStackHash = FontStackHasher()(fontStack);
|
||||
bool needShape = true;
|
||||
if (glyphMap.find(fontStackHash) != glyphMap.end()) {
|
||||
if (glyphMap.contains(fontStackHash)) {
|
||||
auto& glyphs = glyphMap[fontStackHash];
|
||||
if (glyphs.find(glyphID) != glyphs.end()) needShape = false;
|
||||
if (glyphs.contains(glyphID)) needShape = false;
|
||||
}
|
||||
if (needShape) {
|
||||
auto glyph = glyphManager->getGlyph(fontStack, glyphID);
|
||||
|
||||
@@ -376,7 +376,7 @@ void GeometryTileWorker::requestNewGlyphs(const GlyphDependencies& glyphDependen
|
||||
for (auto& fontDependencies : glyphDependencies.glyphs) {
|
||||
auto fontGlyphs = glyphMap.find(FontStackHasher()(fontDependencies.first));
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -449,7 +449,8 @@ void GeometryTileWorker::parse() {
|
||||
}
|
||||
|
||||
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);
|
||||
if (!geometryLayer) {
|
||||
@@ -471,10 +472,13 @@ void GeometryTileWorker::parse() {
|
||||
// images/glyphs are used, or the Layout is stored until the
|
||||
// images/glyphs are available to add the features to the buckets.
|
||||
if (leaderImpl.getTypeInfo()->layout == LayerTypeInfo::Layout::Required) {
|
||||
std::unique_ptr<Layout> layout = LayerManager::get()->createLayout(
|
||||
{parameters, fontFaces, glyphDependencies, imageDependencies, availableImages},
|
||||
std::move(geometryLayer),
|
||||
group);
|
||||
std::unique_ptr<Layout> layout = LayerManager::get()->createLayout({.bucketParameters = parameters,
|
||||
.fontFaces = fontFaces,
|
||||
.glyphDependencies = glyphDependencies,
|
||||
.imageDependencies = imageDependencies,
|
||||
.availableImages = availableImages},
|
||||
std::move(geometryLayer),
|
||||
group);
|
||||
if (layout->hasDependencies()) {
|
||||
layouts.push_back(std::move(layout));
|
||||
} else {
|
||||
@@ -502,7 +506,7 @@ void GeometryTileWorker::parse() {
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
std::lock_guard counterLock{deferredSignalLock};
|
||||
std::scoped_lock counterLock{deferredSignalLock};
|
||||
deferredDeletionsPending++;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ void TileCache::deferPendingReleases() {
|
||||
MLN_ZONE_VALUE(tile_.items.size());
|
||||
tile_.items.clear();
|
||||
|
||||
std::lock_guard<std::mutex> counterLock(deferredSignalLock);
|
||||
std::scoped_lock counterLock(deferredSignalLock);
|
||||
deferredDeletionsPending--;
|
||||
deferredSignal.notify_all();
|
||||
}};
|
||||
|
||||
@@ -51,7 +51,7 @@ private:
|
||||
Resource resource;
|
||||
std::shared_ptr<FileSource> fileSource;
|
||||
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
|
||||
/// object at the same time as the loader's destructor. This construct is shared
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/writer.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <regex>
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -175,7 +177,7 @@ std::vector<std::string> ActionJournal::Impl::getLogFiles() const {
|
||||
}
|
||||
|
||||
std::vector<std::string> ActionJournal::Impl::getLog() {
|
||||
std::lock_guard lock(fileMutex);
|
||||
std::scoped_lock lock(fileMutex);
|
||||
std::vector<std::string> logEvents;
|
||||
|
||||
const auto readFile = [&](std::fstream& file) {
|
||||
@@ -215,7 +217,7 @@ std::vector<std::string> ActionJournal::Impl::getLog() {
|
||||
}
|
||||
|
||||
void ActionJournal::Impl::clearLog() {
|
||||
std::lock_guard lock(fileMutex);
|
||||
std::scoped_lock lock(fileMutex);
|
||||
|
||||
// close current file
|
||||
currentFile.close();
|
||||
@@ -277,21 +279,13 @@ void ActionJournal::Impl::onDidFinishRenderingFrame(const RenderFrameStatus& fra
|
||||
previousFrameTime = currentFrameTime;
|
||||
|
||||
// update rendering stats
|
||||
if (renderingStats.encodingMin > frame.renderingStats.encodingTime) {
|
||||
renderingStats.encodingMin = frame.renderingStats.encodingTime;
|
||||
}
|
||||
renderingStats.encodingMin = std::min(renderingStats.encodingMin, frame.renderingStats.encodingTime);
|
||||
|
||||
if (renderingStats.encodingMax < frame.renderingStats.encodingTime) {
|
||||
renderingStats.encodingMax = frame.renderingStats.encodingTime;
|
||||
}
|
||||
renderingStats.encodingMax = std::max(renderingStats.encodingMax, frame.renderingStats.encodingTime);
|
||||
|
||||
if (renderingStats.renderingMin > frame.renderingStats.renderingTime) {
|
||||
renderingStats.renderingMin = frame.renderingStats.renderingTime;
|
||||
}
|
||||
renderingStats.renderingMin = std::min(renderingStats.renderingMin, frame.renderingStats.renderingTime);
|
||||
|
||||
if (renderingStats.renderingMax < frame.renderingStats.renderingTime) {
|
||||
renderingStats.renderingMax = frame.renderingStats.renderingTime;
|
||||
}
|
||||
renderingStats.renderingMax = std::max(renderingStats.renderingMax, frame.renderingStats.renderingTime);
|
||||
|
||||
renderingStats.encodingTotal += frame.renderingStats.encodingTime;
|
||||
renderingStats.renderingTotal += frame.renderingStats.renderingTime;
|
||||
@@ -617,7 +611,7 @@ void ActionJournal::Impl::logToFile(const std::string& value) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard lock(fileMutex);
|
||||
std::scoped_lock lock(fileMutex);
|
||||
|
||||
if (!prepareFile(value.size() + 1)) {
|
||||
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 axis1 = {{frustumEdges[i][2], 0.0, -frustumEdges[i][0]}};
|
||||
|
||||
projections[i * 2] = {axis0, ProjectPointsToAxis(points, points[0], axis0)};
|
||||
projections[i * 2 + 1] = {axis1, ProjectPointsToAxis(points, points[0], axis1)};
|
||||
projections[i * 2] = {.axis = axis0, .projection = ProjectPointsToAxis(points, points[0], axis0)};
|
||||
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) {
|
||||
std::for_each(frustumPlanePointIndices.begin(), frustumPlanePointIndices.end(), [](vec3i& tri) {
|
||||
std::swap(tri[1], tri[2]);
|
||||
});
|
||||
std::ranges::for_each(frustumPlanePointIndices, [](vec3i& tri) { std::swap(tri[1], tri[2]); });
|
||||
}
|
||||
|
||||
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 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 {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <cstdarg>
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
#include <mutex>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -68,12 +69,12 @@ void Log::useLogThread(bool enable, std::optional<EventSeverity> severity) {
|
||||
}
|
||||
|
||||
void Log::setObserver(std::unique_ptr<Observer> observer) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
currentObserver = std::move(observer);
|
||||
}
|
||||
|
||||
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::swap(observer, currentObserver);
|
||||
return observer;
|
||||
@@ -92,7 +93,7 @@ void Log::record(EventSeverity severity,
|
||||
int64_t code,
|
||||
const std::string& msg,
|
||||
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)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ bool isCanonicalURL(const TileServerOptions& tileServerOptions, const std::strin
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@@ -13,7 +13,7 @@ ThreadedSchedulerBase::~ThreadedSchedulerBase() = default;
|
||||
|
||||
void ThreadedSchedulerBase::terminate() {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(workerMutex);
|
||||
std::scoped_lock lock(workerMutex);
|
||||
terminated = true;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ std::thread ThreadedSchedulerBase::makeSchedulerThread(size_t index) {
|
||||
std::vector<std::shared_ptr<Queue>> pending;
|
||||
{
|
||||
// 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) {
|
||||
pending.push_back(queue);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ std::thread ThreadedSchedulerBase::makeSchedulerThread(size_t index) {
|
||||
for (auto& q : pending) {
|
||||
std::function<void()> tasklet;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(q->lock);
|
||||
std::scoped_lock lock(q->lock);
|
||||
if (q->queue.size()) {
|
||||
q->runningCount++;
|
||||
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`
|
||||
|
||||
if (!--q->runningCount) {
|
||||
std::lock_guard<std::mutex> lock(q->lock);
|
||||
std::scoped_lock lock(q->lock);
|
||||
if (q->queue.empty()) {
|
||||
q->cv.notify_all();
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
std::lock_guard<std::mutex> lock(q->lock);
|
||||
std::scoped_lock lock(q->lock);
|
||||
if (handler) {
|
||||
handler(std::current_exception());
|
||||
}
|
||||
@@ -117,7 +117,7 @@ void ThreadedSchedulerBase::schedule(const util::SimpleIdentity tag, std::functi
|
||||
std::shared_ptr<Queue> q;
|
||||
{
|
||||
MLN_TRACE_ZONE(queue);
|
||||
std::lock_guard<std::mutex> lock(taggedQueueLock);
|
||||
std::scoped_lock lock(taggedQueueLock);
|
||||
|
||||
// find or insert
|
||||
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);
|
||||
std::lock_guard<std::mutex> lock(q->lock);
|
||||
std::scoped_lock lock(q->lock);
|
||||
q->queue.push(std::move(fn));
|
||||
taskCount++;
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ void ThreadedSchedulerBase::waitForEmpty(const util::SimpleIdentity tag) {
|
||||
|
||||
std::shared_ptr<Queue> q;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(taggedQueueLock);
|
||||
std::scoped_lock lock(taggedQueueLock);
|
||||
auto it = taggedQueue.find(tagToFind);
|
||||
if (it == taggedQueue.end()) {
|
||||
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.
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(taggedQueueLock);
|
||||
std::scoped_lock lock(taggedQueueLock);
|
||||
taggedQueue.erase(tagToFind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
void runOnRenderThread(const util::SimpleIdentity tag, std::function<void()>&& fn) override {
|
||||
std::shared_ptr<RenderQueue> queue;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(taggedRenderQueueLock);
|
||||
std::scoped_lock lock(taggedRenderQueueLock);
|
||||
auto it = taggedRenderQueue.find(tag);
|
||||
if (it != taggedRenderQueue.end()) {
|
||||
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));
|
||||
}
|
||||
|
||||
void runRenderJobs(const util::SimpleIdentity tag, bool closeQueue = false) override {
|
||||
MLN_TRACE_FUNC();
|
||||
std::shared_ptr<RenderQueue> queue;
|
||||
std::unique_lock<std::mutex> lock(taggedRenderQueueLock);
|
||||
std::unique_lock lock(taggedRenderQueueLock);
|
||||
|
||||
{
|
||||
auto it = taggedRenderQueue.find(tag);
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> taskLock(queue->mutex);
|
||||
std::scoped_lock taskLock(queue->mutex);
|
||||
while (queue->queue.size()) {
|
||||
auto fn = std::move(queue->queue.front());
|
||||
queue->queue.pop();
|
||||
|
||||
@@ -115,7 +115,7 @@ std::vector<UnwrappedTileID> tileCover(const Point<double>& tl,
|
||||
for (x = x0; x < x1; ++x) {
|
||||
const auto dx = x + 0.5 - c.x;
|
||||
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 auto newRootTile = [&](int16_t wrap) -> Node {
|
||||
return {AABB({{wrap * numTiles, 0.0, 0.0}}, {{(wrap + 1) * numTiles, numTiles, 0.0}}),
|
||||
uint8_t(0),
|
||||
uint16_t(0),
|
||||
uint16_t(0),
|
||||
wrap,
|
||||
false};
|
||||
return {.aabb = AABB({{wrap * numTiles, 0.0, 0.0}}, {{(wrap + 1) * numTiles, numTiles, 0.0}}),
|
||||
.zoom = uint8_t(0),
|
||||
.x = uint16_t(0),
|
||||
.y = uint16_t(0),
|
||||
.wrap = wrap,
|
||||
.fullyVisible = false};
|
||||
};
|
||||
|
||||
// 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());
|
||||
|
||||
for (Bound& b : activeBounds) {
|
||||
TileSpan xp = {INT_MAX, 0, b.winding};
|
||||
TileSpan xp = {.xmin = INT_MAX, .xmax = 0, .winding = b.winding};
|
||||
double x;
|
||||
const auto numEdges = b.points.size() - 1;
|
||||
while (b.currentPoint < numEdges) {
|
||||
|
||||
@@ -18,6 +18,7 @@ Checks: >
|
||||
-modernize-use-constraints,
|
||||
-modernize-use-trailing-return-type,
|
||||
misc-static-assert,
|
||||
-clang-analyzer-security.ArrayBound,
|
||||
-clang-analyzer-security.insecureAPI.rand,
|
||||
-clang-analyzer-core.uninitialized.UndefReturn,
|
||||
-clang-analyzer-core.StackAddressEscape,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
#include <mbgl/algorithm/update_tile_masks.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
namespace {
|
||||
@@ -23,7 +25,7 @@ bool operator==(const FakeTile& lhs, const FakeTile& rhs) {
|
||||
|
||||
void validate(std::map<UnwrappedTileID, FakeTile> 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);
|
||||
EXPECT_EQ(expected, actual);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <algorithm>
|
||||
#include <mbgl/test/util.hpp>
|
||||
#include <mbgl/test/stub_file_source.hpp>
|
||||
#include <mbgl/test/map_adapter.hpp>
|
||||
@@ -12,6 +13,8 @@
|
||||
#include <mbgl/renderer/renderer.hpp>
|
||||
#include <mbgl/gfx/headless_frontend.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
namespace {
|
||||
@@ -416,8 +419,9 @@ TEST(Annotations, QueryFractionalZoomLevels) {
|
||||
auto sameID = [](const Feature& lhs, const Feature& rhs) {
|
||||
return lhs.id == rhs.id;
|
||||
};
|
||||
std::sort(features.begin(), features.end(), sortID);
|
||||
features.erase(std::unique(features.begin(), features.end(), sameID), features.end());
|
||||
std::ranges::sort(features, sortID);
|
||||
features.erase(std::unique(features.begin(), features.end(), sameID),
|
||||
features.end()); // NOLINT(modernize-use-ranges)
|
||||
EXPECT_EQ(features.size(), ids.size());
|
||||
}
|
||||
}
|
||||
@@ -451,15 +455,17 @@ TEST(Annotations, VisibleFeatures) {
|
||||
auto sameID = [](const Feature& lhs, const Feature& rhs) {
|
||||
return lhs.id == rhs.id;
|
||||
};
|
||||
std::sort(features.begin(), features.end(), sortID);
|
||||
features.erase(std::unique(features.begin(), features.end(), sameID), features.end());
|
||||
std::ranges::sort(features, sortID);
|
||||
features.erase(std::unique(features.begin(), features.end(), sameID),
|
||||
features.end()); // NOLINT(modernize-use-ranges)
|
||||
EXPECT_EQ(features.size(), ids.size());
|
||||
|
||||
test.map.jumpTo(CameraOptions().withZoom(4.0).withBearing(0.0));
|
||||
test.frontend.render(test.map);
|
||||
features = test.frontend.getRenderer()->queryRenderedFeatures(box);
|
||||
std::sort(features.begin(), features.end(), sortID);
|
||||
features.erase(std::unique(features.begin(), features.end(), sameID), features.end());
|
||||
std::ranges::sort(features, sortID);
|
||||
features.erase(std::unique(features.begin(), features.end(), sameID),
|
||||
features.end()); // NOLINT(modernize-use-ranges)
|
||||
EXPECT_EQ(features.size(), ids.size());
|
||||
}
|
||||
|
||||
@@ -541,9 +547,9 @@ TEST(Annotations, ViewFrustumCulling) {
|
||||
test.frontend.render(test.map);
|
||||
auto features = test.frontend.getRenderer()->queryRenderedFeatures(box, {});
|
||||
for (uint64_t id : testCase.second) { // testCase.second is vector of ids expected.
|
||||
EXPECT_NE(std::find_if(features.begin(),
|
||||
features.end(),
|
||||
[&id](auto feature) { return id == feature.id.template get<uint64_t>(); }),
|
||||
EXPECT_NE(std::ranges::find_if(features,
|
||||
|
||||
[&id](auto feature) { return id == feature.id.template get<uint64_t>(); }),
|
||||
features.end())
|
||||
<< "Point with id " << id << " is missing in test case " << i;
|
||||
EXPECT_EQ(features.size(), testCase.second.size()) << " in test case " << i;
|
||||
|
||||
@@ -1794,17 +1794,19 @@ TEST(Map, ObserveTileLifecycle) {
|
||||
StubMapObserver observer;
|
||||
observer.onTileActionCallback = [&](TileOperation op, const OverscaledTileID& id, const std::string& sourceID) {
|
||||
if (sourceID != "mapbox") return;
|
||||
std::lock_guard<std::mutex> lock(tileMutex);
|
||||
tileOps.push_back(TileEntry{id, sourceID, op});
|
||||
std::scoped_lock lock(tileMutex);
|
||||
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};
|
||||
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