summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--circle.yml391
-rw-r--r--include/mbgl/actor/scheduler.hpp27
-rw-r--r--next/platform/android/android.cmake2
-rw-r--r--platform/android/CHANGELOG.md1
-rw-r--r--platform/ios/CHANGELOG.md1
-rw-r--r--render-test/android/app/build.gradle12
-rw-r--r--render-test/manifest_parser.cpp20
-rw-r--r--render-test/render_test.cpp6
-rw-r--r--src/mbgl/style/sources/geojson_source.cpp36
-rw-r--r--src/mbgl/util/thread_pool.hpp4
-rw-r--r--test/util/async_task.test.cpp19
11 files changed, 323 insertions, 196 deletions
diff --git a/circle.yml b/circle.yml
index ad4dc8bfd0..31a0b1f84c 100644
--- a/circle.yml
+++ b/circle.yml
@@ -4,123 +4,126 @@ workflows:
version: 2
mbgl-next:
jobs:
- - next-sanity-checks
- - next-build-template:
- name: next-android-armeabi-v7a-release
- executor_name: ubuntu-disco
- target_is_android: true
- config_params: '-G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/android/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_CCACHE=/usr/bin/ccache -DANDROID_ABI=armeabi-v7a'
- - next-build-template:
- name: next-android-arm64-v8a-release
- executor_name: ubuntu-disco
- target_is_android: true
- requires:
- - next-android-armeabi-v7a-release
- config_params: '-G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/android/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_CCACHE=/usr/bin/ccache -DANDROID_ABI=arm64-v8a'
- - next-build-template:
- name: next-android-x86-release
- executor_name: ubuntu-disco
- target_is_android: true
- requires:
- - next-android-armeabi-v7a-release
- config_params: '-G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/android/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_CCACHE=/usr/bin/ccache -DANDROID_ABI=x86'
- - next-build-template:
- name: next-android-x86_64-release
- executor_name: ubuntu-disco
- target_is_android: true
- requires:
- - next-android-armeabi-v7a-release
- config_params: '-G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/android/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_CCACHE=/usr/bin/ccache -DANDROID_ABI=x86_64'
- - next-build-template:
- name: next-linux-gcc8-release
- executor_name: ubuntu-disco
- target_is_linux: true
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8'
- - next-build-template:
- name: next-linux-gcc4.9-release
- executor_name: ubuntu-disco
- target_is_linux: true
- requires:
- - next-linux-gcc8-release
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc-4.9 -DCMAKE_CXX_COMPILER=g++-4.9'
- build_params: '--target mbgl-glfw'
- test_params: '-N -Q'
- - next-build-template:
- name: next-linux-gcc8-debug-coverage
- executor_name: ubuntu-disco
- target_is_linux: true
- requires:
- - next-linux-gcc8-release
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8 -DCMAKE_BUILD_TYPE=DebugCoverage'
- - next-build-template:
- name: next-linux-clang8-release
- executor_name: ubuntu-disco
- target_is_linux: true
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8'
- - next-build-template:
- name: next-FIXME-linux-asan
- executor_name: ubuntu-disco
- target_is_linux: true
- requires:
- - next-sanity-checks
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_BUILD_TYPE=Sanitize -DMBGL_WITH_SANITIZER=address'
- test_params: '|| true'
- - next-build-template:
- name: next-linux-tsan
- executor_name: ubuntu-disco
- target_is_linux: true
- requires:
- - next-sanity-checks
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_BUILD_TYPE=Sanitize -DMBGL_WITH_SANITIZER=thread'
- - next-build-template:
- name: next-FIXME-linux-memsan
- executor_name: ubuntu-disco
- target_is_linux: true
- requires:
- - next-sanity-checks
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_BUILD_TYPE=Sanitize -DMBGL_WITH_SANITIZER=memory'
- test_params: '|| true'
- - next-build-template:
- name: next-FIXME-linux-ubsan
- executor_name: ubuntu-disco
- target_is_linux: true
- requires:
- - next-sanity-checks
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_BUILD_TYPE=Sanitize -DMBGL_WITH_SANITIZER=undefined'
- test_params: '|| true'
- - next-build-template:
- name: next-qt5-linux-gcc5-release
- executor_name: ubuntu-disco
- target_is_linux: true
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_CXX_COMPILER=g++-5 -DMBGL_WITH_QT=ON'
- - next-build-template:
- name: next-qt5-macos-gcc5-release
- executor_name: macos-11_0_0
- target_is_macos: true
- requires:
- - next-qt5-linux-gcc5-release
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DMBGL_WITH_QT=ON -DCMAKE_PREFIX_PATH=$(echo /usr/local/Cellar/qt/5.*/lib/cmake)'
- test_params: '-N -Q'
- - next-build-template:
- name: next-macos-xcode11-release
- executor_name: macos-11_0_0
- target_is_macos: true
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache'
- - next-build-template:
- name: next-macos-xcode11-debug
- executor_name: macos-11_0_0
- target_is_macos: true
- requires:
- - next-macos-xcode11-release
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=Debug'
- - next-build-template:
- name: next-ios-xcode11-release
- executor_name: macos-11_0_0
- target_is_macos: true
- config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_SYSROOT=iphonesimulator'
- test_params: '-Q -N'
- mbgl-legacy:
- jobs:
+ - next-android-armeabi-v7a-render-test
+ # - next-sanity-checks:
+ # requires:
+ # - next-android-armeabi-v7a-render-test
+ # - next-build-template:
+ # name: next-android-armeabi-v7a-release
+ # executor_name: ubuntu-disco
+ # target_is_android: true
+ # config_params: '-G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/android/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_CCACHE=/usr/bin/ccache -DANDROID_ABI=armeabi-v7a'
+ # - next-build-template:
+ # name: next-android-arm64-v8a-release
+ # executor_name: ubuntu-disco
+ # target_is_android: true
+ # requires:
+ # - next-android-armeabi-v7a-release
+ # config_params: '-G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/android/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_CCACHE=/usr/bin/ccache -DANDROID_ABI=arm64-v8a'
+ # - next-build-template:
+ # name: next-android-x86-release
+ # executor_name: ubuntu-disco
+ # target_is_android: true
+ # requires:
+ # - next-android-armeabi-v7a-release
+ # config_params: '-G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/android/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_CCACHE=/usr/bin/ccache -DANDROID_ABI=x86'
+ # - next-build-template:
+ # name: next-android-x86_64-release
+ # executor_name: ubuntu-disco
+ # target_is_android: true
+ # requires:
+ # - next-android-armeabi-v7a-release
+ # config_params: '-G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/android/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_CCACHE=/usr/bin/ccache -DANDROID_ABI=x86_64'
+ # - next-build-template:
+ # name: next-linux-gcc8-release
+ # executor_name: ubuntu-disco
+ # target_is_linux: true
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8'
+ # - next-build-template:
+ # name: next-linux-gcc4.9-release
+ # executor_name: ubuntu-disco
+ # target_is_linux: true
+ # requires:
+ # - next-linux-gcc8-release
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc-4.9 -DCMAKE_CXX_COMPILER=g++-4.9'
+ # build_params: '--target mbgl-glfw'
+ # test_params: '-N -Q'
+ # - next-build-template:
+ # name: next-linux-gcc8-debug-coverage
+ # executor_name: ubuntu-disco
+ # target_is_linux: true
+ # requires:
+ # - next-linux-gcc8-release
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8 -DCMAKE_BUILD_TYPE=DebugCoverage'
+ # - next-build-template:
+ # name: next-linux-clang8-release
+ # executor_name: ubuntu-disco
+ # target_is_linux: true
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8'
+ # - next-build-template:
+ # name: next-FIXME-linux-asan
+ # executor_name: ubuntu-disco
+ # target_is_linux: true
+ # requires:
+ # - next-sanity-checks
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_BUILD_TYPE=Sanitize -DMBGL_WITH_SANITIZER=address'
+ # test_params: '|| true'
+ # - next-build-template:
+ # name: next-linux-tsan
+ # executor_name: ubuntu-disco
+ # target_is_linux: true
+ # requires:
+ # - next-sanity-checks
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_BUILD_TYPE=Sanitize -DMBGL_WITH_SANITIZER=thread'
+ # - next-build-template:
+ # name: next-FIXME-linux-memsan
+ # executor_name: ubuntu-disco
+ # target_is_linux: true
+ # requires:
+ # - next-sanity-checks
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_BUILD_TYPE=Sanitize -DMBGL_WITH_SANITIZER=memory'
+ # test_params: '|| true'
+ # - next-build-template:
+ # name: next-FIXME-linux-ubsan
+ # executor_name: ubuntu-disco
+ # target_is_linux: true
+ # requires:
+ # - next-sanity-checks
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_BUILD_TYPE=Sanitize -DMBGL_WITH_SANITIZER=undefined'
+ # test_params: '|| true'
+ # - next-build-template:
+ # name: next-qt5-linux-gcc5-release
+ # executor_name: ubuntu-disco
+ # target_is_linux: true
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_CXX_COMPILER=g++-5 -DMBGL_WITH_QT=ON'
+ # - next-build-template:
+ # name: next-qt5-macos-gcc5-release
+ # executor_name: macos-11_0_0
+ # target_is_macos: true
+ # requires:
+ # - next-qt5-linux-gcc5-release
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DMBGL_WITH_QT=ON -DCMAKE_PREFIX_PATH=$(echo /usr/local/Cellar/qt/5.*/lib/cmake)'
+ # test_params: '-N -Q'
+ # - next-build-template:
+ # name: next-macos-xcode11-release
+ # executor_name: macos-11_0_0
+ # target_is_macos: true
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache'
+ # - next-build-template:
+ # name: next-macos-xcode11-debug
+ # executor_name: macos-11_0_0
+ # target_is_macos: true
+ # requires:
+ # - next-macos-xcode11-release
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=Debug'
+ # - next-build-template:
+ # name: next-ios-xcode11-release
+ # executor_name: macos-11_0_0
+ # target_is_macos: true
+ # config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_SYSROOT=iphonesimulator'
+ # test_params: '-Q -N'
+ # mbgl-legacy:
+ # jobs:
#
# Naming convention: {platform}-{additional description}-{build type}
# - {platform} is the client platform/framework, which may differ from
@@ -129,59 +132,59 @@ workflows:
# unique aspect of the build environment.
# - {build type} is typically "debug" or "release".
#
- - android-debug-arm-v7-buck
- - android-arm-template:
- name: android-debug-arm-v8
- - android-arm-template:
- name: android-gnustl-arm-v7
- stl: gnustl_shared
- firebase_device_id: "flo"
- firebase_device_os: "21"
- image: android-ndk-r17c:1d5db0eb34
- abi: arm-v7
- - android-release:
- filters:
- tags:
- only: /android-v.*/
- - node-linux-release:
- filters:
- tags:
- only: /node-.*/
- - node-macos-release:
- filters:
- tags:
- only: /node-.*/
- - linux-clang-7-sanitize-address-undefined
- - linux-clang-7-sanitize-thread
- - linux-gcc5-debug-coverage
- - linux-doxygen
- - ios-debug
- - ios-debug-xcode10
- - ios-release-template:
- name: ios-release
- - ios-release-tag:
- filters:
- tags:
- only: /ios-.*/
- branches:
- ignore: /.*/
- - macos-debug
- nightly:
- triggers:
- - schedule:
- cron: "0 5 * * *"
- filters:
- branches:
- only:
- - master
- jobs:
- - metrics-nightly
- - ios-release-template:
- name: ios-release-nightly
- - ios-sanitize-nightly
- - ios-sanitize-address-nightly
- - ios-static-analyzer-nightly
- - ios-static-analyzer-nightly-xcode10
+ # - android-debug-arm-v7-buck
+ # - android-arm-template:
+ # name: android-debug-arm-v8
+ # - android-arm-template:
+ # name: android-gnustl-arm-v7
+ # stl: gnustl_shared
+ # firebase_device_id: "flo"
+ # firebase_device_os: "21"
+ # image: android-ndk-r17c:1d5db0eb34
+ # abi: arm-v7
+ # - android-release:
+ # filters:
+ # tags:
+ # only: /android-v.*/
+ # - node-linux-release:
+ # filters:
+ # tags:
+ # only: /node-.*/
+ # - node-macos-release:
+ # filters:
+ # tags:
+ # only: /node-.*/
+ # - linux-clang-7-sanitize-address-undefined
+ # - linux-clang-7-sanitize-thread
+ # - linux-gcc5-debug-coverage
+ # - linux-doxygen
+ # - ios-debug
+ # - ios-debug-xcode10
+ # - ios-release-template:
+ # name: ios-release
+ # - ios-release-tag:
+ # filters:
+ # tags:
+ # only: /ios-.*/
+ # branches:
+ # ignore: /.*/
+ # - macos-debug
+ # nightly:
+ # triggers:
+ # - schedule:
+ # cron: "0 5 * * *"
+ # filters:
+ # branches:
+ # only:
+ # - master
+ # jobs:
+ # - metrics-nightly
+ # - ios-release-template:
+ # name: ios-release-nightly
+ # - ios-sanitize-nightly
+ # - ios-sanitize-address-nightly
+ # - ios-static-analyzer-nightly
+ # - ios-static-analyzer-nightly-xcode10
executors:
ubuntu-disco:
@@ -215,7 +218,7 @@ commands:
- run:
name: Prepare
command: |
- git submodule sync
+ git submodule
git submodule update --init --recursive
npm install --ignore-scripts
ulimit -c unlimited
@@ -240,6 +243,19 @@ commands:
name: Configure
command: |
cmake next -B build << parameters.config_params >>
+ next-gradle:
+ steps:
+ - run:
+ name: GradleBuild
+ commond: |
+ cd render-test/android && ./gradlew --parallel --max-workers=8 -Pmapbox.abis=armeabi-v7a assembleDebug
+ - run:
+ name: Run gcloud tests on Firebase
+ no_output_timeout: 20m
+ command: |
+ if [[ -n "${GCLOUD_SERVICE_ACCOUNT_JSON}" && -z "${SKIP_FIREBASE:-}" ]]; then
+ gcloud firebase test android models list
+ fi
next-build:
parameters:
build_params:
@@ -650,6 +666,35 @@ commands:
fi
jobs:
+ next-android-armeabi-v7a-render-test:
+ executor: ubuntu-disco
+ steps:
+ - checkout
+ - next-prepare
+ - run:
+ name: Build RenderTestRunner APK
+ command: |
+ cd render-test/android
+ ./gradlew --parallel --max-workers=8 -Pmapbox.abis=arm64-v8a app:assembleDebug app:assembleDebugAndroidTest
+ - login-google-cloud-platform
+ - run:
+ name: Run render test runner on Firebase
+ no_output_timeout: 20m
+ command: |
+ mkdir abc
+ cp -r mapbox-gl-js/test/integration/query-tests/fill/default/ abc/
+ if [[ -n "${GCLOUD_SERVICE_ACCOUNT_JSON}" && -z "${SKIP_FIREBASE:-}" ]]; then
+ gcloud firebase test android models list
+ gcloud firebase test android run --type instrumentation \
+ --app render-test/android/app/build/outputs/apk/debug/app-debug.apk \
+ --test render-test/android/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
+ --device-ids sailfish --os-version-ids 26 --locales en --orientations portrait --timeout 20m \
+ --environment-variables coverage=true,coverageFile="/sdcard/coverage.ec",testResult="/sdcard/render-tests_index.html" --directories-to-pull /sdcard --results-dir mapbox-android-sdk-${CIRCLE_BUILD_NUM}
+ coverageFile=`gsutil ls gs://test-lab-186672a0qp5bq-ycr70axads3nc/mapbox-android-sdk-${CIRCLE_BUILD_NUM}/**/*.ec | tail -1`
+ testResult=`gsutil ls gs://test-lab-186672a0qp5bq-ycr70axads3nc/mapbox-android-sdk-${CIRCLE_BUILD_NUM}/**/*.html | tail -1`
+ gsutil cp $coverageFile $PWD/platform/android/MapboxGLAndroidSDK/build/jacoco | true
+ fi
+ - next-save
next-sanity-checks:
executor: ubuntu-disco
steps:
@@ -706,6 +751,9 @@ jobs:
target_is_macos:
type: boolean
default: false
+ gradle_params:
+ type: string
+ default: ''
executor: << parameters.executor_name >>
steps:
- checkout
@@ -717,6 +765,7 @@ jobs:
config_params: << parameters.config_params >>
- next-build:
build_params: << parameters.build_params >>
+
- when:
condition: << parameters.target_is_linux >>
steps:
diff --git a/include/mbgl/actor/scheduler.hpp b/include/mbgl/actor/scheduler.hpp
index bb2cf124b8..1115328797 100644
--- a/include/mbgl/actor/scheduler.hpp
+++ b/include/mbgl/actor/scheduler.hpp
@@ -50,6 +50,18 @@ public:
// first invoked, the call is ignored.
std::function<void()> bindOnce(std::function<void()>);
+ // Enqueues the given |task| for execution into this scheduler's task queue and
+ // then enqueues the |reply| with the captured task result to the current
+ // task queue.
+ //
+ // The |TaskFn| return type must be compatible with the |ReplyFn| argument type.
+ // Note: the task result is copied and passed by value.
+ template <typename TaskFn, typename ReplyFn>
+ void scheduleAndReplyValue(const TaskFn& task, const ReplyFn& reply) {
+ assert(GetCurrent());
+ scheduleAndReplyValue(task, reply, GetCurrent()->makeWeakPtr());
+ }
+
// Set/Get the current Scheduler for this thread
static Scheduler* GetCurrent();
static void SetCurrent(Scheduler*);
@@ -58,6 +70,21 @@ public:
// will lazily initialize a shared worker pool when ran
// from the first time.
static std::shared_ptr<Scheduler> GetBackground();
+
+protected:
+ template <typename TaskFn, typename ReplyFn>
+ void scheduleAndReplyValue(const TaskFn& task,
+ const ReplyFn& reply,
+ mapbox::base::WeakPtr<Scheduler> replyScheduler) {
+ auto scheduled = [replyScheduler, task, reply] {
+ auto lock = replyScheduler.lock();
+ if (!replyScheduler) return;
+ auto scheduledReply = [reply, result = task()] { reply(result); };
+ replyScheduler->schedule(std::move(scheduledReply));
+ };
+
+ schedule(std::move(scheduled));
+ }
};
} // namespace mbgl
diff --git a/next/platform/android/android.cmake b/next/platform/android/android.cmake
index e086f8b75b..86350b51d5 100644
--- a/next/platform/android/android.cmake
+++ b/next/platform/android/android.cmake
@@ -342,7 +342,7 @@ add_custom_command(
TARGET mbgl-render-test-runner PRE_BUILD
COMMAND
${CMAKE_COMMAND}
- -E
+ -E
copy
${MBGL_ROOT}/render-test/android-manifest.json
${MBGL_ROOT}/android-manifest.json
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md
index 398844a64e..815a20a572 100644
--- a/platform/android/CHANGELOG.md
+++ b/platform/android/CHANGELOG.md
@@ -10,6 +10,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to
### Performance improvements
- Enable incremental vacuum for the offline database in order to make data removal requests faster and to avoid the excessive disk space usage (creating a backup file on VACUUM call) [#15837](https://github.com/mapbox/mapbox-gl-native/pull/15837)
- Convert GeoJSON features to tiles in a background thread and thus unblock the UI thread on updating the GeoJsonSource [#15871](https://github.com/mapbox/mapbox-gl-native/pull/15871)
+ - Convert GeoJSON features to tiles for the loaded source description in a background thread and thus unblock the UI thread [#15885](https://github.com/mapbox/mapbox-gl-native/pull/15885)
## 8.5.0-alpha.2 - October 10, 2019
[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.5.0-alpha.1...android-v8.5.0-alpha.2) since [Mapbox Maps SDK for Android v8.5.0-alpha.1](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.5.0-alpha.1):
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 98761737f7..da4334db89 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -5,6 +5,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
## master
### Other changes
+* Convert GeoJSON features to tiles for the loaded source description in a background thread and thus unblock the UI thread ([#15885](https://github.com/mapbox/mapbox-gl-native/pull/15885))
### Bug fixes
* Fixed the rendering bug caused by redundant pending requests for already requested images [#15864](https://github.com/mapbox/mapbox-gl-native/pull/15864)
diff --git a/render-test/android/app/build.gradle b/render-test/android/app/build.gradle
index 682af85dcf..12b640ecd6 100644
--- a/render-test/android/app/build.gradle
+++ b/render-test/android/app/build.gradle
@@ -7,6 +7,18 @@ android {
applicationId = 'com.mapbox.mapboxsdk.maps.render_test_runner'
minSdkVersion 14
targetSdkVersion 28
+ def abi = 'all'
+ if (project.hasProperty('mapbox.abis')) {
+ // Errors when the user invokes Gradle from the command line and didn't set mapbox.abis
+ abi = project.getProperty("mapbox.abis")
+ }
+ ndk {
+ if (abi != 'all') {
+ abiFilters abi.split(' ')
+ } else {
+ abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
+ }
+ }
externalNativeBuild {
cmake {
arguments '-DANDROID_CCACHE=ccache'
diff --git a/render-test/manifest_parser.cpp b/render-test/manifest_parser.cpp
index 8b5a534027..6bba33754a 100644
--- a/render-test/manifest_parser.cpp
+++ b/render-test/manifest_parser.cpp
@@ -52,8 +52,8 @@ void Manifest::doShuffle(uint32_t seed) {
std::string Manifest::localizeURL(const std::string& url) const {
static const std::regex regex{"local://"};
- if (auto vendorPath = getVendorPath(url, regex)) {
- return *vendorPath;
+ if (auto path = getVendorPath(url, regex)) {
+ return *path;
}
return getIntegrationPath(url, "", regex).value_or(url);
}
@@ -137,16 +137,16 @@ void Manifest::localizeStyleURLs(mbgl::JSValue& root, mbgl::JSDocument& document
mbgl::optional<std::string> Manifest::localizeLocalURL(const std::string& url, bool glyphsPath) const {
static const std::regex regex{"local://"};
- if (auto vendorPath = getVendorPath(url, regex, glyphsPath)) {
- return vendorPath;
+ if (auto path = getVendorPath(url, regex, glyphsPath)) {
+ return path;
}
return getIntegrationPath(url, "", regex, glyphsPath);
}
mbgl::optional<std::string> Manifest::localizeHttpURL(const std::string& url) const {
static const std::regex regex{"http://localhost:2900"};
- if (auto vendorPath = getVendorPath(url, regex)) {
- return vendorPath;
+ if (auto path = getVendorPath(url, regex)) {
+ return path;
}
return getIntegrationPath(url, "", regex);
}
@@ -163,8 +163,8 @@ mbgl::optional<std::string> Manifest::localizeMapboxFontsURL(const std::string&
mbgl::optional<std::string> Manifest::localizeMapboxTilesURL(const std::string& url) const {
static const std::regex regex{"mapbox://"};
- if (auto vendorPath = getVendorPath(url, regex)) {
- return vendorPath;
+ if (auto path = getVendorPath(url, regex)) {
+ return path;
}
return getIntegrationPath(url, "tiles/", regex);
}
@@ -408,8 +408,8 @@ mbgl::optional<Manifest> ManifestParser::parseManifest(const std::string& manife
continue;
}
for (auto& testPath : mbgl::filesystem::recursive_directory_iterator(path)) {
- // Skip paths that fail regexp match.
- if (!testFilter.empty() && !std::regex_match(testPath.path().string(), std::regex(testFilter))) {
+ // Skip paths that fail regexp search.
+ if (!testFilter.empty() && !std::regex_search(testPath.path().string(), std::regex(testFilter))) {
continue;
}
diff --git a/render-test/render_test.cpp b/render-test/render_test.cpp
index e89cab1c1b..3cdd4304c3 100644
--- a/render-test/render_test.cpp
+++ b/render-test/render_test.cpp
@@ -11,6 +11,7 @@
#include "metadata.hpp"
#include "parser.hpp"
#include "runner.hpp"
+#include <mbgl/util/logging.hpp>
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_GREEN "\x1b[32m"
@@ -182,17 +183,20 @@ int runRenderTests(int argc, char** argv) {
status = "passed";
color = "green";
stats.passedTests++;
+ mbgl::Log::Warning(mbgl::Event::General,ANSI_COLOR_RED "* passed %s" ANSI_COLOR_RESET "\n", id.c_str());
printf(ANSI_COLOR_GREEN "* passed %s" ANSI_COLOR_RESET "\n", id.c_str());
} else if (errored) {
status = "errored";
color = "red";
stats.erroredTests++;
+ mbgl::Log::Warning(mbgl::Event::General, ANSI_COLOR_RED "* errored %s" ANSI_COLOR_RESET "\n", id.c_str());
printf(ANSI_COLOR_RED "* errored %s" ANSI_COLOR_RESET "\n", id.c_str());
printf(ANSI_COLOR_RED "* error: %s" ANSI_COLOR_RESET "\n", metadata.errorMessage.c_str());
} else {
status = "failed";
color = "red";
stats.failedTests++;
+ mbgl::Log::Warning(mbgl::Event::General,ANSI_COLOR_RED "* failed %s" ANSI_COLOR_RESET "\n", id.c_str());
printf(ANSI_COLOR_RED "* failed %s" ANSI_COLOR_RESET "\n", id.c_str());
}
}
@@ -208,9 +212,11 @@ int runRenderTests(int argc, char** argv) {
stats.erroredTests + stats.failedTests + stats.ignoreFailedTests + stats.ignorePassedTests + stats.passedTests;
if (stats.passedTests) {
+ mbgl::Log::Warning(mbgl::Event::General, ANSI_COLOR_RED "%u passed (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.passedTests, 100.0 * stats.passedTests / count);
printf(ANSI_COLOR_GREEN "%u passed (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.passedTests, 100.0 * stats.passedTests / count);
}
if (stats.ignorePassedTests) {
+ mbgl::Log::Warning(mbgl::Event::General, ANSI_COLOR_RED "%u passed but were ignored (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.ignorePassedTests, 100.0 * stats.ignorePassedTests / count);
printf(ANSI_COLOR_YELLOW "%u passed but were ignored (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.ignorePassedTests, 100.0 * stats.ignorePassedTests / count);
}
if (stats.ignoreFailedTests) {
diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp
index 3832977cd4..5523336f12 100644
--- a/src/mbgl/style/sources/geojson_source.cpp
+++ b/src/mbgl/style/sources/geojson_source.cpp
@@ -7,6 +7,7 @@
#include <mbgl/style/sources/geojson_source_impl.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/util/logging.hpp>
+#include <mbgl/util/thread_pool.hpp>
namespace mbgl {
namespace style {
@@ -69,18 +70,29 @@ void GeoJSONSource::loadDescription(FileSource& fileSource) {
observer->onSourceError(
*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON")));
} else {
- conversion::Error error;
- std::shared_ptr<GeoJSONData> geoJSONData;
- if (optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*res.data, error)) {
- geoJSONData = GeoJSONData::create(*geoJSON, impl().getOptions());
- } else {
- // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for tiles to load.
- Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s",
- error.message.c_str());
- }
- baseImpl = makeMutable<Impl>(impl(), std::move(geoJSONData));
- loaded = true;
- observer->onSourceLoaded(*this);
+ auto makeImplInBackground = [currentImpl = baseImpl, data = res.data]() -> Immutable<Source::Impl> {
+ assert(data);
+ auto& impl = static_cast<const Impl&>(*currentImpl);
+ conversion::Error error;
+ std::shared_ptr<GeoJSONData> geoJSONData;
+ if (optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*data, error)) {
+ geoJSONData = GeoJSONData::create(*geoJSON, impl.getOptions());
+ } else {
+ // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for tiles to load.
+ Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", error.message.c_str());
+ }
+ return makeMutable<Impl>(impl, std::move(geoJSONData));
+ };
+ auto onImplReady = [this, self = makeWeakPtr(), capturedReq = req.get()](Immutable<Source::Impl> newImpl) {
+ assert(capturedReq);
+ if (!self) return; // This source has been deleted.
+ if (capturedReq != req.get()) return; // A new request is being processed, ignore this impl.
+
+ baseImpl = std::move(newImpl);
+ loaded = true;
+ observer->onSourceLoaded(*this);
+ };
+ Scheduler::GetBackground()->scheduleAndReplyValue(makeImplInBackground, onImplReady);
}
});
}
diff --git a/src/mbgl/util/thread_pool.hpp b/src/mbgl/util/thread_pool.hpp
index 7642f9b4ca..e39c1abc73 100644
--- a/src/mbgl/util/thread_pool.hpp
+++ b/src/mbgl/util/thread_pool.hpp
@@ -60,11 +60,11 @@ private:
static_assert(N > 0, "Thread count must be more than zero.");
};
-using SequencedScheduler = ThreadedScheduler<1>;
+class SequencedScheduler : public ThreadedScheduler<1> {};
template <std::size_t extra>
using ParallelScheduler = ThreadedScheduler<1 + extra>;
-using ThreadPool = ParallelScheduler<3>;
+class ThreadPool : public ParallelScheduler<3> {};
} // namespace mbgl
diff --git a/test/util/async_task.test.cpp b/test/util/async_task.test.cpp
index 682926a17d..214e490fd8 100644
--- a/test/util/async_task.test.cpp
+++ b/test/util/async_task.test.cpp
@@ -151,3 +151,22 @@ TEST(AsyncTask, ThreadSafety) {
// a valid result, although very unlikely (I hope).
EXPECT_GT(count, 0u);
}
+
+TEST(AsyncTask, scheduleAndReplyValue) {
+ RunLoop loop;
+ std::thread::id caller_id = std::this_thread::get_id();
+
+ auto runInBackground = [caller_id]() -> int {
+ EXPECT_NE(caller_id, std::this_thread::get_id());
+ return 42;
+ };
+ auto onResult = [caller_id, &loop](int res) {
+ EXPECT_EQ(caller_id, std::this_thread::get_id());
+ EXPECT_EQ(42, res);
+ loop.stop();
+ };
+
+ auto sheduler = Scheduler::GetBackground();
+ sheduler->scheduleAndReplyValue(runInBackground, onResult);
+ loop.run();
+} \ No newline at end of file