update linux-ci to Ubuntu 24.04, apply clang-tidy fixes (#3998)

This commit is contained in:
Bart Louwers
2025-12-11 21:56:24 +01:00
committed by GitHub
parent 83d34c3a17
commit 5882a9c94e
117 changed files with 927 additions and 825 deletions

View File

@@ -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: '.*'

View File

@@ -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:

View File

@@ -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.
}

View File

@@ -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

View File

@@ -91,7 +91,7 @@ struct RenderingStats {
RenderingStats& operator+=(const RenderingStats&);
#if !defined(NDEBUG)
#ifndef NDEBUG
std::string toString(std::string_view separator) const;
#endif
};

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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))

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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) {

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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});
}
}

View File

@@ -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 {

View File

@@ -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});
}
}
}

View File

@@ -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 {};
}

View File

@@ -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);
}
}

View File

@@ -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,

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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)
}
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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));

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -6,6 +6,7 @@ namespace mbgl {
using namespace shaders;
// NOLINTNEXTLINE(modernize-use-ranges)
MBGL_DEFINE_ENUM(BuiltIn,
{{BuiltIn::None, "None"},
{BuiltIn::Prelude, "Prelude"},

View File

@@ -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)));

View File

@@ -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 +

View File

@@ -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()) {

View File

@@ -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();
}
}

View File

@@ -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};
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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>(),

View File

@@ -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 = ""}};
}
}
});

View File

@@ -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]}});
}
}

View File

@@ -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)

View File

@@ -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};
}

View File

@@ -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; });
}

View File

@@ -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));
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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});
}
}
}

View File

@@ -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();
}};

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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);

View File

@@ -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;

View File

@@ -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