summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLeith Bade <leith@mapbox.com>2014-11-28 01:37:35 +1100
committerLeith Bade <leith@mapbox.com>2014-11-28 01:51:21 +1100
commit8ae2cd3985e959e622f90d30a017032f9a5ca37c (patch)
treeeb9ea52a6a9005259c6124991e8dd7d0f7d97e5e /src
parent014ebd2f133c883eec652b7ea598acc71924a217 (diff)
parent79017060947c1a11f4124ab837bd171b748806de (diff)
downloadqtlocation-mapboxgl-8ae2cd3985e959e622f90d30a017032f9a5ca37c.tar.gz
Merge branch 'master' of github.com:mapbox/mapbox-gl-native into android-mason
Conflicts: README.md configure gyp/mbgl-linux.gypi include/mbgl/map/map.hpp include/mbgl/platform/default/image_reader.hpp include/mbgl/platform/default/jpeg_reader.hpp include/mbgl/platform/default/png_reader.hpp include/mbgl/util/uv_detail.hpp ios/mapbox-gl-cocoa platform/default/image.cpp platform/default/image_reader.cpp platform/default/jpeg_reader.cpp platform/default/png_reader.cpp src/map/map.cpp
Diffstat (limited to 'src')
-rw-r--r--src/geometry/glyph_atlas.cpp10
-rw-r--r--src/map/map.cpp157
-rw-r--r--src/map/raster_tile_data.cpp6
-rw-r--r--src/map/source.cpp65
-rw-r--r--src/map/tile_data.cpp32
-rw-r--r--src/map/tile_parser.cpp15
-rw-r--r--src/map/vector_tile_data.cpp25
-rw-r--r--src/renderer/raster_bucket.cpp2
-rw-r--r--src/style/style_parser.cpp12
-rw-r--r--src/util/raster.cpp6
-rw-r--r--src/util/uv.cpp12
11 files changed, 149 insertions, 193 deletions
diff --git a/src/geometry/glyph_atlas.cpp b/src/geometry/glyph_atlas.cpp
index 72c961fda5..50bda5dc4e 100644
--- a/src/geometry/glyph_atlas.cpp
+++ b/src/geometry/glyph_atlas.cpp
@@ -17,10 +17,6 @@ GlyphAtlas::GlyphAtlas(uint16_t width_, uint16_t height_)
dirty(true) {
}
-GlyphAtlas::~GlyphAtlas() {
- delete[] data;
-}
-
Rect<uint16_t> GlyphAtlas::addGlyph(uint64_t tile_id, const std::string& face_name,
const SDFGlyph& glyph)
{
@@ -74,7 +70,7 @@ Rect<uint16_t> GlyphAtlas::addGlyph_impl(uint64_t tile_id, const std::string& fa
face.emplace(glyph.id, GlyphValue { rect, tile_id });
// Copy the bitmap
- char *target = data;
+ char *target = data.get();
const char *source = glyph.bitmap.data();
for (uint32_t y = 0; y < buffered_height; y++) {
uint32_t y1 = width * (rect.y + y) + rect.x;
@@ -119,7 +115,7 @@ void GlyphAtlas::removeGlyphs(uint64_t tile_id) {
const Rect<uint16_t>& rect = value.rect;
// Clear out the bitmap.
- char *target = data;
+ char *target = data.get();
for (uint32_t y = 0; y < rect.h; y++) {
uint32_t y1 = width * (rect.y + y) + rect.x;
for (uint32_t x = 0; x < rect.w; x++) {
@@ -157,7 +153,7 @@ void GlyphAtlas::bind() {
if (dirty) {
std::lock_guard<std::mutex> lock(mtx);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data.get());
dirty = false;
#if defined(DEBUG)
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 9f4bc78b69..116abc5902 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -92,9 +92,6 @@ using namespace mbgl;
Map::Map(View& view_)
: loop(std::make_unique<uv::loop>()),
thread(std::make_unique<uv::thread>()),
- async_terminate(new uv_async_t()),
- async_render(new uv_async_t()),
- async_cleanup(new uv_async_t()),
view(view_),
#ifndef NDEBUG
main_thread(uv_thread_self()),
@@ -118,10 +115,11 @@ Map::~Map() {
}
// Explicitly reset all pointers.
- texturepool.reset();
+ activeSources.clear();
sprite.reset();
glyphStore.reset();
style.reset();
+ texturepool.reset();
fileSource.reset();
workers.reset();
@@ -147,27 +145,46 @@ void Map::start(bool start_paused) {
is_stopped = false;
// Setup async notifications
+ async_terminate = std::make_unique<uv::async>(**loop, [this]() {
+ assert(uv_thread_self() == map_thread);
+
+ // Remove all of these to make sure they are destructed in the correct thread.
+ glyphStore.reset();
+ fileSource.reset();
+ style.reset();
+ workers.reset();
+ activeSources.clear();
+
+ terminating = true;
+
+ // Closes all open handles on the loop. This means that the loop will automatically terminate.
+ async_cleanup.reset();
+ async_render.reset();
+ async_terminate.reset();
+ });
-// Iron out the differences between libuv 0.10 and 0.11
-#ifdef UV_ASYNC_CALLBACK
-#error Cannot overwrite UV_ASYNC_CALLBACK
-#endif
-#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
-#define UV_ASYNC_CALLBACK(name) [](uv_async_t *a, int) { return Map::name(a); }
-#else
-#define UV_ASYNC_CALLBACK(name) name
-#endif
-
- uv_async_init(**loop, async_terminate.get(), UV_ASYNC_CALLBACK(terminate));
- async_terminate->data = this;
-
- uv_async_init(**loop, async_render.get(), UV_ASYNC_CALLBACK(render));
- async_render->data = this;
-
- uv_async_init(**loop, async_cleanup.get(), UV_ASYNC_CALLBACK(cleanup));
- async_cleanup->data = this;
+ async_render = std::make_unique<uv::async>(**loop, [this]() {
+ assert(uv_thread_self() == map_thread);
+
+ if (state.hasSize()) {
+ if (is_rendered.test_and_set() == false) {
+ prepare();
+ if (is_clean.test_and_set() == false) {
+ render();
+ is_swapped.clear();
+ view.swap();
+ } else {
+ // We set the rendered flag in the test above, so we have to reset it
+ // now that we're not actually rendering because the map is clean.
+ is_rendered.clear();
+ }
+ }
+ }
+ });
-#undef UV_ASYNC_CALLBACK
+ async_cleanup = std::make_unique<uv::async>(**loop, [this]() {
+ painter.cleanup();
+ });
// Do we need to pause first?
if (start_paused) {
@@ -198,7 +215,7 @@ void Map::stop(stop_callback cb, void *data) {
assert(main_thread != map_thread);
assert(async);
- uv_async_send(async_terminate.get());
+ async_terminate->send();
resume();
@@ -315,7 +332,7 @@ void Map::rerender() {
// We only send render events if we want to continuously update the map
// (== async rendering).
if (async) {
- uv_async_send(async_render.get());
+ async_render->send();
}
}
@@ -335,16 +352,10 @@ void Map::swapped() {
void Map::cleanup() {
if (async_cleanup != nullptr) {
- uv_async_send(async_cleanup.get());
+ async_cleanup->send();
}
}
-void Map::cleanup(uv_async_t *async) {
- Map *map = static_cast<Map *>(async->data);
-
- map->painter.cleanup();
-}
-
void Map::terminate() {
painter.terminate();
}
@@ -360,47 +371,6 @@ void Map::setReachability(bool reachable) {
}
}
-void Map::render(uv_async_t *async) {
- Map *map = static_cast<Map *>(async->data);
- assert(uv_thread_self() == map->map_thread);
-
- if (map->state.hasSize()) {
- if (map->is_rendered.test_and_set() == false) {
- map->prepare();
- if (map->is_clean.test_and_set() == false) {
- map->render();
- map->is_swapped.clear();
- map->view.swap();
- } else {
- // We set the rendered flag in the test above, so we have to reset it
- // now that we're not actually rendering because the map is clean.
- map->is_rendered.clear();
- }
- }
- }
-}
-
-void Map::terminate(uv_async_t *async) {
- // Closes all open handles on the loop. This means that the loop will automatically terminate.
- Map *map = static_cast<Map *>(async->data);
- assert(uv_thread_self() == map->map_thread);
-
- // Remove all of these to make sure they are destructed in the correct thread.
- map->glyphStore.reset();
- map->fileSource.reset();
- map->style.reset();
- map->workers.reset();
- map->activeSources.clear();
-
- map->view.make_inactive();
-
- map->terminating = true;
-
- uv_close((uv_handle_t *)map->async_cleanup.get(), nullptr);
- uv_close((uv_handle_t *)map->async_render.get(), nullptr);
- uv_close((uv_handle_t *)map->async_terminate.get(), nullptr);
-}
-
#pragma mark - Setup
void Map::setup() {
@@ -479,12 +449,10 @@ util::ptr<Sprite> Map::getSprite() {
#pragma mark - Size
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::resize(uint16_t width, uint16_t height, float ratio) {
resize(width, height, ratio, width * ratio, height * ratio);
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height) {
if (transform.resize(width, height, ratio, fb_width, fb_height)) {
update();
@@ -493,7 +461,6 @@ void Map::resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width
#pragma mark - Transitions
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::cancelTransitions() {
transform.cancelTransitions();
@@ -503,36 +470,30 @@ void Map::cancelTransitions() {
#pragma mark - Position
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::moveBy(double dx, double dy, double duration) {
transform.moveBy(dx, dy, duration * 1_second);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::setLonLat(double lon, double lat, double duration) {
transform.setLonLat(lon, lat, duration * 1_second);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::getLonLat(double& lon, double& lat) const {
transform.getLonLat(lon, lat);
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::startPanning() {
transform.startPanning();
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::stopPanning() {
transform.stopPanning();
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::resetPosition() {
transform.setAngle(0);
transform.setLonLat(0, 0);
@@ -543,57 +504,47 @@ void Map::resetPosition() {
#pragma mark - Scale
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::scaleBy(double ds, double cx, double cy, double duration) {
transform.scaleBy(ds, cx, cy, duration * 1_second);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::setScale(double scale, double cx, double cy, double duration) {
transform.setScale(scale, cx, cy, duration * 1_second);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
double Map::getScale() const {
return transform.getScale();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::setZoom(double zoom, double duration) {
transform.setZoom(zoom, duration * 1_second);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
double Map::getZoom() const {
return transform.getZoom();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::setLonLatZoom(double lon, double lat, double zoom, double duration) {
transform.setLonLatZoom(lon, lat, zoom, duration * 1_second);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::getLonLatZoom(double& lon, double& lat, double& zoom) const {
transform.getLonLatZoom(lon, lat, zoom);
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::resetZoom() {
setZoom(0);
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::startScaling() {
transform.startScaling();
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::stopScaling() {
transform.stopScaling();
update();
@@ -610,42 +561,35 @@ double Map::getMaxZoom() const {
#pragma mark - Rotation
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::rotateBy(double sx, double sy, double ex, double ey, double duration) {
transform.rotateBy(sx, sy, ex, ey, duration * 1_second);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::setBearing(double degrees, double duration) {
transform.setAngle(-degrees * M_PI / 180, duration * 1_second);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::setBearing(double degrees, double cx, double cy) {
transform.setAngle(-degrees * M_PI / 180, cx, cy);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
double Map::getBearing() const {
return -transform.getAngle() / M_PI * 180;
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::resetNorth() {
transform.setAngle(0, 500_milliseconds);
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::startRotating() {
transform.startRotating();
update();
}
-// Note: This function is called from another thread. Make sure you only call threadsafe functions!
void Map::stopRotating() {
transform.stopRotating();
update();
@@ -709,7 +653,7 @@ void Map::updateSources() {
assert(uv_thread_self() == map_thread);
// First, disable all existing sources.
- for (const util::ptr<StyleSource> &source : activeSources) {
+ for (const auto& source : activeSources) {
source->enabled = false;
}
@@ -717,7 +661,7 @@ void Map::updateSources() {
updateSources(style->layers);
// Then, construct or destroy the actual source object, depending on enabled state.
- for (const util::ptr<StyleSource> &style_source : activeSources) {
+ for (const auto& style_source : activeSources) {
if (style_source->enabled) {
if (!style_source->source) {
style_source->source = std::make_shared<Source>(style_source->info);
@@ -734,10 +678,6 @@ void Map::updateSources() {
});
}
-const std::set<util::ptr<StyleSource>> Map::getActiveSources() const {
- return activeSources;
-}
-
void Map::updateSources(const util::ptr<StyleLayerGroup> &group) {
if (!group) {
return;
@@ -755,8 +695,11 @@ void Map::updateSources(const util::ptr<StyleLayerGroup> &group) {
}
void Map::updateTiles() {
- for (const util::ptr<StyleSource> &source : getActiveSources()) {
- source->source->update(*this, *fileSource);
+ for (const auto& source : activeSources) {
+ source->source->update(*this, getWorker(),
+ style, glyphAtlas, *glyphStore,
+ spriteAtlas, getSprite(),
+ *texturepool, *fileSource, [this](){ update(); });
}
}
diff --git a/src/map/raster_tile_data.cpp b/src/map/raster_tile_data.cpp
index 1552e359bd..8b29fedcd8 100644
--- a/src/map/raster_tile_data.cpp
+++ b/src/map/raster_tile_data.cpp
@@ -5,9 +5,9 @@
using namespace mbgl;
-RasterTileData::RasterTileData(Tile::ID const& id_, Map &map_, const util::ptr<SourceInfo> &source_)
- : TileData(id_, map_, source_),
- bucket(map.getTexturepool(), properties) {
+RasterTileData::RasterTileData(Tile::ID const& id_, Texturepool& texturepool, const SourceInfo& source_)
+ : TileData(id_, source_),
+ bucket(texturepool, properties) {
}
RasterTileData::~RasterTileData() {
diff --git a/src/map/source.cpp b/src/map/source.cpp
index 957afd6fd3..6523ea5d62 100644
--- a/src/map/source.cpp
+++ b/src/map/source.cpp
@@ -22,7 +22,7 @@
namespace mbgl {
-Source::Source(const util::ptr<SourceInfo>& info_)
+Source::Source(SourceInfo& info_)
: info(info_)
{
}
@@ -31,12 +31,12 @@ Source::Source(const util::ptr<SourceInfo>& info_)
// The reason this isn't part of the constructor is that calling shared_from_this() in
// the constructor fails.
void Source::load(Map& map, FileSource& fileSource) {
- if (info->url.empty()) {
+ if (info.url.empty()) {
loaded = true;
return;
}
- std::string url = util::mapbox::normalizeSourceURL(info->url, map.getAccessToken());
+ std::string url = util::mapbox::normalizeSourceURL(info.url, map.getAccessToken());
util::ptr<Source> source = shared_from_this();
fileSource.request(ResourceType::JSON, url)->onload([source, &map](const Response &res) {
@@ -53,7 +53,7 @@ void Source::load(Map& map, FileSource& fileSource) {
return;
}
- source->info->parseTileJSONProperties(d);
+ source->info.parseTileJSONProperties(d);
source->loaded = true;
map.update();
@@ -61,14 +61,6 @@ void Source::load(Map& map, FileSource& fileSource) {
});
}
-bool Source::update(Map& map, FileSource& fileSource) {
- if (loaded && map.getTime() > updated) {
- return updateTiles(map, fileSource);
- } else {
- return false;
- }
-}
-
void Source::updateClipIDs(const std::map<Tile::ID, ClipID> &mapping) {
std::for_each(tiles.begin(), tiles.end(), [&mapping](std::pair<const Tile::ID, std::unique_ptr<Tile>> &pair) {
Tile &tile = *pair.second;
@@ -159,7 +151,13 @@ TileData::State Source::hasTile(const Tile::ID& id) {
return TileData::State::invalid;
}
-TileData::State Source::addTile(Map& map, FileSource& fileSource, const Tile::ID& id) {
+TileData::State Source::addTile(Map& map, uv::worker& worker,
+ util::ptr<Style> style,
+ GlyphAtlas& glyphAtlas, GlyphStore& glyphStore,
+ SpriteAtlas& spriteAtlas, util::ptr<Sprite> sprite,
+ FileSource& fileSource, Texturepool& texturepool,
+ const Tile::ID& id,
+ std::function<void ()> callback) {
const TileData::State state = hasTile(id);
if (state != TileData::State::invalid) {
@@ -186,15 +184,18 @@ TileData::State Source::addTile(Map& map, FileSource& fileSource, const Tile::ID
if (!new_tile.data) {
// If we don't find working tile data, we're just going to load it.
- if (info->type == SourceType::Vector) {
- new_tile.data = std::make_shared<VectorTileData>(normalized_id, map, info);
- } else if (info->type == SourceType::Raster) {
- new_tile.data = std::make_shared<RasterTileData>(normalized_id, map, info);
+ if (info.type == SourceType::Vector) {
+ new_tile.data = std::make_shared<VectorTileData>(normalized_id, map.getMaxZoom(), style,
+ glyphAtlas, glyphStore,
+ spriteAtlas, sprite,
+ texturepool, info);
+ } else if (info.type == SourceType::Raster) {
+ new_tile.data = std::make_shared<RasterTileData>(normalized_id, texturepool, info);
} else {
throw std::runtime_error("source type not implemented");
}
- new_tile.data->request(fileSource);
+ new_tile.data->request(worker, fileSource, map.getState().getPixelRatio(), callback);
tile_data.emplace(new_tile.data->id, new_tile.data);
}
@@ -202,7 +203,7 @@ TileData::State Source::addTile(Map& map, FileSource& fileSource, const Tile::ID
}
double Source::getZoom(const TransformState& state) const {
- double offset = std::log(util::tileSize / info->tile_size) / std::log(2);
+ double offset = std::log(util::tileSize / info.tile_size) / std::log(2);
offset += (state.getPixelRatio() > 1.0 ? 1 :0);
return state.getZoom() + offset;
}
@@ -214,8 +215,8 @@ int32_t Source::coveringZoomLevel(const TransformState& state) const {
std::forward_list<Tile::ID> Source::coveringTiles(const TransformState& state) const {
int32_t z = coveringZoomLevel(state);
- if (z < info->min_zoom) return {{}};
- if (z > info->max_zoom) z = info->max_zoom;
+ if (z < info.min_zoom) return {{}};
+ if (z > info.max_zoom) z = info.max_zoom;
// Map four viewport corners to pixel coordinates
box points = state.cornersToBox(z);
@@ -281,15 +282,23 @@ bool Source::findLoadedParent(const Tile::ID& id, int32_t minCoveringZoom, std::
return false;
}
-bool Source::updateTiles(Map& map, FileSource& fileSource) {
+void Source::update(Map& map, uv::worker& worker,
+ util::ptr<Style> style,
+ GlyphAtlas& glyphAtlas, GlyphStore& glyphStore,
+ SpriteAtlas& spriteAtlas, util::ptr<Sprite> sprite,
+ Texturepool& texturepool, FileSource& fileSource,
+ std::function<void ()> callback) {
+ if (!loaded || map.getTime() <= updated)
+ return;
+
bool changed = false;
int32_t zoom = std::floor(getZoom(map.getState()));
std::forward_list<Tile::ID> required = coveringTiles(map.getState());
// Determine the overzooming/underzooming amounts.
- int32_t minCoveringZoom = util::clamp<int32_t>(zoom - 10, info->min_zoom, info->max_zoom);
- int32_t maxCoveringZoom = util::clamp<int32_t>(zoom + 1, info->min_zoom, info->max_zoom);
+ int32_t minCoveringZoom = util::clamp<int32_t>(zoom - 10, info.min_zoom, info.max_zoom);
+ int32_t maxCoveringZoom = util::clamp<int32_t>(zoom + 1, info.min_zoom, info.max_zoom);
// Retain is a list of tiles that we shouldn't delete, even if they are not
// the most ideal tile for the current viewport. This may include tiles like
@@ -298,7 +307,11 @@ bool Source::updateTiles(Map& map, FileSource& fileSource) {
// Add existing child/parent tiles if the actual tile is not yet loaded
for (const Tile::ID& id : required) {
- const TileData::State state = addTile(map, fileSource, id);
+ const TileData::State state = addTile(map, worker, style,
+ glyphAtlas, glyphStore,
+ spriteAtlas, sprite,
+ fileSource, texturepool,
+ id, callback);
if (state != TileData::State::parsed) {
// The tile we require is not yet loaded. Try to find a parent or
@@ -351,8 +364,6 @@ bool Source::updateTiles(Map& map, FileSource& fileSource) {
});
updated = map.getTime();
-
- return changed;
}
}
diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp
index 9ff694bf3a..c1354d490b 100644
--- a/src/map/tile_data.cpp
+++ b/src/map/tile_data.cpp
@@ -9,10 +9,9 @@
using namespace mbgl;
-TileData::TileData(Tile::ID const& id_, Map &map_, const util::ptr<SourceInfo> &source_)
+TileData::TileData(Tile::ID const& id_, const SourceInfo& source_)
: id(id_),
state(State::initial),
- map(map_),
source(source_),
debugBucket(debugFontBuffer) {
// Initialize tile debug coordinates
@@ -28,16 +27,23 @@ const std::string TileData::toString() const {
return util::sprintf<32>("[tile %d/%d/%d]", id.z, id.x, id.y);
}
-void TileData::request(FileSource& fileSource) {
- if (source->tiles.empty())
+void TileData::request(uv::worker& worker, FileSource& fileSource,
+ float pixelRatio, std::function<void ()> callback) {
+ if (source.tiles.empty())
return;
- std::string url = source->tiles[(id.x + id.y) % source->tiles.size()];
+ std::string url = source.tiles[(id.x + id.y) % source.tiles.size()];
url = util::replaceTokens(url, [&](const std::string &token) -> std::string {
if (token == "z") return std::to_string(id.z);
if (token == "x") return std::to_string(id.x);
if (token == "y") return std::to_string(id.y);
- if (token == "ratio") return (map.getState().getPixelRatio() > 1.0 ? "@2x" : "");
+ if (token == "prefix") {
+ std::string prefix { 2 };
+ prefix[0] = "0123456789abcdef"[id.x % 16];
+ prefix[1] = "0123456789abcdef"[id.y % 16];
+ return prefix;
+ }
+ if (token == "ratio") return pixelRatio > 1.0 ? "@2x" : "";
return "";
});
@@ -46,7 +52,7 @@ void TileData::request(FileSource& fileSource) {
// Note: Somehow this feels slower than the change to request_http()
std::weak_ptr<TileData> weak_tile = shared_from_this();
req = fileSource.request(ResourceType::Tile, url);
- req->onload([weak_tile, url](const Response &res) {
+ req->onload([weak_tile, url, callback, &worker](const Response &res) {
util::ptr<TileData> tile = weak_tile.lock();
if (!tile || tile->state == State::obsolete) {
// noop. Tile is obsolete and we're now just waiting for the refcount
@@ -63,7 +69,7 @@ void TileData::request(FileSource& fileSource) {
tile->data = res.data;
// Schedule tile parsing in another thread
- tile->reparse();
+ tile->reparse(worker, callback);
} else {
#if defined(DEBUG)
fprintf(stderr, "[%s] tile loading failed: %ld, %s\n", url.c_str(), res.code, res.message.c_str());
@@ -82,17 +88,17 @@ void TileData::cancel() {
}
}
-void TileData::reparse()
+void TileData::reparse(uv::worker& worker, std::function<void()> callback)
{
// We're creating a new work request. The work request deletes itself after it executed
// the after work handler
new uv::work<util::ptr<TileData>>(
- map.getWorker(),
- [](util::ptr<TileData> &tile) {
+ worker,
+ [](util::ptr<TileData>& tile) {
tile->parse();
},
- [](util::ptr<TileData> &tile) {
- tile->map.update();
+ [callback](util::ptr<TileData>&) {
+ callback();
},
shared_from_this());
}
diff --git a/src/map/tile_parser.cpp b/src/map/tile_parser.cpp
index e707cde620..4e9c320e36 100644
--- a/src/map/tile_parser.cpp
+++ b/src/map/tile_parser.cpp
@@ -32,9 +32,10 @@ TileParser::~TileParser() = default;
TileParser::TileParser(const std::string &data, VectorTileData &tile_,
const util::ptr<const Style> &style_,
GlyphAtlas & glyphAtlas_,
- const util::ptr<GlyphStore> &glyphStore_,
+ GlyphStore & glyphStore_,
SpriteAtlas & spriteAtlas_,
- const util::ptr<Sprite> &sprite_)
+ const util::ptr<Sprite> &sprite_,
+ Texturepool& texturePool_)
: vector_data(pbf((const uint8_t *)data.data(), data.size())),
tile(tile_),
style(style_),
@@ -42,10 +43,10 @@ TileParser::TileParser(const std::string &data, VectorTileData &tile_,
glyphStore(glyphStore_),
spriteAtlas(spriteAtlas_),
sprite(sprite_),
- collision(std::make_unique<Collision>(tile.id.z, 4096, tile.source->tile_size, tile.depth)) {
+ texturePool(texturePool_),
+ collision(std::make_unique<Collision>(tile.id.z, 4096, tile.source.tile_size, tile.depth)) {
assert(&tile != nullptr);
assert(style);
- assert(glyphStore);
assert(sprite);
assert(collision);
}
@@ -100,7 +101,7 @@ std::unique_ptr<Bucket> TileParser::createBucket(util::ptr<StyleBucket> bucket_d
}
// Skip this bucket if we are to not render this
- if (tile.id.z < std::floor(bucket_desc->min_zoom) && std::floor(bucket_desc->min_zoom) < tile.source->max_zoom) return nullptr;
+ if (tile.id.z < std::floor(bucket_desc->min_zoom) && std::floor(bucket_desc->min_zoom) < tile.source.max_zoom) return nullptr;
if (tile.id.z >= std::ceil(bucket_desc->max_zoom)) return nullptr;
auto layer_it = vector_data.layers.find(bucket_desc->source_layer);
@@ -154,7 +155,7 @@ std::unique_ptr<Bucket> TileParser::createFillBucket(const VectorTileLayer& laye
return obsolete() ? nullptr : std::move(bucket);
}
-std::unique_ptr<Bucket> TileParser::createRasterBucket(const util::ptr<Texturepool> &texturepool, const StyleBucketRaster &raster) {
+std::unique_ptr<Bucket> TileParser::createRasterBucket(Texturepool& texturepool, const StyleBucketRaster &raster) {
std::unique_ptr<RasterBucket> bucket = std::make_unique<RasterBucket>(texturepool, raster);
return obsolete() ? nullptr : std::move(bucket);
}
@@ -167,7 +168,7 @@ std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer& laye
std::unique_ptr<Bucket> TileParser::createSymbolBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketSymbol &symbol) {
std::unique_ptr<SymbolBucket> bucket = std::make_unique<SymbolBucket>(symbol, *collision);
- bucket->addFeatures(layer, filter, tile.id, spriteAtlas, *sprite, glyphAtlas, *glyphStore);
+ bucket->addFeatures(layer, filter, tile.id, spriteAtlas, *sprite, glyphAtlas, glyphStore);
return obsolete() ? nullptr : std::move(bucket);
}
diff --git a/src/map/vector_tile_data.cpp b/src/map/vector_tile_data.cpp
index 133d23efa8..1237e3546b 100644
--- a/src/map/vector_tile_data.cpp
+++ b/src/map/vector_tile_data.cpp
@@ -8,13 +8,24 @@
using namespace mbgl;
-VectorTileData::VectorTileData(Tile::ID const& id_, Map &map_, const util::ptr<SourceInfo> &source_)
- : TileData(id_, map_, source_),
- depth(id.z >= source->max_zoom ? map.getMaxZoom() - id.z : 1) {
+VectorTileData::VectorTileData(Tile::ID const& id_,
+ float mapMaxZoom, util::ptr<Style> style_,
+ GlyphAtlas& glyphAtlas_, GlyphStore& glyphStore_,
+ SpriteAtlas& spriteAtlas_, util::ptr<Sprite> sprite_,
+ Texturepool& texturepool_,
+ const SourceInfo& source_)
+ : TileData(id_, source_),
+ glyphAtlas(glyphAtlas_),
+ glyphStore(glyphStore_),
+ spriteAtlas(spriteAtlas_),
+ sprite(sprite_),
+ texturepool(texturepool_),
+ style(style_),
+ depth(id.z >= source.max_zoom ? mapMaxZoom - id.z : 1) {
}
VectorTileData::~VectorTileData() {
- map.getGlyphAtlas().removeGlyphs(id.to_uint64());
+ glyphAtlas.removeGlyphs(id.to_uint64());
}
@@ -27,8 +38,10 @@ void VectorTileData::parse() {
// Parsing creates state that is encapsulated in TileParser. While parsing,
// the TileParser object writes results into this objects. All other state
// is going to be discarded afterwards.
- TileParser parser(data, *this, map.getStyle(), map.getGlyphAtlas(),
- map.getGlyphStore(), map.getSpriteAtlas(), map.getSprite());
+ TileParser parser(data, *this, style,
+ glyphAtlas, glyphStore,
+ spriteAtlas, sprite,
+ texturepool);
parser.parse();
} catch (const std::exception& ex) {
#if defined(DEBUG)
diff --git a/src/renderer/raster_bucket.cpp b/src/renderer/raster_bucket.cpp
index 7adb3f845e..12b2b9e514 100644
--- a/src/renderer/raster_bucket.cpp
+++ b/src/renderer/raster_bucket.cpp
@@ -3,7 +3,7 @@
using namespace mbgl;
-RasterBucket::RasterBucket(const util::ptr<Texturepool> &texturepool, const StyleBucketRaster& properties_)
+RasterBucket::RasterBucket(Texturepool& texturepool, const StyleBucketRaster& properties_)
: properties(properties_),
texture(properties_),
raster(texturepool) {
diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp
index fa51e48cee..22d43df443 100644
--- a/src/style/style_parser.cpp
+++ b/src/style/style_parser.cpp
@@ -178,14 +178,12 @@ void StyleParser::parseSources(JSVal value) {
rapidjson::Value::ConstMemberIterator itr = value.MemberBegin();
for (; itr != value.MemberEnd(); ++itr) {
std::string name { itr->name.GetString(), itr->name.GetStringLength() };
- util::ptr<SourceInfo> info = std::make_shared<SourceInfo>();
+ SourceInfo& info = sources.emplace(name, std::make_shared<StyleSource>()).first->second->info;
- parseRenderProperty<SourceTypeClass>(itr->value, info->type, "type");
- parseRenderProperty(itr->value, info->url, "url");
- parseRenderProperty(itr->value, info->tile_size, "tileSize");
- info->parseTileJSONProperties(itr->value);
-
- sources.emplace(std::move(name), std::make_shared<StyleSource>(info));
+ parseRenderProperty<SourceTypeClass>(itr->value, info.type, "type");
+ parseRenderProperty(itr->value, info.url, "url");
+ parseRenderProperty(itr->value, info.tile_size, "tileSize");
+ info.parseTileJSONProperties(itr->value);
}
} else {
Log::Warning(Event::ParseStyle, "sources must be an object");
diff --git a/src/util/raster.cpp b/src/util/raster.cpp
index 76cd411223..4f6acc36cf 100644
--- a/src/util/raster.cpp
+++ b/src/util/raster.cpp
@@ -11,13 +11,13 @@
using namespace mbgl;
-Raster::Raster(const util::ptr<Texturepool> &texturepool_)
+Raster::Raster(Texturepool& texturepool_)
: texturepool(texturepool_)
{}
Raster::~Raster() {
if (textured) {
- texturepool->removeTextureID(texture);
+ texturepool.removeTextureID(texture);
}
}
@@ -46,7 +46,7 @@ void Raster::bind(bool linear) {
}
if (img && !textured) {
- texture = texturepool->getTextureID();
+ texture = texturepool.getTextureID();
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
diff --git a/src/util/uv.cpp b/src/util/uv.cpp
index 03a885d308..7aa5bad0cf 100644
--- a/src/util/uv.cpp
+++ b/src/util/uv.cpp
@@ -22,16 +22,4 @@ std::string cwd() {
#endif
}
-void deleter::operator()(uv_async_t *async) {
- uv_close((uv_handle_t *)async, [](uv_handle_t *handle) {
- delete (uv_async_t *)handle;
- });
-}
-
-void deleter::operator()(uv_timer_t *timer) {
- uv_close((uv_handle_t *)timer, [](uv_handle_t *handle) {
- delete (uv_timer_t *)handle;
- });
-}
-
}