Apply just the changes from the MLT branch which aren't really part of that work (#3793)

This commit is contained in:
Tim Sylvester
2025-09-11 16:39:58 -07:00
committed by GitHub
parent 921251b973
commit bc025fca49
44 changed files with 181 additions and 123 deletions

View File

@@ -116,7 +116,8 @@ Checks: [
-readability-avoid-nested-conditional-operator,
-readability-math-missing-parentheses,
-readability-enum-initial-value,
-boost-use-ranges
-boost-use-ranges,
-portability-template-virtual-member-function,
]
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'

View File

@@ -94,11 +94,14 @@ jobs:
shell: bash
steps:
- if: runner.os == 'Windows'
run: git config --global core.longpaths true
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
with:
submodules: true
fetch-depth: 0
submodules: recursive
fetch-depth: 1
- name: Get OS Architecture
if: runner.os == 'MacOS' || runner.os == 'Linux'

View File

@@ -98,12 +98,15 @@ jobs:
QT_VERSION: ${{ matrix.qt_version }}
steps:
- if: runner.os == 'Windows'
run: git config --global core.longpaths true
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
with:
path: source
fetch-depth: 0
submodules: true
fetch-depth: 1
submodules: recursive
- name: Install test dependencies
if: runner.os == 'Linux'

View File

@@ -12,9 +12,11 @@
"generator": "Xcode",
"description": "Create Xcode project for iOS",
"binaryDir": "${sourceDir}/build-ios",
"toolchainFile": "${sourceDir}/platform/ios/ios.toolchain.cmake",
"cacheVariables": {
"CMAKE_SYSTEM_NAME": "iOS",
"CMAKE_CXX_COMPILER_LAUNCHER": "ccache",
"CMAKE_OSX_DEPLOYMENT_TARGET": "14.0",
"MLN_WITH_METAL": "ON",
"MLN_WITH_OPENGL": "OFF"
}
@@ -27,6 +29,7 @@
"cacheVariables": {
"CMAKE_SYSTEM_NAME": "Darwin",
"CMAKE_CXX_COMPILER_LAUNCHER": "ccache",
"CMAKE_OSX_DEPLOYMENT_TARGET": "14.3",
"MLN_WITH_METAL": "ON",
"MLN_WITH_OPENGL": "OFF",
"CMAKE_BUILD_TYPE": "Debug",

View File

@@ -10,7 +10,6 @@
#include <cstdint>
#include <cstddef>
#include <memory>
#include <vector>
#include <functional>
#include <optional>

View File

@@ -31,7 +31,7 @@ private:
// unique id used for debugging and profiling purposes
// localID should not be used as unique id because a const buffer pool is managed using IBufferAllocator
// Currently unique IDs for constant buffers are only used when Tracy profiling is enabled
// Currently unique IDs for constant buffers are only used when Tracy profiling is enabled
#ifdef MLN_TRACY_ENABLE
int64_t uniqueDebugId = -1;
#endif

View File

@@ -21,8 +21,8 @@ public:
using Object = std::unordered_map<std::string, expression::Value>;
if (context.formattedSection && context.formattedSection->is<Object>()) {
const auto& section = context.formattedSection->get<Object>();
if (section.find(propertyName) != section.end()) {
return section.at(propertyName);
if (auto hit = section.find(propertyName); hit != section.end()) {
return hit->second;
}
}

View File

@@ -8,6 +8,7 @@ namespace mbgl {
template <typename Enum>
constexpr Enum operator|(Enum a, Enum b) {
static_assert(std::is_enum_v<Enum>, "Enum must be an enum type");
// NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
return Enum(mbgl::underlying_type(a) | mbgl::underlying_type(b));
}

View File

@@ -13,6 +13,7 @@ enum CompressionFormat {
DETECT = 15 + 32
};
bool is_compressed(const std::string&);
std::string compress(const std::string& raw, int windowBits = CompressionFormat::ZLIB);
std::string decompress(const std::string& raw, int windowBits = CompressionFormat::DETECT);

View File

@@ -1,7 +1,6 @@
#pragma once
#include <mbgl/util/work_task.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mutex>

View File

@@ -1,3 +1,4 @@
#include <algorithm>
#include <mbgl/storage/http_file_source.hpp>
#include <mbgl/storage/resource_options.hpp>
#include <mbgl/storage/resource.hpp>
@@ -16,23 +17,24 @@
#include <dlfcn.h>
#include <queue>
#include <map>
#include <cassert>
#include <cstring>
#include <cstdio>
#include <optional>
static void handleError(CURLMcode code) {
namespace {
void handleError(CURLMcode code) {
if (code != CURLM_OK) {
throw std::runtime_error(std::string("CURL multi error: ") + curl_multi_strerror(code));
}
}
static void handleError(CURLcode code) {
void handleError(CURLcode code) {
if (code != CURLE_OK) {
throw std::runtime_error(std::string("CURL easy error: ") + curl_easy_strerror(code));
}
}
} // namespace
namespace mbgl {
@@ -233,10 +235,8 @@ int HTTPFileSource::Impl::startTimeout(CURLM * /* multi */, long timeout_ms, voi
assert(userp);
auto context = reinterpret_cast<Impl *>(userp);
if (timeout_ms < 0) {
// A timeout of 0 ms means that the timer will invoked in the next loop iteration.
timeout_ms = 0;
}
// A timeout of 0 ms means that the timer will invoked in the next loop iteration.
timeout_ms = std::max<long>(timeout_ms, 0);
context->timeout.stop();
context->timeout.start(mbgl::Milliseconds(timeout_ms), Duration::zero(), std::bind(&Impl::onTimeout, context));
@@ -245,22 +245,22 @@ int HTTPFileSource::Impl::startTimeout(CURLM * /* multi */, long timeout_ms, voi
}
void HTTPFileSource::Impl::setResourceOptions(ResourceOptions options) {
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
std::lock_guard lock(resourceOptionsMutex);
resourceOptions = options;
}
ResourceOptions HTTPFileSource::Impl::getResourceOptions() {
std::lock_guard<std::mutex> lock(resourceOptionsMutex);
std::lock_guard lock(resourceOptionsMutex);
return resourceOptions.clone();
}
void HTTPFileSource::Impl::setClientOptions(ClientOptions options) {
std::lock_guard<std::mutex> lock(clientOptionsMutex);
std::lock_guard lock(clientOptionsMutex);
clientOptions = options;
}
ClientOptions HTTPFileSource::Impl::getClientOptions() {
std::lock_guard<std::mutex> lock(clientOptionsMutex);
std::lock_guard lock(clientOptionsMutex);
return clientOptions.clone();
}
@@ -338,6 +338,7 @@ size_t HTTPRequest::writeCallback(void *const contents, const size_t size, const
return size * nmemb;
}
namespace {
// Compares the beginning of the (non-zero-terminated!) data buffer with the
// (zero-terminated!) header string. If the data buffer contains the header
// string at the beginning, it returns the length of the header string == begin
@@ -354,6 +355,7 @@ size_t headerMatches(const char *const header, const char *const buffer, const s
}
return i == headerLength ? i : std::string::npos;
}
} // namespace
size_t HTTPRequest::headerCallback(char *const buffer, const size_t size, const size_t nmemb, void *userp) {
assert(userp);

View File

@@ -72,11 +72,9 @@ public:
std::string db_path(const std::string &path) { return path.substr(0, path.find('?')); }
bool is_compressed(const std::string &v) { return (((uint8_t)v[0]) == 0x1f) && (((uint8_t)v[1]) == 0x8b); }
// Generate a tilejson resource from .mbtiles file
void request_tilejson(const Resource &resource, ActorRef<FileSourceRequest> req) {
auto path = url_to_path(resource.url);
const auto path = url_to_path(resource.url);
Response response;
@@ -88,12 +86,12 @@ public:
mapbox::sqlite::Statement meta(db, "SELECT * from metadata");
for (mapbox::sqlite::Query q(meta); q.run();) {
auto name = q.get<std::string>(0);
const auto name = q.get<std::string>(0);
auto val = q.get<std::string>(1);
if (name == "json") {
doc.Parse(val.c_str());
} else {
values[name] = val;
values[name] = std::move(val);
}
}
@@ -104,25 +102,25 @@ public:
values["tilejson"] = "2.0.0";
values["scheme"] = "xyz";
auto format_ptr = values.find("format");
std::string format = format_ptr == values.end() ? "png" : format_ptr->second;
const auto format_ptr = values.find("format");
const std::string format = (format_ptr == values.end()) ? "png" : format_ptr->second;
if (format != "pbf" && values.count("scale") == 0) {
if (format != "pbf" && !values.contains("scale")) {
values["scale"] = "1";
}
// We use file location with appended parameter query parameter as URL for actual tile data
std::string tile_url = std::string(resource.url + "?file={x}/{y}/{z}." + format);
rapidjson::Value arr(kArrayType);
rapidjson::Value tile_url_val(tile_url, allocator);
rapidjson::Value tile_url_val(std::move(tile_url), allocator);
arr.PushBack(tile_url_val, allocator);
doc.AddMember("tiles", arr, allocator);
std::string minz;
std::string maxz;
auto minzoom_ptr = values.find("minzoom");
auto maxzoom_ptr = values.find("maxzoom");
const auto minzoom_ptr = values.find("minzoom");
const auto maxzoom_ptr = values.find("maxzoom");
if (minzoom_ptr == values.end() || maxzoom_ptr == values.end()) {
mapbox::sqlite::Statement zoom_stmt(db, "SELECT MIN(zoom_level),MAX(zoom_level) from tiles");
@@ -139,42 +137,43 @@ public:
maxz = maxzoom_ptr->second;
}
auto minZoom = std::stoi(minz);
auto maxZoom = std::stoi(maxz);
const auto minZoom = minz.empty() ? 0 : std::stoi(minz);
const auto maxZoom = maxz.empty() ? 0 : std::stoi(maxz);
for (auto const &entry : values) {
if (entry.first == "scale") {
doc.AddMember("scale", std::stod(entry.second), allocator);
} else if (entry.first == "minzoom" || entry.first == "maxzoom") {
auto name = rapidjson::Value(entry.first, allocator);
doc.AddMember(name, std::stoi(entry.second), allocator);
Document::ValueType value{entry.second.empty() ? 0 : std::stoi(entry.second)};
doc.AddMember(std::move(name), std::move(value), allocator);
} else if (entry.first == "bounds") {
std::vector<double> x = split(entry.second, ',');
if (x.size() != 4) {
const std::vector<double> bounds_values = split(entry.second, ',');
if (bounds_values.size() != 4) {
response.error = std::make_unique<Response::Error>(Response::Error::Reason::Other);
req.invoke(&FileSourceRequest::setResponse, response);
return;
}
double cLon = (x[0] + x[2]) / 2;
double cLat = (x[1] + x[3]) / 2;
int cZoom = (minZoom + maxZoom) / 2;
rapidjson::Value bounds_arr(kArrayType);
for (auto vv : x) {
bounds_arr.PushBack(vv, allocator);
}
const double cLon = (bounds_values[0] + bounds_values[2]) / 2;
const double cLat = (bounds_values[1] + bounds_values[3]) / 2;
const int cZoom = (minZoom + maxZoom) / 2;
if (format != "pbf") {
doc.AddMember("bounds", bounds_arr, allocator);
rapidjson::Value bounds_arr(kArrayType);
for (auto vv : bounds_values) {
bounds_arr.PushBack(vv, allocator);
}
doc.AddMember("bounds", std::move(bounds_arr), allocator);
}
rapidjson::Value center_arr(kArrayType);
center_arr.PushBack(cLon, allocator);
center_arr.PushBack(cLat, allocator);
center_arr.PushBack(cZoom, allocator);
doc.AddMember("center", center_arr, allocator);
doc.AddMember("center", std::move(center_arr), allocator);
} else {
rapidjson::Value name = rapidjson::Value(entry.first, allocator);
doc.AddMember(name, rapidjson::Value(entry.second, allocator), allocator);
doc.AddMember(std::move(name), rapidjson::Value(entry.second, allocator), allocator);
}
}
@@ -210,7 +209,7 @@ public:
response.expires = Timestamp::max();
response.etag = resource.url;
if (is_compressed(*response.data)) {
if (util::is_compressed(*response.data)) {
response.data = std::make_shared<std::string>(util::decompress(*response.data));
}
}
@@ -250,7 +249,7 @@ private:
void close_all() { db_cache.clear(); }
// Multiple databases open simultaneoulsy, to effectively support multiple .mbtiles maps
// Multiple databases open simultaneously, to effectively support multiple .mbtiles maps
mapbox::sqlite::Database &get_db(const std::string &path) {
auto ptr = db_cache.find(path);
if (ptr != db_cache.end()) {

View File

@@ -119,7 +119,7 @@ public:
req,
tileID,
header.root_dir_offset,
static_cast<uint32_t>(header.root_dir_bytes),
static_cast<std::uint32_t>(header.root_dir_bytes),
0,
[=, this](std::pair<uint64_t, uint32_t> tileAddress, std::unique_ptr<Response::Error> tileError) {
if (tileError) {

View File

@@ -31,6 +31,29 @@ namespace util {
// cause a link error.
#undef compress
bool is_compressed(const std::string &v) {
if (v.size() > 2) {
const auto byte0 = static_cast<uint8_t>(v[0]);
const auto byte1 = static_cast<uint8_t>(v[1]);
if (byte0 == 0x1f && byte1 == 0x8b) {
// gzip (rfc1952)
return true;
} else if (byte0 == 0x78) {
// zlib (rfc1950)
switch (byte1) {
case 0x01: // 78 01 - No Compression/low
case 0x5E: // 78 5E - Fast Compression
case 0x9C: // 78 9C - Default Compression
case 0xDA: // 78 DA - Best Compression
return true;
default:
return false;
}
}
}
return false;
}
std::string compress(const std::string &raw, int windowBits) {
z_stream deflate_stream;
memset(&deflate_stream, 0, sizeof(deflate_stream));
@@ -79,14 +102,13 @@ std::string decompress(const std::string &raw, int windowBits) {
inflate_stream.avail_in = uInt(raw.size());
std::string result;
char out[15384];
char out[16384];
int code;
do {
inflate_stream.next_out = reinterpret_cast<Bytef *>(out);
inflate_stream.avail_out = sizeof(out);
code = inflate(&inflate_stream, 0);
// result.append(out, sizeof(out) - inflate_stream.avail_out);
if (result.size() < inflate_stream.total_out) {
result.append(out, inflate_stream.total_out - result.size());
}

View File

@@ -2498,7 +2498,7 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
break;
case MLNTileOperationCancelled:
NSLog(@"Pending work on tile %@", tileStr);
NSLog(@"Pending work cancelled on tile %@", tileStr);
break;
case MLNTileOperationNullOp:

View File

@@ -0,0 +1,3 @@
set(CMAKE_SYSTEM_NAME iOS)
set(CMAKE_SYSTEM_VERSION 15.0)
set(CMAKE_SYSTEM_PROCESSOR arm64)

View File

@@ -166,7 +166,7 @@ void MLNMapViewImpl::onGlyphsRequested(const mbgl::FontStack& fontStack, const m
void MLNMapViewImpl::onTileAction(mbgl::TileOperation operation, const mbgl::OverscaledTileID& tile, const std::string& sourceID) {
[mapView tileDidTriggerAction:MLNTileOperation(static_cast<int>(operation))
x:tile.canonical.x
y:tile.canonical.x
y:tile.canonical.y
z:tile.canonical.z
wrap:tile.wrap
overscaledZ:tile.overscaledZ

View File

@@ -26,7 +26,7 @@ void Scheduler::SetCurrent(Scheduler* scheduler) {
Scheduler* Scheduler::GetCurrent(bool init) {
if (!localScheduler && init) {
thread_local util::RunLoop runLoop;
static thread_local util::RunLoop runLoop;
SetCurrent(&runLoop);
}
return localScheduler;

View File

@@ -135,10 +135,10 @@ void AnnotationManager::update(const AnnotationID& id, const FillAnnotation& ann
void AnnotationManager::remove(const AnnotationID& id) {
CHECK_ANNOTATIONS_ENABLED_AND_RETURN_NOARG();
if (symbolAnnotations.find(id) != symbolAnnotations.end()) {
if (symbolAnnotations.contains(id)) {
symbolTree.remove(symbolAnnotations.at(id));
symbolAnnotations.erase(id);
} else if (shapeAnnotations.find(id) != shapeAnnotations.end()) {
} else if (shapeAnnotations.contains(id)) {
auto it = shapeAnnotations.find(id);
(void)*style.get().impl->removeLayer(it->second->layerID);
shapeAnnotations.erase(it);

View File

@@ -154,7 +154,7 @@ struct glyph {
// Font data From Hershey Simplex Font
// http://paulbourke.net/dataformats/hershey/
// NOLINTBEGIN(modernize-use-designated-initializers)
const glyph simplex[] = {
/* 32 */ {16, 0, nullptr},
/* 33 ! */
@@ -346,3 +346,4 @@ const glyph simplex[] = {
/* 126 ~ */
{24, sizeof(simplex_94), simplex_94},
};
// NOLINTEND(modernize-use-designated-initializers)

View File

@@ -210,8 +210,9 @@ void DashPatternTexture::upload(gfx::UploadPass& uploadPass) {
if (std::holds_alternative<AlphaImage>(texture)) {
auto tempTexture = uploadPass.getContext().createTexture2D();
tempTexture->upload(std::get<AlphaImage>(texture));
tempTexture->setSamplerConfiguration(
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Repeat, gfx::TextureWrapType::Clamp});
tempTexture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear,
.wrapU = gfx::TextureWrapType::Repeat,
.wrapV = gfx::TextureWrapType::Clamp});
texture = std::move(tempTexture);
}
}

View File

@@ -107,7 +107,8 @@ UniqueGPUExpression GPUExpression::create(const Expression& expression, const Zo
}
float GPUExpression::evaluateFloat(const float zoom) const {
const auto index = std::distance(&inputs[0], std::upper_bound(&inputs[0], &inputs[stopCount], zoom));
const auto index = static_cast<std::uint16_t>(
std::distance(&inputs[0], std::upper_bound(&inputs[0], &inputs[stopCount], zoom)));
if (index == 0) {
return stops.floats[0];
} else if (index == stopCount) {
@@ -153,7 +154,8 @@ Color GPUExpression::getColor(std::size_t index) const {
}
Color GPUExpression::evaluateColor(const float zoom) const {
const auto index = std::distance(&inputs[0], std::upper_bound(&inputs[0], &inputs[stopCount], zoom));
const auto index = static_cast<std::uint16_t>(
std::distance(&inputs[0], std::upper_bound(&inputs[0], &inputs[stopCount], zoom)));
if (index == 0) {
return getColor(0);
} else if (index == stopCount) {

View File

@@ -93,14 +93,14 @@ void PolylineGenerator<PLV, PS>::generate(const GeometryCoordinates& coordinates
const std::size_t first = [&coordinates, &len] {
std::size_t i = 0;
// If the line has duplicate vertices at the start, adjust index to remove them.
while (i < len - 1 && coordinates[i] == coordinates[i + 1]) {
while (i + 1 < len && coordinates[i] == coordinates[i + 1]) {
i++;
}
return i;
}();
// Ignore invalid geometry.
if (len < (options.type == FeatureType::Polygon ? 3 : 2)) {
if (len < ((options.type == FeatureType::Polygon) ? 3u : 2u)) {
return;
}

View File

@@ -5,7 +5,6 @@
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/util/monotonic_timer.hpp>
#include <algorithm>
#include <initializer_list>
#include <sstream>
#include <iomanip>
@@ -26,7 +25,7 @@ bool RenderingStats::isZero() const {
memIndexBuffers,
memVertexBuffers,
memUniformBuffers};
return std::all_of(expectedZeros.begin(), expectedZeros.end(), [](auto x) { return x == 0; });
return std::ranges::all_of(expectedZeros, [](auto x) { return x == 0; });
}
RenderingStats& RenderingStats::operator+=(const RenderingStats& r) {

View File

@@ -6,7 +6,7 @@ namespace gfx {
bool ShaderGroup::isShader(const std::string& shaderName) const noexcept {
std::shared_lock<std::shared_mutex> readerLock(programLock);
return programs.find(shaderName) != programs.end();
return programs.contains(shaderName);
}
const std::shared_ptr<gfx::Shader> ShaderGroup::getShader(const std::string& shaderName) const noexcept {
@@ -25,7 +25,7 @@ bool ShaderGroup::replaceShader(std::shared_ptr<gfx::Shader>&& shader) noexcept
bool ShaderGroup::replaceShader(std::shared_ptr<Shader>&& shader, const std::string& shaderName) noexcept {
std::unique_lock<std::shared_mutex> writerLock(programLock);
if (programs.find(shaderName) == programs.end()) {
if (!programs.contains(shaderName)) {
return false;
}
@@ -39,7 +39,7 @@ bool ShaderGroup::registerShader(std::shared_ptr<gfx::Shader>&& shader) noexcept
bool ShaderGroup::registerShader(std::shared_ptr<Shader>&& shader, const std::string& shaderName) noexcept {
std::unique_lock<std::shared_mutex> writerLock(programLock);
if (programs.find(shaderName) != programs.end()) {
if (programs.contains(shaderName)) {
return false;
}

View File

@@ -13,7 +13,7 @@ ShaderGroup& ShaderRegistry::getLegacyGroup() noexcept {
bool ShaderRegistry::isShaderGroup(const std::string& shaderGroupName) const noexcept {
std::shared_lock<std::shared_mutex> readerLock(shaderGroupLock);
return shaderGroups.find(shaderGroupName) != shaderGroups.end();
return shaderGroups.contains(shaderGroupName);
}
const ShaderGroupPtr ShaderRegistry::getShaderGroup(const std::string& shaderGroupName) const noexcept {
@@ -28,7 +28,7 @@ const ShaderGroupPtr ShaderRegistry::getShaderGroup(const std::string& shaderGro
bool ShaderRegistry::replaceShader(ShaderGroupPtr&& shader, const std::string& shaderGroupName) noexcept {
std::unique_lock<std::shared_mutex> writerLock(shaderGroupLock);
if (shaderGroups.find(shaderGroupName) == shaderGroups.end()) {
if (!shaderGroups.contains(shaderGroupName)) {
return false;
}
@@ -38,7 +38,7 @@ bool ShaderRegistry::replaceShader(ShaderGroupPtr&& shader, const std::string& s
bool ShaderRegistry::registerShaderGroup(ShaderGroupPtr&& shader, const std::string& shaderGroupName) noexcept {
std::unique_lock<std::shared_mutex> writerLock(shaderGroupLock);
if (shaderGroups.find(shaderGroupName) != shaderGroups.end()) {
if (shaderGroups.contains(shaderGroupName)) {
return false;
}

View File

@@ -45,7 +45,7 @@ public:
const auto& sortKeyProperty = layout.template get<style::CircleSortKey>();
float sortKey = sortKeyProperty.evaluate(*feature, zoom, style::CircleSortKey::defaultValue());
CircleFeature circleFeature{i, std::move(feature), sortKey};
CircleFeature circleFeature{.i = i, .feature = std::move(feature), .sortKey = sortKey};
const auto sortPosition = std::lower_bound(features.cbegin(), features.cend(), circleFeature);
features.insert(sortPosition, std::move(circleFeature));
}

View File

@@ -7,7 +7,7 @@ namespace util {
// Map of key -> index into features
using Index = std::unordered_map<size_t, size_t>;
namespace {
size_t mergeFromRight(std::vector<SymbolFeature>& features,
Index& rightIndex,
Index::iterator left,
@@ -40,7 +40,7 @@ size_t mergeFromLeft(std::vector<SymbolFeature>& features,
size_t getKey(const std::u16string& text, const GeometryCoordinate& coord) {
return util::hash(text, coord.x, coord.y);
}
} // namespace
void mergeLines(std::vector<SymbolFeature>& features) {
Index leftIndex;
Index rightIndex;

View File

@@ -8,6 +8,8 @@
#include <mbgl/style/layer_properties.hpp>
#include <mbgl/util/containers.hpp>
#include <list>
namespace mbgl {
class PatternDependency {
@@ -54,8 +56,8 @@ struct PatternFeatureInserter<void> {
template <typename PropertiesType>
static void insert(std::vector<PatternFeature>& features,
std::size_t index,
std::unique_ptr<GeometryTileFeature> feature,
PatternLayerMap patternDependencyMap,
std::unique_ptr<GeometryTileFeature>&& feature,
PatternLayerMap&& patternDependencyMap,
float /*zoom*/,
const PropertiesType&,
const CanonicalTileID&) {
@@ -68,8 +70,8 @@ struct PatternFeatureInserter {
template <typename PropertiesType>
static void insert(std::vector<PatternFeature>& features,
std::size_t index,
std::unique_ptr<GeometryTileFeature> feature,
PatternLayerMap patternDependencyMap,
std::unique_ptr<GeometryTileFeature>&& feature,
PatternLayerMap&& patternDependencyMap,
float zoom,
const PropertiesType& properties,
const CanonicalTileID& canonical) {
@@ -91,7 +93,7 @@ class PatternLayout : public Layout {
public:
PatternLayout(const BucketParameters& parameters,
const std::vector<Immutable<style::LayerProperties>>& group,
std::unique_ptr<GeometryTileLayer> sourceLayer_,
std::unique_ptr<GeometryTileLayer>&& sourceLayer_,
const LayoutParameters& layoutParameters)
: sourceLayer(std::move(sourceLayer_)),
zoom(parameters.tileID.overscaledZ),

View File

@@ -4,7 +4,6 @@
#include <mbgl/text/tagged_string.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <array>
#include <string>
#include <optional>

View File

@@ -27,13 +27,13 @@ namespace mbgl {
using namespace style;
namespace {
template <class Property>
static bool has(const style::SymbolLayoutProperties::PossiblyEvaluated& layout) {
bool has(const style::SymbolLayoutProperties::PossiblyEvaluated& layout) {
return layout.get<Property>().match([](const typename Property::Type& t) { return !t.empty(); },
[](const auto&) { return true; });
}
namespace {
expression::Value sectionOptionsToValue(const SectionOptions& options) {
std::unordered_map<std::string, expression::Value> result;
// TODO: Data driven properties that can be overridden on per section basis.

View File

@@ -689,7 +689,7 @@ ScreenCoordinate TransformState::latLngToScreenCoordinate(const LatLng& latLng,
TileCoordinate TransformState::screenCoordinateToTileCoordinate(const ScreenCoordinate& point, uint8_t atZoom) const {
if (size.isEmpty()) {
return {{}, 0};
return {.p = {}, .z = 0};
}
float targetZ = 0;
@@ -718,7 +718,7 @@ TileCoordinate TransformState::screenCoordinateToTileCoordinate(const ScreenCoor
double t = z0 == z1 ? 0 : (targetZ - z0) / (z1 - z0);
Point<double> p = util::interpolate(p0, p1, t) / scale * static_cast<double>(1 << atZoom);
return {{p.x, p.y}, static_cast<double>(atZoom)};
return {.p = {p.x, p.y}, .z = static_cast<double>(atZoom)};
}
LatLng TransformState::screenCoordinateToLatLng(const ScreenCoordinate& point, LatLng::WrapMode wrapMode) const {

View File

@@ -40,7 +40,7 @@ public:
const ImagePositions&,
const PatternLayerMap&,
std::size_t,
const CanonicalTileID&) {};
const CanonicalTileID&) {}
virtual void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) {}

View File

@@ -13,12 +13,14 @@ DebugBucket::DebugBucket(const OverscaledTileID& id,
const bool complete_,
std::optional<Timestamp> modified_,
std::optional<Timestamp> expires_,
MapDebugOptions debugMode_)
MapDebugOptions debugMode_,
std::string sourceName_)
: renderable(renderable_),
complete(complete_),
modified(std::move(modified_)),
expires(std::move(expires_)),
debugMode(debugMode_) {
debugMode(debugMode_),
sourceName(std::move(sourceName_)) {
auto addText = [&](const std::string& text, double left, double baseline, double scale) {
for (uint8_t c : text) {
if (c < 32 || c >= 127) continue;
@@ -53,7 +55,8 @@ DebugBucket::DebugBucket(const OverscaledTileID& id,
const std::string text = util::toString(id) + " - " +
(complete ? "complete"
: renderable ? "renderable"
: "pending");
: "pending") +
" " + sourceName;
addText(text, 50, baseline, 5);
baseline += 200;
}

View File

@@ -22,7 +22,8 @@ public:
bool complete,
std::optional<Timestamp> modified,
std::optional<Timestamp> expires,
MapDebugOptions);
MapDebugOptions,
std::string sourceName);
void upload(gfx::UploadPass&);
@@ -31,6 +32,7 @@ public:
const std::optional<Timestamp> modified;
const std::optional<Timestamp> expires;
const MapDebugOptions debugMode;
const std::string sourceName;
gfx::VertexVector<FillLayoutVertex> vertices;
gfx::IndexVector<gfx::Lines> indices;

View File

@@ -428,12 +428,13 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
}
// Prepare. Update all matrices and generate data that we should upload to the GPU.
for (const auto& entry : renderSources) {
for (const auto& [name, renderSource] : renderSources) {
MLN_TRACE_ZONE(prepare source);
if (entry.second->isEnabled()) {
entry.second->prepare({.transform = renderTreeParameters->transformParams,
if (renderSource->isEnabled()) {
renderSource->prepare({.transform = renderTreeParameters->transformParams,
.debugOptions = updateParameters->debugOptions,
.imageManager = *imageManager});
.imageManager = *imageManager,
.sourceName = name});
}
}

View File

@@ -43,6 +43,7 @@ public:
const TransformParameters& transform;
const MapDebugOptions& debugOptions;
const ImageManager& imageManager;
const std::string sourceName;
};
using RenderTiles = std::shared_ptr<const std::vector<std::reference_wrapper<const RenderTile>>>;

View File

@@ -120,8 +120,13 @@ void RenderTile::prepare(const SourcePrepareParameters& parameters) {
(!debugBucket || debugBucket->renderable != tile.isRenderable() || debugBucket->complete != tile.isComplete() ||
!(debugBucket->modified == tile.modified) || !(debugBucket->expires == tile.expires) ||
debugBucket->debugMode != parameters.debugOptions)) {
debugBucket = std::make_unique<DebugBucket>(
tile.id, tile.isRenderable(), tile.isComplete(), tile.modified, tile.expires, parameters.debugOptions);
debugBucket = std::make_unique<DebugBucket>(tile.id,
tile.isRenderable(),
tile.isComplete(),
tile.modified,
tile.expires,
parameters.debugOptions,
parameters.sourceName);
} else if (parameters.debugOptions == MapDebugOptions::NoDebug) {
debugBucket.reset();
}

View File

@@ -45,6 +45,7 @@ public:
std::unique_ptr<gl::ProgramBase<Name>> programBase;
// NOLINTNEXTLINE(bugprone-crtp-constructor-accessibility) We don't want to list every derived class as a friend
Program([[maybe_unused]] const ProgramParameters& programParameters) {
switch (gfx::Backend::GetType()) {
#if MLN_RENDER_BACKEND_METAL

View File

@@ -14,13 +14,15 @@
#include <mapbox/eternal.hpp>
#include <algorithm>
#include <cmath>
#include <limits>
#include <numbers>
namespace mbgl {
namespace style {
namespace expression {
namespace {
/*
Represents the parameter list for an expression that takes an arbitrary
number of arguments (of a specific type).
@@ -39,7 +41,7 @@ struct Varargs : std::vector<T> {
explicit Varargs(Args&&... args)
: std::vector<T>(std::forward<Args>(args)...) {}
};
} // namespace
namespace detail {
// Base class for the Signature<Fn> structs that are used to determine
// each CompoundExpression definition's type::Type data from the type of its
@@ -225,16 +227,17 @@ struct SignatureType<Lambda, std::enable_if_t<std::is_class_v<Lambda>>> {
using Type = typename SignatureType<decltype(&Lambda::operator())>::Type;
};
namespace {
template <typename Fn>
static std::unique_ptr<detail::SignatureBase> makeSignature(std::string name,
Fn evaluateFunction,
Dependency dependencies = Dependency::None) {
std::unique_ptr<detail::SignatureBase> makeSignature(std::string name,
Fn evaluateFunction,
Dependency dependencies = Dependency::None) {
return std::make_unique<Signature<typename SignatureType<Fn>::Type>>(
evaluateFunction, std::move(name), dependencies);
}
} // namespace
} // namespace detail
namespace {
Value featureIdAsExpressionValue(const EvaluationContext& params) {
assert(params.feature);
auto id = params.feature->getID();
@@ -297,17 +300,17 @@ std::optional<std::string> featureIdAsString(const EvaluationContext& params) {
};
const auto& eCompoundExpression() {
static auto signature = detail::makeSignature("e", []() -> Result<double> { return 2.718281828459045; });
static auto signature = detail::makeSignature("e", []() -> Result<double> { return std::numbers::e; });
return signature;
}
const auto& piCompoundExpression() {
static auto signature = detail::makeSignature("pi", []() -> Result<double> { return 3.141592653589793; });
static auto signature = detail::makeSignature("pi", []() -> Result<double> { return std::numbers::pi; });
return signature;
}
const auto& ln2CompoundExpression() {
static auto signature = detail::makeSignature("ln2", []() -> Result<double> { return 0.6931471805599453; });
static auto signature = detail::makeSignature("ln2", []() -> Result<double> { return std::numbers::ln2; });
return signature;
}
@@ -956,8 +959,8 @@ const auto& filterTypeInCompoundExpression() {
"filter-type-in",
[](const EvaluationContext& params, const Varargs<std::string>& types) -> Result<bool> {
assert(params.feature);
std::optional<std::string> type = featureTypeAsString(params.feature->getType());
return std::find(types.begin(), types.end(), type) != types.end();
const auto type = featureTypeAsString(params.feature->getType());
return std::ranges::find(types, type) != types.end();
},
Dependency::Feature);
return signature;
@@ -967,8 +970,8 @@ const auto& filterIdInCompoundExpression() {
static auto signature = detail::makeSignature(
"filter-id-in",
[](const EvaluationContext& params, const Varargs<Value>& ids) -> Result<bool> {
auto id = featureIdAsExpressionValue(params);
return std::find(ids.begin(), ids.end(), id) != ids.end();
const auto id = featureIdAsExpressionValue(params);
return std::ranges::find(ids, id) != ids.end();
},
Dependency::Feature);
return signature;
@@ -1113,9 +1116,9 @@ std::string expectedTypesError(const Definitions& definitions, const std::vector
return "Expected arguments of type " + signatures + ", but found (" + actualTypes + ") instead.";
}
static ParseResult createCompoundExpression(const Definitions& definitions,
std::vector<std::unique_ptr<Expression>> args,
ParsingContext& ctx) {
ParseResult createCompoundExpression(const Definitions& definitions,
std::vector<std::unique_ptr<Expression>> args,
ParsingContext& ctx) {
ParsingContext signatureContext(ctx.getKey());
for (auto it = definitions.first; it != definitions.second; ++it) {
@@ -1162,6 +1165,8 @@ static ParseResult createCompoundExpression(const Definitions& definitions,
return ParseResult();
}
} // namespace
ParseResult parseCompoundExpression(const std::string& name, const Convertible& value, ParsingContext& ctx) {
assert(isArray(value) && arrayLength(value) > 0);

View File

@@ -14,7 +14,6 @@
#include <memory>
#include <unordered_map>
#include <vector>
#include <optional>
namespace mbgl {

View File

@@ -20,7 +20,8 @@ using namespace std::numbers;
namespace mbgl {
static double signedArea(const GeometryCoordinates& ring) {
namespace {
double signedArea(const GeometryCoordinates& ring) {
double sum = 0;
for (std::size_t i = 0, len = ring.size(), j = len - 1; i < len; j = i++) {
@@ -32,7 +33,7 @@ static double signedArea(const GeometryCoordinates& ring) {
return sum;
}
static LinearRing<int32_t> toWagyuPath(const GeometryCoordinates& ring) {
LinearRing<int32_t> toWagyuPath(const GeometryCoordinates& ring) {
MLN_TRACE_FUNC();
LinearRing<int32_t> result;
@@ -43,7 +44,7 @@ static LinearRing<int32_t> toWagyuPath(const GeometryCoordinates& ring) {
return result;
}
static GeometryCollection toGeometryCollection(MultiPolygon<int16_t>&& multipolygon) {
GeometryCollection toGeometryCollection(MultiPolygon<int16_t>&& multipolygon) {
MLN_TRACE_FUNC();
GeometryCollection result;
@@ -54,6 +55,7 @@ static GeometryCollection toGeometryCollection(MultiPolygon<int16_t>&& multipoly
}
return result;
}
} // namespace
GeometryCollection fixupPolygons(const GeometryCollection& rings) {
MLN_TRACE_FUNC();

View File

@@ -47,9 +47,8 @@ TileLoader<T>::TileLoader(T& tile_,
// initial std::optional part of the request.
loadFromCache();
} else if (necessity == TileNecessity::Required) {
// When the file source doesn't support cache-only requests, and we
// definiitely need this data, we can start out with a network request
// immediately.
// When the file source doesn't support cache-only requests, and we definitely
// need this data, we can start out with a network request immediately.
loadFromNetwork();
} else {
// When the FileSource doesn't support cache-only requests, we do

View File

@@ -49,9 +49,9 @@ void scanSpans(edge e0, edge e1, int32_t ymin, int32_t ymax, ScanLine& scanLine)
// scan lines!
const double m0 = e0.dx / e0.dy;
const double m1 = e1.dx / e1.dy;
const double d0 = e0.dx > 0; // use y + 1 to compute x0
const double d1 = e1.dx < 0; // use y + 1 to compute x1
for (double y = y0; y < y1; y++) {
const double d0 = e0.dx > 0; // use y + 1 to compute x0
const double d1 = e1.dx < 0; // use y + 1 to compute x1
for (double y = y0; y < y1; y++) { // NOLINT(clang-analyzer-security.FloatLoopCounter)
double x0 = m0 * ::fmax(0, ::fmin(e0.dy, y + d0 - e0.y0)) + e0.x0;
double x1 = m1 * ::fmax(0, ::fmin(e1.dy, y + d1 - e1.y0)) + e1.x0;
scanLine(static_cast<int32_t>(std::floor(x1)), static_cast<int32_t>(std::ceil(x0)), static_cast<int32_t>(y));