diff options
-rw-r--r-- | circle.yml | 391 | ||||
-rw-r--r-- | include/mbgl/actor/scheduler.hpp | 27 | ||||
-rw-r--r-- | next/platform/android/android.cmake | 2 | ||||
-rw-r--r-- | platform/android/CHANGELOG.md | 1 | ||||
-rw-r--r-- | platform/ios/CHANGELOG.md | 1 | ||||
-rw-r--r-- | render-test/android/app/build.gradle | 12 | ||||
-rw-r--r-- | render-test/manifest_parser.cpp | 20 | ||||
-rw-r--r-- | render-test/render_test.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/style/sources/geojson_source.cpp | 36 | ||||
-rw-r--r-- | src/mbgl/util/thread_pool.hpp | 4 | ||||
-rw-r--r-- | test/util/async_task.test.cpp | 19 |
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 |