diff --git a/include/mbgl/storage/network_status.hpp b/include/mbgl/storage/network_status.hpp index d7f502a3b..1b5471a44 100644 --- a/include/mbgl/storage/network_status.hpp +++ b/include/mbgl/storage/network_status.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include + #include #include @@ -26,7 +27,7 @@ public: static void Unsubscribe(util::AsyncTask* async); private: - static std::atomic online; + static util::Atomic online; static std::mutex mtx; static std::set observers; }; diff --git a/include/mbgl/util/run_loop.hpp b/include/mbgl/util/run_loop.hpp index 9703fe7bc..56965c97e 100644 --- a/include/mbgl/util/run_loop.hpp +++ b/include/mbgl/util/run_loop.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -9,7 +10,6 @@ #include #include #include -#include namespace mbgl { namespace util { @@ -59,7 +59,7 @@ public: template std::unique_ptr invokeCancellable(Fn&& fn, Args&&... args) { - auto flag = std::make_shared>(); + auto flag = std::make_shared>(); *flag = false; auto tuple = std::make_tuple(std::move(args)...); @@ -77,7 +77,7 @@ public: template std::unique_ptr invokeWithCallback(Fn&& fn, Cb&& callback, Args&&... args) { - auto flag = std::make_shared>(); + auto flag = std::make_shared>(); *flag = false; // Create a lambda L1 that invokes another lambda L2 on the current RunLoop R, that calls @@ -114,7 +114,7 @@ private: template class Invoker : public WorkTask { public: - Invoker(F&& f, P&& p, std::shared_ptr> canceled_ = nullptr) + Invoker(F&& f, P&& p, std::shared_ptr> canceled_ = nullptr) : canceled(std::move(canceled_)), func(std::move(f)), params(std::move(p)) { @@ -148,7 +148,7 @@ private: } std::recursive_mutex mutex; - std::shared_ptr> canceled; + std::shared_ptr> canceled; F func; P params; diff --git a/platform/android/src/async_task.cpp b/platform/android/src/async_task.cpp index 4a68c1c09..6a9263baf 100644 --- a/platform/android/src/async_task.cpp +++ b/platform/android/src/async_task.cpp @@ -1,9 +1,9 @@ #include "run_loop_impl.hpp" #include +#include #include -#include #include namespace mbgl { @@ -12,7 +12,7 @@ namespace util { class AsyncTask::Impl : public RunLoop::Impl::Runnable { public: Impl(std::function&& fn) - : task(std::move(fn)) { + : queued(true), task(std::move(fn)) { loop->initRunnable(this); } @@ -21,7 +21,8 @@ public: } void maySend() { - if (!queued.test_and_set()) { + if (queued) { + queued = false; loop->addRunnable(this); } } @@ -32,7 +33,7 @@ public: void runTask() override { loop->removeRunnable(this); - queued.clear(); + queued = true; task(); } @@ -42,7 +43,9 @@ private: RunLoop::Impl* loop = reinterpret_cast(RunLoop::getLoopHandle()); - std::atomic_flag queued = ATOMIC_FLAG_INIT; + // TODO: Use std::atomic_flag if we ever drop + // support for ARMv5 + util::Atomic queued; std::function task; }; diff --git a/platform/android/src/run_loop_impl.hpp b/platform/android/src/run_loop_impl.hpp index 5cf723117..d855728b6 100644 --- a/platform/android/src/run_loop_impl.hpp +++ b/platform/android/src/run_loop_impl.hpp @@ -2,10 +2,10 @@ #include "jni.hpp" +#include #include #include -#include #include #include #include @@ -47,7 +47,7 @@ private: bool detach = false; ALooper* loop = nullptr; - std::atomic running; + util::Atomic running; std::recursive_mutex mtx; std::list runnables; diff --git a/src/mbgl/geometry/glyph_atlas.hpp b/src/mbgl/geometry/glyph_atlas.hpp index 20ba5890e..ffabbc2e7 100644 --- a/src/mbgl/geometry/glyph_atlas.hpp +++ b/src/mbgl/geometry/glyph_atlas.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -10,7 +11,6 @@ #include #include #include -#include namespace mbgl { @@ -52,7 +52,7 @@ private: BinPack bin; std::unordered_map, FontStackHash> index; const std::unique_ptr data; - std::atomic dirty; + util::Atomic dirty; gl::TextureHolder texture; }; diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 298255ada..841b4607c 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -518,7 +518,7 @@ CameraOptions Map::cameraForLatLngs(const std::vector& latLngs, optional scaleY -= (padding->top + padding->bottom) / height; } double minScale = ::fmin(scaleX, scaleY); - double zoom = ::log2(getScale() * minScale); + double zoom = util::log2(getScale() * minScale); zoom = util::clamp(zoom, getMinZoom(), getMaxZoom()); // Calculate the center point of a virtual bounds that is extended in all directions by padding. diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index ac8b6396c..fab5991de 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -222,7 +222,7 @@ double TransformState::zoomScale(double zoom) const { } double TransformState::scaleZoom(double s) const { - return ::log2(s); + return util::log2(s); } double TransformState::worldSize() const { diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index d7286b0b4..5292ecc6e 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -2,11 +2,10 @@ #include #include +#include #include #include -#include - #define BUFFER_OFFSET_0 ((GLbyte*)nullptr) #define BUFFER_OFFSET(i) ((BUFFER_OFFSET_0) + (i)) @@ -47,7 +46,7 @@ public: virtual void swapRenderData() {} protected: - std::atomic uploaded; + util::Atomic uploaded; }; diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp index 891f48fa2..b144855a1 100644 --- a/src/mbgl/sprite/sprite_atlas.hpp +++ b/src/mbgl/sprite/sprite_atlas.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -10,7 +11,6 @@ #include #include #include -#include #include #include @@ -92,7 +92,7 @@ private: std::map images; std::set uninitialized; std::unique_ptr data; - std::atomic dirty; + util::Atomic dirty; bool fullUploadRequired = true; gl::TextureHolder texture; uint32_t filter = 0; diff --git a/src/mbgl/storage/network_status.cpp b/src/mbgl/storage/network_status.cpp index 1ef5619bd..bc538a5f3 100644 --- a/src/mbgl/storage/network_status.cpp +++ b/src/mbgl/storage/network_status.cpp @@ -9,7 +9,7 @@ namespace mbgl { -std::atomic NetworkStatus::online(true); +util::Atomic NetworkStatus::online(true); std::mutex NetworkStatus::mtx; std::set NetworkStatus::observers; diff --git a/src/mbgl/style/style_bucket_parameters.hpp b/src/mbgl/style/style_bucket_parameters.hpp index 17639afae..d8d9bc593 100644 --- a/src/mbgl/style/style_bucket_parameters.hpp +++ b/src/mbgl/style/style_bucket_parameters.hpp @@ -3,9 +3,9 @@ #include #include #include +#include #include -#include namespace mbgl { @@ -22,7 +22,7 @@ class StyleBucketParameters { public: StyleBucketParameters(const OverscaledTileID& tileID_, const GeometryTileLayer& layer_, - const std::atomic& obsolete_, + const util::Atomic& obsolete_, uintptr_t tileUID_, bool& partialParse_, SpriteStore& spriteStore_, @@ -49,7 +49,7 @@ public: const OverscaledTileID& tileID; const GeometryTileLayer& layer; - const std::atomic& obsolete; + const util::Atomic& obsolete; uintptr_t tileUID; bool& partialParse; SpriteStore& spriteStore; diff --git a/src/mbgl/text/glyph_pbf.hpp b/src/mbgl/text/glyph_pbf.hpp index 08616b268..3ebd4f4bc 100644 --- a/src/mbgl/text/glyph_pbf.hpp +++ b/src/mbgl/text/glyph_pbf.hpp @@ -3,9 +3,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -29,7 +29,7 @@ public: } private: - std::atomic parsed; + util::Atomic parsed; std::unique_ptr req; GlyphStoreObserver* observer = nullptr; }; diff --git a/src/mbgl/tile/tile_worker.cpp b/src/mbgl/tile/tile_worker.cpp index fdebe9122..266e357ab 100644 --- a/src/mbgl/tile/tile_worker.cpp +++ b/src/mbgl/tile/tile_worker.cpp @@ -22,7 +22,7 @@ TileWorker::TileWorker(const OverscaledTileID& id_, SpriteStore& spriteStore_, GlyphAtlas& glyphAtlas_, GlyphStore& glyphStore_, - const std::atomic& obsolete_, + const util::Atomic& obsolete_, const MapMode mode_) : id(id_), sourceID(std::move(sourceID_)), diff --git a/src/mbgl/tile/tile_worker.hpp b/src/mbgl/tile/tile_worker.hpp index 83bf6c7f4..e19d803ac 100644 --- a/src/mbgl/tile/tile_worker.hpp +++ b/src/mbgl/tile/tile_worker.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -12,7 +13,6 @@ #include #include #include -#include #include namespace mbgl { @@ -47,7 +47,7 @@ public: SpriteStore&, GlyphAtlas&, GlyphStore&, - const std::atomic&, + const util::Atomic&, const MapMode); ~TileWorker(); @@ -72,7 +72,7 @@ private: SpriteStore& spriteStore; GlyphAtlas& glyphAtlas; GlyphStore& glyphStore; - const std::atomic& obsolete; + const util::Atomic& obsolete; const MapMode mode; bool partialParse = false; diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp index 2545df801..ec557e202 100644 --- a/src/mbgl/tile/vector_tile_data.hpp +++ b/src/mbgl/tile/vector_tile_data.hpp @@ -3,9 +3,9 @@ #include #include #include +#include #include -#include #include #include @@ -66,7 +66,7 @@ private: PlacementConfig targetConfig; // Used to signal the worker that it should abandon parsing this tile as soon as possible. - std::atomic obsolete { false }; + util::Atomic obsolete { false }; }; } // namespace mbgl diff --git a/src/mbgl/util/atomic.hpp b/src/mbgl/util/atomic.hpp new file mode 100644 index 000000000..3f68bf46a --- /dev/null +++ b/src/mbgl/util/atomic.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +namespace mbgl { +namespace util { + +// std::atomic is implemented lock free which +// is not supported by ARMv5 but the code generated +// seems to be using that and not working at all, +// thus, this naive implementation using mutexes. +#if defined(__ANDROID__) && defined(__ARM_ARCH_5TE__) + +template +class Atomic { +public: + Atomic() = default; + explicit Atomic(const T& data_) : data(data_) {} + + void operator=(const T& other) { + std::lock_guard lock(mtx); + data = other; + } + + operator bool() const { + std::lock_guard lock(mtx); + + return data; + } + +private: + T data; + mutable std::mutex mtx; +}; + +#else + +template +using Atomic = std::atomic; + +#endif + +} // namespace util +} // namespace mbgl diff --git a/src/mbgl/util/math.cpp b/src/mbgl/util/math.cpp index a52475410..0e86849ad 100644 --- a/src/mbgl/util/math.cpp +++ b/src/mbgl/util/math.cpp @@ -21,5 +21,15 @@ uint32_t ceil_log2(uint64_t x) { return y; } +double log2(double x) { +// log2() is producing wrong results on ARMv5 binaries +// running on ARMv7+ CPUs. +#if defined(__ANDROID__) && defined(__ARM_ARCH_5TE__) + return std::log(x) / 0.6931471805599453; // log(x) / log(2) +#else + return ::log2(x); +#endif +} + } // namespace util -} // namespace mbgl \ No newline at end of file +} // namespace mbgl diff --git a/src/mbgl/util/math.hpp b/src/mbgl/util/math.hpp index ef60f76ff..bfedc2a42 100644 --- a/src/mbgl/util/math.hpp +++ b/src/mbgl/util/math.hpp @@ -110,5 +110,7 @@ T smoothstep(T edge0, T edge1, T x) { // (== number of bits required to store x) uint32_t ceil_log2(uint64_t x); +double log2(double x); + } // namespace util } // namespace mbgl diff --git a/src/mbgl/util/thread.hpp b/src/mbgl/util/thread.hpp index 9efd5ea92..c5f9d7338 100644 --- a/src/mbgl/util/thread.hpp +++ b/src/mbgl/util/thread.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include