Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Tile loading blocks map view updates but not user dot #1455

Closed
1ec5 opened this issue May 7, 2015 · 15 comments
Closed

Tile loading blocks map view updates but not user dot #1455

1ec5 opened this issue May 7, 2015 · 15 comments
Labels
iOS Mapbox Maps SDK for iOS performance Speed, stability, CPU usage, memory usage, or power usage
Milestone

Comments

@1ec5
Copy link
Contributor

1ec5 commented May 7, 2015

Sometime in the last day or two (maybe due to #1326?), I’ve started noticing that MGLMapView often hangs while parsing tiles (as opposed to waiting for them to come over the network). All the while, the user dot happily moves around in response to gestures, so it appears to glide around the map. Eventually the map catches up, but the result is very disorienting.

glide

Hopefully the hanging is captured elsewhere, but we should also attempt to keep the user dot from moving if the map is unable to rerender.

/cc @incanus @jfirebaugh @kkaefer

@1ec5 1ec5 added iOS Mapbox Maps SDK for iOS performance Speed, stability, CPU usage, memory usage, or power usage labels May 7, 2015
@incanus
Copy link
Contributor

incanus commented May 7, 2015

Currently, since we call _mbglMap->renderSync() and that returns void, we can't tell if the frame render was successful, else we could bail or set a flag to disallow the user dot to update on the next -updateUserLocationAnnotationView.

@jfirebaugh
Copy link
Contributor

Can you capture a set of stack traces when this occurs?

@1ec5
Copy link
Contributor Author

1ec5 commented May 7, 2015

Not sure what stack traces to provide, since the app doesn’t actually hang. (Should’ve said “stalled” or something above.) I can say for sure that Source::emitTileLoaded() and TileData::endParsing() only get called once the map starts drawing again, but not while I’m dragging the user dot around.

@1ec5
Copy link
Contributor Author

1ec5 commented May 7, 2015

Bisect implicates 5c7867f (#1412), and #1326 didn’t address the issue.

@1ec5 1ec5 added this to the iOS Beta 1 milestone May 7, 2015
@1ec5
Copy link
Contributor Author

1ec5 commented May 7, 2015

Placing on beta 1 milestone because it’s so easy to get either a free-floating user dot or (with a hidden user dot) what looks like a hung app. Steps to reproduce:

  1. Set simulator simulated location to San Francisco, CA, USA.
  2. Turn on user location tracking.
  3. Pinch broadly outward to zoom in.
  4. Pan around the entire screen for a few seconds.

(Edit: Step 1 is to set the simulated location in Xcode, but to be clear, this is running on the device, where tile loading is much, much slower than in the Simulator.)

@jfirebaugh
Copy link
Contributor

Not sure what stack traces to provide, since the app doesn’t actually hang.

When it happens, hit the pause button in the debugger. I would expect to see the map thread blocked on something or doing heavy work -- the question is what.

@1ec5
Copy link
Contributor Author

1ec5 commented May 7, 2015

Map (14)#0  0x000000019873f078 in __psynch_cvwait ()
#1  0x00000001987daf2c in _pthread_cond_wait ()
#2  0x0000000197724cb0 in std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) ()
#3  0x00000001977257f8 in std::__1::__assoc_sub_state::__sub_wait(std::__1::unique_lock<std::__1::mutex>&) ()
#4  0x0000000197725720 in std::__1::__assoc_sub_state::copy() ()
#5  0x0000000197725a14 in std::__1::future<void>::get() ()
#6  0x0000000100378544 in mbgl::WorkRequest::join() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/util/work_request.cpp:35
#7  0x00000001001a1984 in mbgl::TileData::cancel() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_data.cpp:60
#8  0x00000001001e16a8 in mbgl::VectorTileData::~VectorTileData() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/vector_tile_data.cpp:33
#9  0x00000001001e1868 in mbgl::VectorTileData::~VectorTileData() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/vector_tile_data.cpp:30
#10 0x000000010018dfcc in std::__1::__shared_ptr_emplace<mbgl::VectorTileData, std::__1::allocator<mbgl::VectorTileData> >::__on_zero_shared() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:3738
#11 0x0000000197759764 in std::__1::__shared_weak_count::__release_shared() ()
#12 0x0000000100192ef8 in std::__1::shared_ptr<mbgl::TileData>::~shared_ptr() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4448
#13 0x0000000100193260 in mbgl::util::ptr<mbgl::TileData>::~ptr() at /Users/mxn/hub/mapbox-gl-native/include/mbgl/util/ptr.hpp:11
#14 0x0000000100184650 in mbgl::util::ptr<mbgl::TileData>::~ptr() at /Users/mxn/hub/mapbox-gl-native/include/mbgl/util/ptr.hpp:11
#15 0x000000010018eeb4 in mbgl::Tile::~Tile() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile.hpp:15
#16 0x000000010018ee4c in mbgl::Tile::~Tile() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile.hpp:15
#17 0x00000001001880a4 in std::__1::default_delete<mbgl::Tile>::operator()(mbgl::Tile*) const [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2431
#18 0x0000000100188090 in std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> >::reset(mbgl::Tile*) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2630
#19 0x000000010018802c in std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> >::~unique_ptr() [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2598
#20 0x0000000100188020 in std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> >::~unique_ptr() [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2598
#21 0x0000000100188018 in std::__1::pair<mbgl::TileID const, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >::~pair() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/utility:248
#22 0x0000000100187fb0 in std::__1::pair<mbgl::TileID const, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >::~pair() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/utility:248
#23 0x0000000100187ef8 in std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >::~__value_type() [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/map:617
#24 0x0000000100187ef0 in std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >::~__value_type() [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/map:617
#25 0x0000000100187ee8 in void std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, void*> > >::__destroy<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > > >(std::__1::integral_constant<bool, false>, std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, void*> >&, std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >*) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1589
#26 0x0000000100187edc in void std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, void*> > >::destroy<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > > >(std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, void*> >&, std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >*) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1487
#27 0x0000000100187ecc in std::__1::__tree<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, std::__1::__map_value_compare<mbgl::TileID, std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, std::__1::less<mbgl::TileID>, true>, std::__1::allocator<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > > > >::erase(std::__1::__tree_const_iterator<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, std::__1::__tree_node<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, void*>*, long>) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tree:1985
#28 0x0000000100180974 in std::__1::map<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> >, std::__1::less<mbgl::TileID>, std::__1::allocator<std::__1::pair<mbgl::TileID const, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > > > >::erase(std::__1::__map_const_iterator<std::__1::__tree_const_iterator<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, std::__1::__tree_node<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, void*>*, long> >) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/map:1074
#29 0x0000000100180964 in void mbgl::util::erase_if<std::__1::map<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> >, std::__1::less<mbgl::TileID>, std::__1::allocator<std::__1::pair<mbgl::TileID const, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > > > >, std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, std::__1::__tree_node<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, void*>*, long> >, mbgl::Source::update(mbgl::MapData&, mbgl::TransformState const&, mbgl::Style&, mbgl::GlyphAtlas&, mbgl::GlyphStore&, mbgl::SpriteAtlas&, mbgl::util::ptr<mbgl::Sprite>, mbgl::TexturePool&)::$_3>(std::__1::map<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> >, std::__1::less<mbgl::TileID>, std::__1::allocator<std::__1::pair<mbgl::TileID const, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > > > >&, std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, std::__1::__tree_node<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, void*>*, long> >, std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, std::__1::__tree_node<std::__1::__value_type<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > >, void*>*, long> >, mbgl::Source::update(mbgl::MapData&, mbgl::TransformState const&, mbgl::Style&, mbgl::GlyphAtlas&, mbgl::GlyphStore&, mbgl::SpriteAtlas&, mbgl::util::ptr<mbgl::Sprite>, mbgl::TexturePool&)::$_3) at /Users/mxn/hub/mapbox-gl-native/include/mbgl/util/std.hpp:38
#30 0x000000010017f818 in void mbgl::util::erase_if<std::__1::map<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> >, std::__1::less<mbgl::TileID>, std::__1::allocator<std::__1::pair<mbgl::TileID const, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > > > >, mbgl::Source::update(mbgl::MapData&, mbgl::TransformState const&, mbgl::Style&, mbgl::GlyphAtlas&, mbgl::GlyphStore&, mbgl::SpriteAtlas&, mbgl::util::ptr<mbgl::Sprite>, mbgl::TexturePool&)::$_3>(std::__1::map<mbgl::TileID, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> >, std::__1::less<mbgl::TileID>, std::__1::allocator<std::__1::pair<mbgl::TileID const, std::__1::unique_ptr<mbgl::Tile, std::__1::default_delete<mbgl::Tile> > > > >&, mbgl::Source::update(mbgl::MapData&, mbgl::TransformState const&, mbgl::Style&, mbgl::GlyphAtlas&, mbgl::GlyphStore&, mbgl::SpriteAtlas&, mbgl::util::ptr<mbgl::Sprite>, mbgl::TexturePool&)::$_3) at /Users/mxn/hub/mapbox-gl-native/include/mbgl/util/std.hpp:47
#31 0x000000010017f590 in mbgl::Source::update(mbgl::MapData&, mbgl::TransformState const&, mbgl::Style&, mbgl::GlyphAtlas&, mbgl::GlyphStore&, mbgl::SpriteAtlas&, mbgl::util::ptr<mbgl::Sprite>, mbgl::TexturePool&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/source.cpp:451
#32 0x0000000100178580 in mbgl::ResourceLoader::update(mbgl::MapData&, mbgl::TransformState const&, mbgl::GlyphAtlas&, mbgl::GlyphStore&, mbgl::SpriteAtlas&, mbgl::TexturePool&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/resource_loader.cpp:72
#33 0x0000000100169584 in mbgl::MapContext::updateTiles() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/map_context.cpp:152
#34 0x0000000100169b00 in mbgl::MapContext::update() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/map_context.cpp:195
#35 0x0000000100170324 in mbgl::MapContext::MapContext(uv_loop_s*, mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool)::$_5::operator()() const at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/map_context.cpp:38
#36 0x0000000100170120 in std::__1::__invoke<mbgl::MapContext::MapContext(uv_loop_s*, mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool)::$_5&>(decltype(std::__1::forward<mbgl::MapContext::MapContext(uv_loop_s*, mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool)::$_5&>(fp)(std::__1::forward<>(fp0))), mbgl::MapContext::MapContext(uv_loop_s*, mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool)::$_5&&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_base:413
#37 0x000000010017010c in std::__1::__function::__func<mbgl::MapContext::MapContext(uv_loop_s*, mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool)::$_5, std::__1::allocator<mbgl::MapContext::MapContext(uv_loop_s*, mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool)::$_5>, void ()>::operator()() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1370
#38 0x0000000100173e2c in std::__1::function<void ()>::operator()() const at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1756
#39 0x0000000100173d54 in uv::async::async_cb(uv_async_s*, int) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/util/uv_detail.hpp:120
#40 0x00000001003f1ad8 in uv__async_event at /Users/mxn/hub/mapbox-gl-native/mason_packages/.build/libuv-0.10.28/src/unix/async.c:80
#41 0x00000001003f1e90 in uv__async_io at /Users/mxn/hub/mapbox-gl-native/mason_packages/.build/libuv-0.10.28/src/unix/async.c:156
#42 0x000000010040b49c in uv__io_poll at /Users/mxn/hub/mapbox-gl-native/mason_packages/.build/libuv-0.10.28/src/unix/kqueue.c:233
#43 0x00000001003f253c in uv_run at /Users/mxn/hub/mapbox-gl-native/mason_packages/.build/libuv-0.10.28/src/unix/core.c:317
#44 0x00000001003ef234 in uv::loop::run() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/util/uv_detail.hpp:55
#45 0x0000000100145c90 in void mbgl::util::Thread<mbgl::MapContext>::run<std::__1::tuple<mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool&>, 0ul, 1ul, 2ul, 3ul>(std::__1::tuple<mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool&>&&, (anonymous namespace)::index_sequence<0ul, 1ul, 2ul, 3ul>) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/util/thread.hpp:142
#46 0x0000000100164c48 in mbgl::util::Thread<mbgl::MapContext>::Thread<mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, mbgl::util::ThreadPriority, mbgl::View&&&, mbgl::FileSource&&&, mbgl::MapData&&&, bool&&&)::'lambda'()::operator()() const at /Users/mxn/hub/mapbox-gl-native/src/mbgl/util/thread.hpp:123
#47 0x0000000100164960 in std::__1::__invoke<mbgl::util::Thread<mbgl::MapContext>::Thread<mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, mbgl::util::ThreadPriority, mbgl::View&&&, mbgl::FileSource&&&, mbgl::MapData&&&, bool&&&)::'lambda'()>(decltype(std::__1::forward<mbgl::util::Thread<mbgl::MapContext>::Thread<mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, mbgl::util::ThreadPriority, mbgl::View&&&, mbgl::FileSource&&&, mbgl::MapData&&&, bool&&&)::'lambda'()>(fp)(std::__1::forward<>(fp0))), mbgl::util::Thread<mbgl::MapContext>::Thread<mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, mbgl::util::ThreadPriority, mbgl::View&&&, mbgl::FileSource&&&, mbgl::MapData&&&, bool&&&)::'lambda'()&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_base:413
#48 0x0000000100164954 in _ZNSt3__116__thread_executeIZN4mbgl4util6ThreadINS1_10MapContextEEC1IJRNS1_4ViewERNS1_10FileSourceERNS1_7MapDataERbEEERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS2_14ThreadPriorityEDpOT_EUlvE_JEJEEEvRNS_5tupleIJT_DpT0_EEENS_15__tuple_indicesIJXspT1_EEEE [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:332
#49 0x0000000100164944 in std::__1::__thread_proxy<std::__1::tuple<mbgl::util::Thread<mbgl::MapContext>::Thread<mbgl::View&, mbgl::FileSource&, mbgl::MapData&, bool&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, mbgl::util::ThreadPriority, mbgl::View&&&, mbgl::FileSource&&&, mbgl::MapData&&&, bool&&&)::'lambda'()> >(void*, void*) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:342
#50 0x00000001987dbdc8 in _pthread_body ()
#51 0x00000001987dbd24 in _pthread_start ()

Two Worker threads appear to be busy:

Worker (23)#0   0x00000001000ba5d4 in ClipperLib::ClipperBase::AddPath(std::__1::vector<ClipperLib::IntPoint, std::__1::allocator<ClipperLib::IntPoint> > const&, ClipperLib::PolyType, bool) at /Users/mxn/hub/mapbox-gl-native/src/clipper/clipper.cpp:1266
#1  0x00000001001ee208 in mbgl::FillBucket::addGeometry(std::__1::vector<std::__1::vector<mbgl::vec2<short>, std::__1::allocator<mbgl::vec2<short> > >, std::__1::allocator<std::__1::vector<mbgl::vec2<short>, std::__1::allocator<mbgl::vec2<short> > > > > const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/renderer/fill_bucket.cpp:76
#2  0x00000001001aa7fc in void mbgl::TileParser::addBucketGeometries<std::__1::unique_ptr<mbgl::FillBucket, std::__1::default_delete<mbgl::FillBucket> > >(std::__1::unique_ptr<mbgl::FillBucket, std::__1::default_delete<mbgl::FillBucket> >&, mbgl::GeometryTileLayer const&, mapbox::util::variant<mbgl::NullExpression, mbgl::EqualsExpression, mbgl::NotEqualsExpression, mbgl::LessThanExpression, mbgl::LessThanEqualsExpression, mbgl::GreaterThanExpression, mbgl::GreaterThanEqualsExpression, mbgl::InExpression, mbgl::NotInExpression, mbgl::AnyExpression, mbgl::AllExpression, mbgl::NoneExpression> const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:159
#3  0x00000001001a7ea0 in mbgl::TileParser::createFillBucket(mbgl::GeometryTileLayer const&, mbgl::StyleBucket const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:168
#4  0x00000001001a7768 in mbgl::TileParser::createBucket(mbgl::StyleBucket const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:118
#5  0x00000001001a6f94 in mbgl::TileParser::parse() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:65
#6  0x00000001001e1b68 in mbgl::VectorTileData::parse() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/vector_tile_data.cpp:49
#7  0x00000001001a3550 in mbgl::TileData::reparse(mbgl::Worker&, std::__1::function<void ()>)::$_1::operator()() const at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_data.cpp:77
…
Worker (29)#0   0x00000001003044a8 in void std::__1::allocator_traits<std::__1::allocator<float> >::__destroy<float>(std::__1::integral_constant<bool, true>, std::__1::allocator<float>&, float*) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1584
#1  0x00000001003044a4 in void std::__1::allocator_traits<std::__1::allocator<float> >::destroy<float>(std::__1::allocator<float>&, float*) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1487
#2  0x0000000100304494 in std::__1::__split_buffer<float, std::__1::allocator<float>&>::__destruct_at_end(float*, std::__1::integral_constant<bool, false>) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__split_buffer:310
#3  0x0000000100304440 in std::__1::__split_buffer<float, std::__1::allocator<float>&>::__destruct_at_end(float*) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__split_buffer:136
#4  0x0000000100304424 in std::__1::__split_buffer<float, std::__1::allocator<float>&>::clear() [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__split_buffer:83
#5  0x0000000100304414 in std::__1::__split_buffer<float, std::__1::allocator<float>&>::~__split_buffer() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__split_buffer:355
#6  0x00000001003043ac in std::__1::__split_buffer<float, std::__1::allocator<float>&>::~__split_buffer() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__split_buffer:354
#7  0x0000000100304000 in void std::__1::vector<float, std::__1::allocator<float> >::__push_back_slow_path<float>(float&&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1572
#8  0x00000001001ef14c in std::__1::vector<float, std::__1::allocator<float> >::push_back(float&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1606
#9  0x00000001001ef024 in mbgl::FillBucket::tessellate() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/renderer/fill_bucket.cpp:124
#10 0x00000001001ee328 in mbgl::FillBucket::addGeometry(std::__1::vector<std::__1::vector<mbgl::vec2<short>, std::__1::allocator<mbgl::vec2<short> > >, std::__1::allocator<std::__1::vector<mbgl::vec2<short>, std::__1::allocator<mbgl::vec2<short> > > > > const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/renderer/fill_bucket.cpp:82
#11 0x00000001001aa7fc in void mbgl::TileParser::addBucketGeometries<std::__1::unique_ptr<mbgl::FillBucket, std::__1::default_delete<mbgl::FillBucket> > >(std::__1::unique_ptr<mbgl::FillBucket, std::__1::default_delete<mbgl::FillBucket> >&, mbgl::GeometryTileLayer const&, mapbox::util::variant<mbgl::NullExpression, mbgl::EqualsExpression, mbgl::NotEqualsExpression, mbgl::LessThanExpression, mbgl::LessThanEqualsExpression, mbgl::GreaterThanExpression, mbgl::GreaterThanEqualsExpression, mbgl::InExpression, mbgl::NotInExpression, mbgl::AnyExpression, mbgl::AllExpression, mbgl::NoneExpression> const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:159
#12 0x00000001001a7ea0 in mbgl::TileParser::createFillBucket(mbgl::GeometryTileLayer const&, mbgl::StyleBucket const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:168
#13 0x00000001001a7768 in mbgl::TileParser::createBucket(mbgl::StyleBucket const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:118
#14 0x00000001001a6f94 in mbgl::TileParser::parse() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:65
#15 0x00000001001e1b68 in mbgl::VectorTileData::parse() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/vector_tile_data.cpp:49
#16 0x00000001001a3550 in mbgl::TileData::reparse(mbgl::Worker&, std::__1::function<void ()>)::$_1::operator()() const at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_data.cpp:77
…

@kkaefer
Copy link
Contributor

kkaefer commented May 7, 2015

What likely happens is the following: When the user pans the map, we update the Transform (main thread), and trigger an update. Eventually the update will be executed (map thread). This triggers a view.invalidate(), which notifies the main thread that it needs to trigger a view repaint. That means we're doing two round trips between threads for a gesture => rerender. This also explains why the user dot keeps moving on panning (the main thread is not blocked).

@1ec5
Copy link
Contributor Author

1ec5 commented May 7, 2015

At this point, I would consider the regression to be that the map stops redrawing while reparsing tiles. (If we also stopped the user dot from moving, it would still be perceived as a hang, and hangs are that much more jarring during gesture recognition.) In the past, was it the case that the Map thread remained unblocked while the Worker threads continued parsing?

@jfirebaugh
Copy link
Contributor

The stack traces show the map thread blocked waiting for worker tasks to complete during ~TileData. That blocking behavior was added in 5c7867f in order to fix #1309, a common crasher when zooming/panning.

The workers are busy clipping and tessellating FillBuckets. In order to fix this without regressing #1309, we'd need to make the work that the FillBucket is doing interruptible, so that the worker task can short-circuit when the tile becomes obsolete.

The situation is possibly exacerbated by the issue described in #1461.

@jfirebaugh
Copy link
Contributor

There's a check just up the stack, in the feature loop. Could clipping and tessellating a single feature really take long enough to cause a noticeable pause?

@1ec5
Copy link
Contributor Author

1ec5 commented May 8, 2015

I wouldn’t read too much into the top of the stacks, which vary widely. The only thing in common to each stack I’ve captured is that (re)parsing is occurring:

Worker (22)#0   0x000000010014c180 in mapbox::util::variant<bool, long long, unsigned long long, double, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::~variant() at /Users/mxn/hub/mapbox-gl-native/include/mbgl/util/variant.hpp:722
…
#33 0x0000000100134a14 in decltype(mapbox::util::variant<mbgl::NullExpression, mbgl::EqualsExpression, mbgl::NotEqualsExpression, mbgl::LessThanExpression, mbgl::LessThanEqualsExpression, mbgl::GreaterThanExpression, mbgl::GreaterThanEqualsExpression, mbgl::InExpression, mbgl::NotInExpression, mbgl::AnyExpression, mbgl::AllExpression, mbgl::NoneExpression>::visit(fp0fp)) mapbox::util::apply_visitor<mapbox::util::variant<mbgl::NullExpression, mbgl::EqualsExpression, mbgl::NotEqualsExpression, mbgl::LessThanExpression, mbgl::LessThanEqualsExpression, mbgl::GreaterThanExpression, mbgl::GreaterThanEqualsExpression, mbgl::InExpression, mbgl::NotInExpression, mbgl::AnyExpression, mbgl::AllExpression, mbgl::NoneExpression>, mbgl::Evaluator<mbgl::GeometryTileFeatureExtractor> >(mbgl::Evaluator<mbgl::GeometryTileFeatureExtractor>, mapbox::util::variant<mbgl::NullExpression, mbgl::EqualsExpression, mbgl::NotEqualsExpression, mbgl::LessThanExpression, mbgl::LessThanEqualsExpression, mbgl::GreaterThanExpression, mbgl::GreaterThanEqualsExpression, mbgl::InExpression, mbgl::NotInExpression, mbgl::AnyExpression, mbgl::AllExpression, mbgl::NoneExpression> const&) at /Users/mxn/hub/mapbox-gl-native/include/mbgl/util/variant.hpp:754
#34 0x0000000100134e6c in bool mbgl::evaluate<mbgl::GeometryTileFeatureExtractor>(mapbox::util::variant<mbgl::NullExpression, mbgl::EqualsExpression, mbgl::NotEqualsExpression, mbgl::LessThanExpression, mbgl::LessThanEqualsExpression, mbgl::GreaterThanExpression, mbgl::GreaterThanEqualsExpression, mbgl::InExpression, mbgl::NotInExpression, mbgl::AnyExpression, mbgl::AllExpression, mbgl::NoneExpression> const&, mbgl::GeometryTileFeatureExtractor const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/style/filter_expression_private.hpp:20
#35 0x000000010022ffa0 in mbgl::SymbolBucket::processFeatures(mbgl::GeometryTileLayer const&, mapbox::util::variant<mbgl::NullExpression, mbgl::EqualsExpression, mbgl::NotEqualsExpression, mbgl::LessThanExpression, mbgl::LessThanEqualsExpression, mbgl::GreaterThanExpression, mbgl::GreaterThanEqualsExpression, mbgl::InExpression, mbgl::NotInExpression, mbgl::AnyExpression, mbgl::AllExpression, mbgl::NoneExpression> const&, mbgl::GlyphStore&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/renderer/symbol_bucket.cpp:84
#36 0x000000010023269c in mbgl::SymbolBucket::addFeatures(mbgl::GeometryTileLayer const&, mapbox::util::variant<mbgl::NullExpression, mbgl::EqualsExpression, mbgl::NotEqualsExpression, mbgl::LessThanExpression, mbgl::LessThanEqualsExpression, mbgl::GreaterThanExpression, mbgl::GreaterThanEqualsExpression, mbgl::InExpression, mbgl::NotInExpression, mbgl::AnyExpression, mbgl::AllExpression, mbgl::NoneExpression> const&, unsigned long, mbgl::SpriteAtlas&, mbgl::Sprite&, mbgl::GlyphAtlas&, mbgl::GlyphStore&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/renderer/symbol_bucket.cpp:152
#37 0x00000001001b90d4 in mbgl::TileParser::createSymbolBucket(mbgl::GeometryTileLayer const&, mbgl::StyleBucket const&, bool&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:240
#38 0x00000001001b7824 in mbgl::TileParser::createBucket(mbgl::StyleBucket const&) at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:123
#39 0x00000001001b6f94 in mbgl::TileParser::parse() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_parser.cpp:65
#40 0x00000001001f1b68 in mbgl::VectorTileData::parse() at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/vector_tile_data.cpp:49
#41 0x00000001001b3550 in mbgl::TileData::reparse(mbgl::Worker&, std::__1::function<void ()>)::$_1::operator()() const at /Users/mxn/hub/mapbox-gl-native/src/mbgl/map/tile_data.cpp:77

@1ec5
Copy link
Contributor Author

1ec5 commented May 8, 2015

I’m unable to reproduce any of this while profiling the demo app in Instruments using the Time Profiler instrument: performance in this configuration is just as good as in the Simulator.

@kkaefer
Copy link
Contributor

kkaefer commented May 8, 2015

There's a check just up the stack, in the feature loop. Could clipping and tessellating a single feature really take long enough to cause a noticeable pause?

This check is effective, and processing a single feature typically only takes a few microseconds. The problem is a combination of two issues:

When submitting WorkRequests, they are put into a queue until they are being processed. If the queue clogs up, the WorkRequests that are in the queue cannot be canceled, so joining the WorkRequest does a blocking wait until all previous WorkRequests in the queue have been processed, only to discover that the tile's state was marked as obsolete in the very first iteration. (#1470)

4ccf246 intensified this problem by changing our worker pool from a shared queue to an individual queue for every thread with round-robin distribution of WorkRequests. This means there can be situations where a thread's work queue gets clogged up with work items while other workers would be available to process them. (#1471)

@jfirebaugh
Copy link
Contributor

Should be significantly alleviated #1470 and the remaining performance optimization regarding distribution is ticketed; closing here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
iOS Mapbox Maps SDK for iOS performance Speed, stability, CPU usage, memory usage, or power usage
Projects
None yet
Development

No branches or pull requests

4 participants