diff options
author | Leith Bade <leith@mapbox.com> | 2014-11-28 01:37:35 +1100 |
---|---|---|
committer | Leith Bade <leith@mapbox.com> | 2014-11-28 01:51:21 +1100 |
commit | 8ae2cd3985e959e622f90d30a017032f9a5ca37c (patch) | |
tree | eb9ea52a6a9005259c6124991e8dd7d0f7d97e5e /src | |
parent | 014ebd2f133c883eec652b7ea598acc71924a217 (diff) | |
parent | 79017060947c1a11f4124ab837bd171b748806de (diff) | |
download | qtlocation-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.cpp | 10 | ||||
-rw-r--r-- | src/map/map.cpp | 157 | ||||
-rw-r--r-- | src/map/raster_tile_data.cpp | 6 | ||||
-rw-r--r-- | src/map/source.cpp | 65 | ||||
-rw-r--r-- | src/map/tile_data.cpp | 32 | ||||
-rw-r--r-- | src/map/tile_parser.cpp | 15 | ||||
-rw-r--r-- | src/map/vector_tile_data.cpp | 25 | ||||
-rw-r--r-- | src/renderer/raster_bucket.cpp | 2 | ||||
-rw-r--r-- | src/style/style_parser.cpp | 12 | ||||
-rw-r--r-- | src/util/raster.cpp | 6 | ||||
-rw-r--r-- | src/util/uv.cpp | 12 |
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; - }); -} - } |