diff --git a/.gitignore b/.gitignore index d8959d4f3..2ea84e982 100644 --- a/.gitignore +++ b/.gitignore @@ -16,8 +16,15 @@ /test/build /test/node_modules /test/fixtures/*/*_actual.* +/test/fixtures/api/1.png +/test/fixtures/api/2.png +/test/fixtures/database/*.db /include/mbgl/shader/shaders.hpp /src/shader/shaders_gl.cpp /src/shader/shaders_gles2.cpp /bin/style.bin.js *~ + +/ios/benchmark/assets/tiles/mapbox.mapbox-streets-v6/ +/ios/benchmark/assets/tiles/mapbox.mapbox-terrain-v2/ +/ios/benchmark/assets/glyphs/DIN Offc Pro*/ diff --git a/.mason b/.mason index 03869fd11..c43967404 160000 --- a/.mason +++ b/.mason @@ -1 +1 @@ -Subproject commit 03869fd11e4bc619d3ba7e4f8a1f00d4612c90ea +Subproject commit c43967404c84d020d63f6aba450d97770dfeaebb diff --git a/.travis.yml b/.travis.yml index 71936b872..f08aa8149 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,100 +1,105 @@ -language: cpp +language: android + +sudo: false matrix: exclude: - os: linux include: - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v7 TESTMUNK=yes - compiler: clang + env: FLAVOR=linux CXX=g++-4.9 BUILDTYPE=Release + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'gdb', 'g++-4.9', 'gcc-4.9', 'libllvm3.4', 'xutils-dev', 'libxxf86vm-dev', 'x11proto-xf86vidmode-dev', 'mesa-utils' ] - os: linux - env: CONFIG=debug MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v7 TESTMUNK=no - compiler: clang + env: FLAVOR=linux CXX=clang++-3.5 BUILDTYPE=Debug + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.5' ] + packages: [ 'gdb', 'clang-3.5', 'libstdc++-4.9-dev', 'libstdc++6', 'libllvm3.4', 'xutils-dev', 'libxxf86vm-dev', 'x11proto-xf86vidmode-dev', 'mesa-utils' ] - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v5 TESTMUNK=no - compiler: clang - - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v8 TESTMUNK=no - compiler: clang - - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=x86 TESTMUNK=no - compiler: clang - - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=mips TESTMUNK=no - compiler: clang - - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=mips-64 TESTMUNK=no - compiler: clang - - os: linux - env: BUILDTYPE=Release JOBS=16 - compiler: clang - - os: linux - env: BUILDTYPE=Debug JOBS=16 - compiler: clang - - os: linux - env: BUILDTYPE=Release JOBS=8 - compiler: gcc + env: FLAVOR=linux CXX=clang++-3.5 BUILDTYPE=Release + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.5' ] + packages: [ 'gdb', 'clang-3.5', 'libstdc++-4.9-dev', 'libstdc++6', 'libllvm3.4', 'xutils-dev', 'libxxf86vm-dev', 'x11proto-xf86vidmode-dev', 'mesa-utils' ] - os: osx - env: BUILDTYPE=Debug JOBS=8 MASON_PLATFORM=osx - compiler: clang + env: FLAVOR=osx BUILDTYPE=Debug - os: osx - env: BUILDTYPE=Release JOBS=8 MASON_PLATFORM=ios - compiler: clang + env: FLAVOR=ios BUILDTYPE=Release + - os: linux + env: FLAVOR=android ANDROID_ABI=arm-v7 BUILDTYPE=Release + android: + components: [ 'build-tools-22.0.1', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] + - os: linux + env: FLAVOR=android ANDROID_ABI=arm-v7 BUILDTYPE=Debug + android: + components: [ 'build-tools-22.0.1', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] + - os: linux + env: FLAVOR=android ANDROID_ABI=arm-v8 BUILDTYPE=Release + android: + components: [ 'build-tools-22.0.1', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] + - os: linux + env: FLAVOR=android ANDROID_ABI=x86 BUILDTYPE=Release + android: + components: [ 'build-tools-22.0.1', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] + - os: linux + env: FLAVOR=android ANDROID_ABI=mips BUILDTYPE=Release + android: + components: [ 'build-tools-22.0.1', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] env: global: - - secure: "MZHblLZXG/jWf2w0ZFlxCLDwx2qtGgRDODQyg1BR7JIuMz6AtWv8XR/sUczWLbiABCL0a/NzJF1g4v2pI7X69IntcjOdIABBgTh7++6+1TJ0Kp8viEltb55nQG3lHy/R6fOaI7Pj9tuCX0PCRtGA5C/fGnodLGEjy3RVOJ09ln0=" - - secure: "KaSQbhgjtV7ZCkesHmvrNsbQVjk5SPfGKB1VkWenRGYhLF45HpSRNwSxMQddZ566Pg7qIFgF1iWl/B0QW3B6AWL5WmzQ5AOJgwS876pNIc/UT7ubMPtgAtjpvw1bQvQP3B8MrB+3OE5c6tD+a3LhR9krV//dOsfErR5Yy+3Mbkc=" - - ANDROID_BUILD_INSTANCE_PROFILE: arn:aws:iam::234858372212:instance-profile/android-gl-build/travis/instance-profile/travis-mapbox-gl-native-AndroidInstanceProfile-13EA815DD8IQ9 - - secure: "RiBIBfVhhaMjU5ksuwJO3shdvG9FpinBjdSv4co9jg9171SR8edNriedHjVKSIeBhSGNmZmX+twS3dJS/By6tl/LKh9sTynA+ZAYYljkE7jn881B/gMrlYvdAA6og5KvkhV1/0iJWlhuZrMTkhpDR200iLgg3EWBhWjltzmDW/I=" - - secure: "CHBiUM60TolDbQnn+4IRA/tvOKwKs3g9EDvv8YHSJMg3FuHmjKQkprBasvxf3hnTXg4WLZEubmeDcyJ6RRzPP5mMSr/hksYl0pSjj/6TUecE5fHPVVeN7txVqkpOBf9i45Y+iBUQMjBb1NnDK3pHXxpnAs1Q/pe7vReErj4GF1U=" - - LD_LIBRARY_PATH: '/usr/local/lib' - - TERM: dumb - # begin iOS code signing - - secure: "I6Iu75X1E+js5tzijtKi1EGtIuBcA4/25nDYe0svV4HAtujY71ZJZ4eB6355CKhFXpLXrF3i7eKVX3v+zWS0QROPEWacgsqsvNg+Ba9cnznW/faUSOYekCfhzWd/6reYDM7KzKAQwSUHLk9JIWK/kkmi4r+vVJK7h+tjPllK5YA=" - - IOS_APP_NAME="Mapbox GL" - - 'IOS_DEVELOPER_NAME="iPhone Distribution: Mapbox, Inc."' - - IOS_PROFILE_NAME="ios-in-house" - - secure: "nQqSM8rd7OHtV4MqmNqVnkrVHqxKqQsaWRYk4/nPdhbeVWtTtkk0df711LrF1TUtbEPEewHxYUvTZ/UXmwJNeoKdzTHavI8hnatRkgjyxGERPn1il1Otelht9I+LQQHf+plrpRjVWBrNIW0Zox1B3cqn6d3NglpbXrEQ2EjYGNA=" - # end iOS code signing - - KIF_SCREENSHOTS="${TRAVIS_BUILD_DIR}/screenshots" + - TERM: dumb + # AWS + - secure: "MZHblLZXG/jWf2w0ZFlxCLDwx2qtGgRDODQyg1BR7JIuMz6AtWv8XR/sUczWLbiABCL0a/NzJF1g4v2pI7X69IntcjOdIABBgTh7++6+1TJ0Kp8viEltb55nQG3lHy/R6fOaI7Pj9tuCX0PCRtGA5C/fGnodLGEjy3RVOJ09ln0=" + - secure: "KaSQbhgjtV7ZCkesHmvrNsbQVjk5SPfGKB1VkWenRGYhLF45HpSRNwSxMQddZ566Pg7qIFgF1iWl/B0QW3B6AWL5WmzQ5AOJgwS876pNIc/UT7ubMPtgAtjpvw1bQvQP3B8MrB+3OE5c6tD+a3LhR9krV//dOsfErR5Yy+3Mbkc=" + # Access Token + - secure: "RiBIBfVhhaMjU5ksuwJO3shdvG9FpinBjdSv4co9jg9171SR8edNriedHjVKSIeBhSGNmZmX+twS3dJS/By6tl/LKh9sTynA+ZAYYljkE7jn881B/gMrlYvdAA6og5KvkhV1/0iJWlhuZrMTkhpDR200iLgg3EWBhWjltzmDW/I=" + # Testmunk + - secure: "CHBiUM60TolDbQnn+4IRA/tvOKwKs3g9EDvv8YHSJMg3FuHmjKQkprBasvxf3hnTXg4WLZEubmeDcyJ6RRzPP5mMSr/hksYl0pSjj/6TUecE5fHPVVeN7txVqkpOBf9i45Y+iBUQMjBb1NnDK3pHXxpnAs1Q/pe7vReErj4GF1U=" + # iOS code signing + - secure: "I6Iu75X1E+js5tzijtKi1EGtIuBcA4/25nDYe0svV4HAtujY71ZJZ4eB6355CKhFXpLXrF3i7eKVX3v+zWS0QROPEWacgsqsvNg+Ba9cnznW/faUSOYekCfhzWd/6reYDM7KzKAQwSUHLk9JIWK/kkmi4r+vVJK7h+tjPllK5YA=" + - IOS_APP_NAME="Mapbox GL" + - 'IOS_DEVELOPER_NAME="iPhone Distribution: Mapbox, Inc."' + - IOS_PROFILE_NAME="ios-in-house" + - secure: "nQqSM8rd7OHtV4MqmNqVnkrVHqxKqQsaWRYk4/nPdhbeVWtTtkk0df711LrF1TUtbEPEewHxYUvTZ/UXmwJNeoKdzTHavI8hnatRkgjyxGERPn1il1Otelht9I+LQQHf+plrpRjVWBrNIW0Zox1B3cqn6d3NglpbXrEQ2EjYGNA=" + - KIF_SCREENSHOTS="${TRAVIS_BUILD_DIR}/screenshots" before_install: -- if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then sudo service mysql stop; fi -- if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then sudo service postgresql stop; fi -- source ./scripts/local_mason.sh - source ./scripts/travis_helper.sh -- source ./scripts/install_node.sh -- source ./scripts/flags.sh -- ./scripts/travis_before_install.sh -- if [[ ${TRAVIS_OS_NAME} == "linux" && ${MASON_PLATFORM} != "android" ]]; then export LD_LIBRARY_PATH=`mason prefix mesa 10.4.3`/lib; fi -- if [[ ${TRAVIS_OS_NAME} == "linux" && ${MASON_PLATFORM} != "android" ]]; then glxinfo; fi -- if [[ ${TRAVIS_OS_NAME} == "osx" && ${TEST_OS} == "ios" ]]; then mkdir -p ${KIF_SCREENSHOTS}; fi install: -- ulimit -c - -before_script: - # Set the core file limit to unlimited so a core file is generated upon crash - - ulimit -c unlimited -S - # begin iOS code signing - - openssl aes-256-cbc -k "$IOS_ENCRYPTION_SECRET" -in scripts/ios_travis/ios-in-house.mobileprovision.enc -d -a -out scripts/ios_travis/ios-in-house.mobileprovision - - openssl aes-256-cbc -k "$IOS_ENCRYPTION_SECRET" -in scripts/ios_travis/ios-dist.cer.enc -d -a -out scripts/ios_travis/ios-dist.cer - - openssl aes-256-cbc -k "$IOS_ENCRYPTION_SECRET" -in scripts/ios_travis/ios-dist.p12.enc -d -a -out scripts/ios_travis/ios-dist.p12 - - ./scripts/ios_travis/add-key.sh - # end iOS code signing +- ./scripts/${FLAVOR}/install.sh script: -- ./scripts/travis_script.sh - -after_script: -- ./scripts/ios_travis/remove-key.sh +- ./scripts/${FLAVOR}/run.sh after_failure: -- if [[ ${TRAVIS_OS_NAME} == "osx" && ${TEST_OS} == "ios" ]]; then ./scripts/ios_travis/upload_screenshots.sh; fi +- "[ -f ./scripts/${FLAVOR}/after_failure.sh ] && ./scripts/${FLAVOR}/after_failure.sh" + +after_failure: +- "[ -f ./scripts/${FLAVOR}/after_script.sh ] && ./scripts/${FLAVOR}/after_script.sh" notifications: slack: secure: HHQYr7sF8M1SzoWSqgKVYtwAgGdLLCyTMsQjFhEEQNYO92ZwURE5s03qWTGH5k8+4Yqn26yrXt3NztLC4JIOpcGervN2mSZyq4dZgFTcWEd61igw0qwSenlwvFfbE1ASK/KYCzfyn9MIfHN+ovwLoRxXZkPwinKDvl3DXjBaFNg= + git: submodules: false diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..a417af376 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +## 0.3.1 + +- Temporarily removed `IBDesignable` support on iOS. + +## 0.3.0 + +- Initial iOS beta release. + +Known issues: + +- None. diff --git a/Makefile b/Makefile index 11eb5e530..748105102 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,8 @@ endif ifeq ($(shell uname -s), Linux) HOST = linux -JOBS ?= $(shell sysctl -n hw.ncpu) +JOBS ?= $(shell grep --count processor /proc/cpuinfo) +BUILD_ROOT = $(shell pwd) endif JOBS ?= 1 @@ -31,8 +32,12 @@ config/%.gypi: configure styles/styles: git submodule update --init styles +ifeq ($(shell uname -s), Darwin) SMCalloutView: git submodule update --init platform/ios/vendor/SMCalloutView +else +SMCalloutView: +endif KIF: git submodule update --init test/ios/KIF @@ -42,11 +47,11 @@ KIF: .PRECIOUS: Makefile/project Makefile/project: config/$(HOST).gypi styles/styles SMCalloutView - deps/run_gyp gyp/project.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make + deps/run_gyp gyp/$(HOST).gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make .PRECIOUS: Xcode/project Xcode/project: config/$(HOST).gypi styles/styles SMCalloutView - deps/run_gyp gyp/project.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f xcode + deps/run_gyp gyp/$(HOST).gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f xcode #### Library builds ############################################################ @@ -71,8 +76,9 @@ test-%: test ./scripts/run_tests.sh "build/$(HOST)/$(BUILDTYPE)/test" --gtest_filter=$* .PHONY: xtest +xtest: XCPRETTY := $(shell ./scripts/xcpretty.sh) xtest: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS) + xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS) $(XCPRETTY) xtest-%: xtest ./scripts/run_tests.sh "build/osx/Build/Products/$(BUILDTYPE)/test" --gtest_filter=$* @@ -87,12 +93,16 @@ osx: Makefile/project run-osx: osx "build/osx/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL" +run-valgrind-osx: osx + (valgrind --leak-check=full --suppressions=scripts/valgrind.sup build/osx/$(BUILDTYPE)/Mapbox\ GL.app/Contents/MacOS/Mapbox\ GL) + .PHONY: xosx-proj xosx run-xosx xosx-proj: Xcode/project - open ./build/osx/gyp/project.xcodeproj + open ./build/osx/gyp/osx.xcodeproj +xosx: XCPRETTY := $(shell ./scripts/xcpretty.sh) xosx: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS) + xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS) $(XCPRETTY) run-xosx: xosx "gyp/build/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL" @@ -105,24 +115,33 @@ xproj: xosx-proj #### iOS application builds #################################################### .PRECIOUS: Xcode/ios -Xcode/ios: ios/app/mapboxgl-app.gyp config/ios.gypi styles/styles SMCalloutView - deps/run_gyp ios/app/mapboxgl-app.gyp $(CONFIG_ios) $(LIBS_ios) --generator-output=./build/ios -f xcode +Xcode/ios: gyp/ios.gyp config/ios.gypi styles/styles SMCalloutView + deps/run_gyp gyp/ios.gyp $(CONFIG_ios) $(LIBS_ios) --generator-output=./build/ios -f xcode .PHONY: ios-proj ios isim ipackage ios-proj: Xcode/ios - open ./build/ios/ios/app/mapboxgl-app.xcodeproj + open ./build/ios/gyp/ios.xcodeproj +ios: XCPRETTY := $(shell ./scripts/xcpretty.sh) ios: Xcode/ios - xcodebuild -sdk iphoneos ARCHS="arm64 armv7 armv7s" PROVISIONING_PROFILE="2b532944-bf3d-4bf4-aa6c-a81676984ae8" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Release -target iosapp -jobs $(JOBS) + xcodebuild -sdk iphoneos ARCHS="arm64 armv7 armv7s" PROVISIONING_PROFILE="19324a54-7455-4f0b-8e1c-e6957c718ebc" -project ./build/ios/gyp/ios.xcodeproj -configuration Release -target iosapp -jobs $(JOBS) $(XCPRETTY) +ibench: XCPRETTY := $(shell ./scripts/xcpretty.sh) +ibench: Xcode/ios + xcodebuild -sdk iphoneos ARCHS="arm64" PROVISIONING_PROFILE="19324a54-7455-4f0b-8e1c-e6957c718ebc" -project ./build/ios/gyp/ios.xcodeproj -configuration Release -target ios-bench -jobs $(JOBS) $(XCPRETTY) + +isim: XCPRETTY := $(shell ./scripts/xcpretty.sh) isim: Xcode/ios - xcodebuild -sdk iphonesimulator ARCHS="x86_64 i386" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Debug -target iosapp -jobs $(JOBS) + xcodebuild -sdk iphonesimulator ARCHS="x86_64 i386" -project ./build/ios/gyp/ios.xcodeproj -configuration Debug -target iosapp -jobs $(JOBS) $(XCPRETTY) -ipackage: clean Xcode/ios - ./scripts/package_ios.sh +ipackage: Xcode/ios + JOBS=$(JOBS) ./scripts/ios/package.sh -itest: ipackage KIF - ./scripts/test_ios.sh +ipackage-sim: Xcode/ios + JOBS=$(JOBS) ./scripts/ios/package.sh sim + +itest: ipackage-sim KIF + ./scripts/ios/test.sh # Legacy name iproj: ios-proj @@ -137,9 +156,13 @@ linux: Makefile/project run-linux: linux (cd build/$(HOST)/$(BUILDTYPE) && ./mapbox-gl) +run-valgrind-linux: linux + (cd build/$(HOST)/$(BUILDTYPE) && valgrind --leak-check=full --suppressions=$(BUILD_ROOT)/scripts/valgrind.sup ./mapbox-gl) + .PHONY: xlinux run-xlinux +xlinux: XCPRETTY := $(shell ./scripts/xcpretty.sh) xlinux: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target linuxapp -jobs $(JOBS) + xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target linuxapp -jobs $(JOBS) $(XCPRETTY) run-xlinux: xlinux "gyp/build/$(BUILDTYPE)/mapbox-gl" @@ -180,9 +203,10 @@ android-project: android-lib render: Makefile/project $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) mbgl-render -.PHONY: xrender run-xrender +.PHONY: xrender +xrender: XCPRETTY := $(shell ./scripts/xcpretty.sh) xrender: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target mbgl-render -jobs $(JOBS) + xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target mbgl-render -jobs $(JOBS) $(XCPRETTY) ##### Maintenace operations #################################################### diff --git a/README.md b/README.md index a44b13861..6b15f596c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ [![Travis](https://api.travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) -An OpenGL renderer for [Mapbox Vector Tiles](https://www.mapbox.com/blog/vector-tiles), -implemented in C++11, currently targeting iOS, OS X, Android, and Ubuntu Linux. +An OpenGL renderer for [Mapbox Vector Tiles](https://www.mapbox.com/blog/vector-tiles), consisting of a C++ library for OS X and Linux and SDK bindings for iOS and Android. # Depends - - Modern C++ compiler that supports `-std=c++11` (On OS X clang++, on Linux g++-4.8 or g++-4.9) + - Modern C++ compiler that supports `-std=c++14` (clang++ 3.5 or later or g++-4.9 or later) - [Boost headers](http://boost.org/) - [`zlib`](http://www.zlib.net/) - [`libpng`](http://www.libpng.org/pub/png/libpng.html) @@ -46,15 +45,27 @@ Target OS X: 10.9+ ## iOS -If you merely want to install the library for iOS and try it out as an Objective-C consumer: +### Use -0. Use [Homebrew](http://brew.sh/) to install Boost headers: `brew install boost`. -1. Run `./scripts/package_ios.sh`. The packaging script will produce the statically-linked `libMapboxGL.a`, `MapboxGL.bundle` for resources, and a `Headers` folder. -2. Copy the contents of `build/ios/pkg/static` into your project. It should happen automatically, but ensure that: +#### CocoaPods + +[CocoaPods](https://cocoapods.org) is preferred. Put the following in your `Podfile`: + +```ruby +use_frameworks! +pod 'MapboxGL' +``` + +#### Manually + +1. Use [Homebrew](http://brew.sh/) to install Boost headers: `brew install boost`. +1. Install [appledoc](http://appledoc.gentlebytes.com/appledoc/) for API docs generation. We recommend [`2.2v963`](https://github.com/tomaz/appledoc/releases/tag/v2.2-963), which currently isn't available in Homebrew. +1. Run `make ipackage`. The packaging script will produce the statically-linked `libMapboxGL.a`, `MapboxGL.bundle` for resources, a `Headers` folder, and a `Docs` folder with HTML API documentation. +1. Copy the contents of `build/ios/pkg/static` into your project. It should happen automatically, but ensure that: - `Headers` is in your *Header Search Paths* (`HEADER_SEARCH_PATHS`) build setting. - `MapboxGL.bundle` is in your target's *Copy Bundle Resources* build phase. - `libMapboxGL.a` is in your target's *Link Binary With Libraries* build phase. -3. Add the following Cocoa framework dependencies to your target's *Link Binary With Libraries* build phase: +1. Add the following Cocoa framework dependencies to your target's *Link Binary With Libraries* build phase: - `CoreTelephony.framework` - `GLKit.framework` - `ImageIO.framework` @@ -64,28 +75,31 @@ If you merely want to install the library for iOS and try it out as an Objective - `libc++.dylib` - `libsqlite3.dylib` - `libz.dylib` -4. Add `-ObjC` to your target's "Other Linker Flags" build setting (`OTHER_LDFLAGS`). -5. [Set the Mapbox API access token](#mapbox-api-access-tokens). -6. `#import "MapboxGL.h"` +1. Add `-ObjC` to your target's "Other Linker Flags" build setting (`OTHER_LDFLAGS`). +1. [Set the Mapbox API access token](#mapbox-api-access-tokens). +1. `#import "MapboxGL.h"` -If you want to build from source and/or contribute to development of the project, run `make iproj`, which will create and open an Xcode project which can build the entire library from source as well as an Objective-C test app. +### Development -You can also run `make itest` to run the included tests. Requires `brew install xcpretty`. +If you want to build from source and/or contribute to development of the project, run `make iproj`, which will create and open an Xcode project which can build the entire library from source as well as an Objective-C test app. If you don't have an Apple Developer account, change the destination from "My Mac" to a simulator such as "iPhone 6" before you run and build the app. + +You can run `make itest` to run the included integration tests. Requires `gem install xcpretty`. If you want to run the tests in Xcode instead, first `make ipackage` to create a local static library version, then open `test/ios/ios-tests.xcodeproj`, and lastly `Command + U` on the `Mapbox GL Tests` application target. Target devices: iPhone 4S and above (5, 5c, 5s, 6, 6 Plus) and iPad 2 and above (3, 4, Mini, Air, Mini 2, Air 2). -Target iOS: 7.0 through 8.1 +Target iOS: 7.0 through latest 8.x. ## Linux We are using Ubuntu for development. While the software should work on other distributions as well, we are not providing explicit build instructions here. -Install GCC 4.8+ if you are running Ubuntu 13.10 or older. Alternatively, you can also use Clang 3.4+. +Install GCC 4.9+ if you are running Ubuntu 13.10 or older. Alternatively, you can also use Clang 3.5+. sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test sudo apt-get update - sudo apt-get install gcc-4.8 g++-4.8 + sudo apt-get install gcc-4.9 g++-4.9 + export CXX=g++-4.9 Ensure you have git and other build essentials: @@ -110,10 +124,6 @@ Otherwise, you can just install sudo apt-get install libboost-dev libboost-program-options-dev -Once you're done installing the build dependencies, you can get started by running - - ./configure - Then, you can then proceed to build the library: git submodule update --init @@ -184,6 +194,35 @@ Run: You can then open `android/java` in Android Studio via "Import Non-Android Studio Project". +### Setting up Android emulator + +If you want to run the test app in the emulator, we recommend the x86 build because it will run a lot faster. + +First ensure you have an `MAPBOX_ACCESS_TOKEN` environment variable set, as described below. Then, create an x86 build: + + ANDROID_ABI=x86 make android + +In Android Studio, create an x86 AVD (Android Virtual Device): +- Open AVD Manager via the Tools menu -> Android -> AVD Manager +- Click "Create Virtual Device" at the bottom on AVD Manager window +- Select one of the device profiles, for example the Nexus 4 +- Click "Next" +- Select a Lollipop or Kitkat release with ABI of x86. If the line is greyed out click Download to download the OS files. +- Click "Next" +- Under "Emulated Performance" check "Host GPU" and uncheck "Store a snapshot for faster startup" +- Click "Finish" +- Close the AVD Manager + +Now when you run or debug the Android project you will see a window "Choose Device". Select your new AVD from drop down under "Launch emulator". If you select "Use same device for future launches" Android Studio will remember the selection and not ask again. + +### Running on a hardware device + +First read the [Google documentation](http://developer.android.com/tools/device.html) to set up your device and your OS to connect to the device. + +When you plug your device in and then run or debug the Android project you will see a window "Choose Device". Choose your device from the "Choose a running device" list. + +If your device does not show you have not set it up properly, double check the [Google documentation](http://developer.android.com/tools/device.html). + # Troubleshooting To trigger a complete rebuild, run `make clean` and then start over generating the Xcode projects or Makefiles as described above. @@ -204,7 +243,7 @@ For iOS and OS X use of the demo apps in Xcode, setup the access token by editin For Linux, set the environment variable `MAPBOX_ACCESS_TOKEN` to your token. -For Android, gradle will take the value of `MAPBOX_ACCESS_TOKEN` and save it to `android/java/app/src/main/res/raw/token.txt` where the app will read it from. +For Android, gradle will take the value of `MAPBOX_ACCESS_TOKEN` and save it to `android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw/token.txt` where the app will read it from. # Style diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp index ac5188484..2c7e75778 100644 --- a/android/cpp/jni.cpp +++ b/android/cpp/jni.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -255,20 +256,6 @@ void JNICALL nativeDestroySurface(JNIEnv *env, jobject obj, jlong nativeMapViewP nativeMapView->destroySurface(); } -void JNICALL nativeStart(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeStart"); - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->start(); -} - -void JNICALL nativeStop(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeStop"); - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->stop(); -} - void JNICALL nativePause(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativePause"); assert(nativeMapViewPtr != 0); @@ -287,14 +274,7 @@ void JNICALL nativeUpdate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeUpdate"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().triggerUpdate(); -} - -void JNICALL nativeTerminate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeTerminate"); - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().terminate(); + nativeMapView->getMap().update(); } void JNICALL nativeResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint width, jint height, @@ -310,7 +290,7 @@ void JNICALL nativeResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint assert(fbWidth <= UINT16_MAX); assert(fbHeight <= UINT16_MAX); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->resize(width, height, ratio, fbWidth, fbHeight); + nativeMapView->getMap().resize(width, height, ratio); } void JNICALL nativeRemoveClass(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring clazz) { @@ -938,12 +918,9 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { {"nativeCreateSurface", "(JLandroid/view/Surface;)V", reinterpret_cast(&nativeCreateSurface)}, {"nativeDestroySurface", "(J)V", reinterpret_cast(&nativeDestroySurface)}, - {"nativeStart", "(J)V", reinterpret_cast(&nativeStart)}, - {"nativeStop", "(J)V", reinterpret_cast(&nativeStop)}, {"nativePause", "(J)V", reinterpret_cast(&nativePause)}, {"nativeResume", "(J)V", reinterpret_cast(&nativeResume)}, {"nativeUpdate", "(J)V", reinterpret_cast(&nativeUpdate)}, - {"nativeTerminate", "(J)V", reinterpret_cast(&nativeTerminate)}, {"nativeResize", "(JIIFII)V", reinterpret_cast(static_cast(&nativeResize))}, diff --git a/android/cpp/native_map_view.cpp b/android/cpp/native_map_view.cpp index 39a777bff..03530aeff 100644 --- a/android/cpp/native_map_view.cpp +++ b/android/cpp/native_map_view.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -16,9 +17,6 @@ #include #include - -pthread_once_t loadGLExtensions = PTHREAD_ONCE_INIT; - namespace mbgl { namespace android { @@ -59,9 +57,11 @@ NativeMapView::NativeMapView(JNIEnv *env, jobject obj_) : mbgl::View(*this), fileCache(mbgl::android::cachePath + "/mbgl-cache.db"), fileSource(&fileCache), - map(*this, fileSource) { + map(*this, fileSource, MapMode::Continuous) { mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::NativeMapView"); + map.pause(); + assert(env != nullptr); assert(obj_ != nullptr); @@ -114,18 +114,22 @@ void NativeMapView::activate() { void NativeMapView::deactivate() { mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::deactivate"); - if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { - mbgl::Log::Error(mbgl::Event::OpenGL, "eglMakeCurrent(EGL_NO_CONTEXT) returned error %d", - eglGetError()); - throw new std::runtime_error("eglMakeCurrent() failed"); + if (display != EGL_NO_DISPLAY) { + if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { + mbgl::Log::Error(mbgl::Event::OpenGL, "eglMakeCurrent(EGL_NO_CONTEXT) returned error %d", + eglGetError()); + throw new std::runtime_error("eglMakeCurrent() failed"); + } + } else { + mbgl::Log::Info(mbgl::Event::Android, "Not deactivating as we are not ready"); } } -void NativeMapView::invalidate() { +void NativeMapView::invalidate(std::function render) { mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::invalidate"); if ((display != EGL_NO_DISPLAY) && (surface != EGL_NO_SURFACE)) { - map.render(); + render(); if (!eglSwapBuffers(display, surface)) { mbgl::Log::Error(mbgl::Event::OpenGL, "eglSwapBuffers() returned error %d", @@ -300,8 +304,6 @@ void NativeMapView::terminateContext() { context = EGL_NO_CONTEXT; } -void loadExtensions(); - void NativeMapView::createSurface(ANativeWindow *window_) { mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::createSurface"); @@ -341,9 +343,11 @@ void NativeMapView::createSurface(ANativeWindow *window_) { "SL Version"); // In the emulator this returns NULL with error code 0? // https://code.google.com/p/android/issues/detail?id=78977 } - log_gl_string(GL_EXTENSIONS, "Extensions"); - pthread_once(&loadGLExtensions, loadExtensions); + log_gl_string(GL_EXTENSIONS, "Extensions"); + mbgl::gl::InitializeExtensions([] (const char * name) { + return reinterpret_cast(eglGetProcAddress(name)); + }); if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { mbgl::Log::Error(mbgl::Event::OpenGL, @@ -358,7 +362,7 @@ void NativeMapView::createSurface(ANativeWindow *window_) { void NativeMapView::destroySurface() { mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::destroySurface"); - pause(true); + pause(); if (surface != EGL_NO_SURFACE) { if (!eglDestroySurface(display, surface)) { @@ -576,133 +580,11 @@ EGLConfig NativeMapView::chooseConfig(const EGLConfig configs[], EGLint numConfi return configId; } -void NativeMapView::start() { - mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::start"); - - if (display == EGL_NO_DISPLAY) { - initializeDisplay(); - } - - if (context == EGL_NO_CONTEXT) { - initializeContext(); - } - - assert(display != EGL_NO_DISPLAY); - assert(context != EGL_NO_CONTEXT); - - map.start(true); -} - -void loadExtensions() { - const GLubyte *str = glGetString(GL_EXTENSIONS); - if (str == nullptr) { - mbgl::Log::Error(mbgl::Event::OpenGL, "glGetString(GL_EXTENSIONS) returned error %d", - glGetError()); - return; - } - - std::string extensions(reinterpret_cast(str)); - - if (extensions.find("GL_OES_vertex_array_object") != std::string::npos) { - mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_OES_vertex_array_object."); - gl::BindVertexArray = reinterpret_cast( - eglGetProcAddress("glBindVertexArrayOES")); - gl::DeleteVertexArrays = reinterpret_cast( - eglGetProcAddress("glDeleteVertexArraysOES")); - gl::GenVertexArrays = reinterpret_cast( - eglGetProcAddress("glGenVertexArraysOES")); - gl::IsVertexArray = - reinterpret_cast(eglGetProcAddress("glIsVertexArrayOES")); - assert(gl::BindVertexArray != nullptr); - assert(gl::DeleteVertexArrays != nullptr); - assert(gl::GenVertexArrays != nullptr); - assert(gl::IsVertexArray != nullptr); - } - - if (extensions.find("GL_OES_packed_depth_stencil") != std::string::npos) { - mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_OES_packed_depth_stencil."); - gl::isPackedDepthStencilSupported = true; - } - - if (extensions.find("GL_OES_depth24") != std::string::npos) { - gl::isDepth24Supported = true; - } - - if (extensions.find("GL_KHR_debug") != std::string::npos) { - mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_KHR_debug."); - gl::DebugMessageControl = reinterpret_cast( - eglGetProcAddress("glDebugMessageControl")); - gl::DebugMessageInsert = reinterpret_cast( - eglGetProcAddress("glDebugMessageInsert")); - gl::DebugMessageCallback = reinterpret_cast( - eglGetProcAddress("glDebugMessageCallback")); - gl::GetDebugMessageLog = reinterpret_cast( - eglGetProcAddress("glGetDebugMessageLog")); - gl::GetPointerv = - reinterpret_cast(eglGetProcAddress("glGetPointerv")); - gl::PushDebugGroup = - reinterpret_cast(eglGetProcAddress("glPushDebugGroup")); - gl::PopDebugGroup = - reinterpret_cast(eglGetProcAddress("glPopDebugGroup")); - gl::ObjectLabel = - reinterpret_cast(eglGetProcAddress("glObjectLabel")); - gl::GetObjectLabel = - reinterpret_cast(eglGetProcAddress("glGetObjectLabel")); - gl::ObjectPtrLabel = - reinterpret_cast(eglGetProcAddress("glObjectPtrLabel")); - gl::GetObjectPtrLabel = reinterpret_cast( - eglGetProcAddress("glGetObjectPtrLabel")); - assert(gl::DebugMessageControl != nullptr); - assert(gl::DebugMessageInsert != nullptr); - assert(gl::DebugMessageCallback != nullptr); - assert(gl::GetDebugMessageLog != nullptr); - assert(gl::GetPointerv != nullptr); - assert(gl::PushDebugGroup != nullptr); - assert(gl::PopDebugGroup != nullptr); - assert(gl::ObjectLabel != nullptr); - assert(gl::GetObjectLabel != nullptr); - assert(gl::ObjectPtrLabel != nullptr); - assert(gl::GetObjectPtrLabel != nullptr); - } else { - if (extensions.find("GL_EXT_debug_marker") != std::string::npos) { - mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_EXT_debug_marker."); - gl::InsertEventMarkerEXT = reinterpret_cast( - eglGetProcAddress("glInsertEventMarkerEXT")); - gl::PushGroupMarkerEXT = reinterpret_cast( - eglGetProcAddress("glPushGroupMarkerEXT")); - gl::PopGroupMarkerEXT = reinterpret_cast( - eglGetProcAddress("glPopGroupMarkerEXT")); - assert(gl::InsertEventMarkerEXT != nullptr); - assert(gl::PushGroupMarkerEXT != nullptr); - assert(gl::PopGroupMarkerEXT != nullptr); - } - - if (extensions.find("GL_EXT_debug_label") != std::string::npos) { - mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_EXT_debug_label."); - gl::LabelObjectEXT = reinterpret_cast( - eglGetProcAddress("glLabelObjectEXT")); - gl::GetObjectLabelEXT = reinterpret_cast( - eglGetProcAddress("glGetObjectLabelEXT")); - assert(gl::LabelObjectEXT != nullptr); - assert(gl::GetObjectLabelEXT != nullptr); - } - } -} - -void NativeMapView::stop() { - mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::stop"); +void NativeMapView::pause() { + mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::pause"); if ((display != EGL_NO_DISPLAY) && (context != EGL_NO_CONTEXT)) { - map.stop(); - } -} - -void NativeMapView::pause(bool waitForPause) { - mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::pause %s", - (waitForPause) ? "true" : "false"); - - if ((display != EGL_NO_DISPLAY) && (context != EGL_NO_CONTEXT)) { - map.pause(waitForPause); + map.pause(); } } @@ -824,9 +706,5 @@ void NativeMapView::updateFps() { env = nullptr; } -void NativeMapView::resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight) { - View::resize(width, height, ratio, fbWidth, fbHeight); -} - } } diff --git a/android/java/MapboxGLAndroidSDK/build.gradle b/android/java/MapboxGLAndroidSDK/build.gradle index 901aa6d9d..f0659b8c7 100644 --- a/android/java/MapboxGLAndroidSDK/build.gradle +++ b/android/java/MapboxGLAndroidSDK/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.1.3' + classpath 'com.android.tools.build:gradle:1.2.2' classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0' } } @@ -29,9 +29,9 @@ repositories { dependencies { compile 'commons-validator:commons-validator:1.4.1' - compile 'com.android.support:support-annotations:22.0.0' - compile 'com.android.support:support-v4:22.0.0' - compile 'com.squareup.okhttp:okhttp:2.2.0' + compile 'com.android.support:support-annotations:22.1.1' + compile 'com.android.support:support-v4:22.1.1' + compile 'com.squareup.okhttp:okhttp:2.3.0' } android { diff --git a/android/java/MapboxGLAndroidSDK/gradle.properties b/android/java/MapboxGLAndroidSDK/gradle.properties index 79e2dadca..8ba98ea4f 100644 --- a/android/java/MapboxGLAndroidSDK/gradle.properties +++ b/android/java/MapboxGLAndroidSDK/gradle.properties @@ -14,7 +14,7 @@ POM_DEVELOPER_NAME=Mapbox ANDROID_MIN_SDK=8 ANDROID_BUILD_TARGET_SDK_VERSION=22 -ANDROID_BUILD_TOOLS_VERSION=22.0.0 +ANDROID_BUILD_TOOLS_VERSION=22.0.1 ANDROID_BUILD_SDK_VERSION=22 POM_NAME=Mapbox GL Android SDK diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java index f865f9144..da4b40c4c 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java @@ -419,7 +419,6 @@ public class MapView extends SurfaceView { mNativeMapView.initializeDisplay(); mNativeMapView.initializeContext(); - mNativeMapView.start(); } // Called when we need to save instance state @@ -441,7 +440,6 @@ public class MapView extends SurfaceView { // Called when we need to clean up // Must be called from Activity onDestroy public void onDestroy() { - mNativeMapView.stop(); mNativeMapView.terminateContext(); mNativeMapView.terminateDisplay(); } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java index 4dcd5ef8e..7f074c6db 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java @@ -73,14 +73,6 @@ class NativeMapView { nativeDestroySurface(mNativeMapViewPtr); } - public void start() { - nativeStart(mNativeMapViewPtr); - } - - public void stop() { - nativeStop(mNativeMapViewPtr); - } - public void pause() { nativePause(mNativeMapViewPtr); } @@ -386,18 +378,12 @@ class NativeMapView { private native void nativeDestroySurface(long nativeMapViewPtr); - private native void nativeStart(long nativeMapViewPtr); - - private native void nativeStop(long nativeMapViewPtr); - private native void nativePause(long nativeMapViewPtr); private native void nativeResume(long nativeMapViewPtr); private native void nativeUpdate(long nativeMapViewPtr); - private native void nativeTerminate(long nativeMapViewPtr); - private native void nativeResize(long nativeMapViewPtr, int width, int height, float ratio, int fbWidth, int fbHeight); diff --git a/android/java/MapboxGLAndroidSDKTestApp/build.gradle b/android/java/MapboxGLAndroidSDKTestApp/build.gradle index 7cdd4fc91..5f2db91d7 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/build.gradle +++ b/android/java/MapboxGLAndroidSDKTestApp/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.1.3' + classpath 'com.android.tools.build:gradle:1.2.2' classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0' } } @@ -31,7 +31,7 @@ gradle.projectsEvaluated { android { compileSdkVersion 22 - buildToolsVersion "22.0.0" + buildToolsVersion "22.0.1" repositories { mavenCentral() @@ -74,9 +74,9 @@ dependencies { compile(project(':MapboxGLAndroidSDK')) { transitive = true } - compile 'com.android.support:support-annotations:22.0.0' - compile 'com.android.support:support-v4:22.0.0' - compile 'com.android.support:appcompat-v7:22.0.0' + compile 'com.android.support:support-annotations:22.1.1' + compile 'com.android.support:support-v4:22.1.1' + compile 'com.android.support:appcompat-v7:22.1.1' compile 'com.mapzen.android:lost:1.0.0' } diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java index bd7100d98..65cb17462 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java @@ -128,8 +128,6 @@ public class MainActivity extends ActionBarActivity { mClassSpinner = (Spinner) findViewById(R.id.spinner_class); mOutdoorsClassAdapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(), R.array.outdoors_class_list, android.R.layout.simple_spinner_dropdown_item); - mSatelliteClassAdapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(), - R.array.satellite_class_list, android.R.layout.simple_spinner_dropdown_item); // Prepare for GPS mLocationClient = new LostApiClient.Builder(this).build(); @@ -318,18 +316,37 @@ public class MainActivity extends ActionBarActivity { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { switch (position) { - // Bright + + // Mapbox Streets case 0: - mMapFragment.getMap().setStyleUrl("asset://styles/bright-v7.json"); + mMapFragment.getMap().setStyleUrl("asset://styles/mapbox-streets-v7.json"); mMapFragment.getMap().removeAllClasses(); mClassSpinner.setVisibility(View.INVISIBLE); mClassSpinner.setAdapter(null); mClassSpinner.setOnItemSelectedListener(null); break; - // Basic + // Emerald case 1: - mMapFragment.getMap().setStyleUrl("asset://styles/basic-v7.json"); + mMapFragment.getMap().setStyleUrl("asset://styles/emerald-v7.json"); + mMapFragment.getMap().removeAllClasses(); + mClassSpinner.setVisibility(View.INVISIBLE); + mClassSpinner.setAdapter(null); + mClassSpinner.setOnItemSelectedListener(null); + break; + + // Light + case 2: + mMapFragment.getMap().setStyleUrl("asset://styles/light-v7.json"); + mMapFragment.getMap().removeAllClasses(); + mClassSpinner.setVisibility(View.INVISIBLE); + mClassSpinner.setAdapter(null); + mClassSpinner.setOnItemSelectedListener(null); + break; + + // Dark + case 3: + mMapFragment.getMap().setStyleUrl("asset://styles/dark-v7.json"); mMapFragment.getMap().removeAllClasses(); mClassSpinner.setVisibility(View.INVISIBLE); mClassSpinner.setAdapter(null); @@ -337,7 +354,7 @@ public class MainActivity extends ActionBarActivity { break; // Outdoors - case 2: + case 4: mMapFragment.getMap().setStyleUrl("asset://styles/outdoors-v7.json"); mMapFragment.getMap().removeAllClasses(); mClassSpinner.setVisibility(View.VISIBLE); @@ -345,33 +362,6 @@ public class MainActivity extends ActionBarActivity { mClassSpinner.setOnItemSelectedListener(new OutdoorClassSpinnerListener()); break; - // Satellite - case 3: - mMapFragment.getMap().setStyleUrl("asset://styles/satellite-v7.json"); - mMapFragment.getMap().removeAllClasses(); - mClassSpinner.setVisibility(View.VISIBLE); - mClassSpinner.setAdapter(mSatelliteClassAdapter); - mClassSpinner.setOnItemSelectedListener(new SatelliteClassSpinnerListener()); - break; - - // Pencil - case 4: - mMapFragment.getMap().setStyleUrl("asset://styles/pencil-v7.json"); - mMapFragment.getMap().removeAllClasses(); - mClassSpinner.setVisibility(View.INVISIBLE); - mClassSpinner.setAdapter(null); - mClassSpinner.setOnItemSelectedListener(null); - break; - - // Empty - case 5: - mMapFragment.getMap().setStyleUrl("asset://styles/empty-v7.json"); - mMapFragment.getMap().removeAllClasses(); - mClassSpinner.setVisibility(View.INVISIBLE); - mClassSpinner.setAdapter(null); - mClassSpinner.setOnItemSelectedListener(null); - break; - default: onNothingSelected(parent); break; diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/android/java/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml index 7b4e51b47..901e23192 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml @@ -12,12 +12,10 @@ Map compass. Click to reset the map rotation to North. - Bright - Basic - Outdoors - Satellite - Pencil - Empty + Mapbox Streets + Emerald + Light + Dark @@ -25,10 +23,4 @@ Night - - Labels + Contours - Labels Only - No Labels - - diff --git a/android/scripts/build-debug.sh b/android/scripts/build-debug.sh deleted file mode 100755 index 450820a11..000000000 --- a/android/scripts/build-debug.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -export BUILDTYPE=Debug - -./android/scripts/common.sh $1 diff --git a/android/scripts/build-release.sh b/android/scripts/build-release.sh deleted file mode 100755 index 73c7fab81..000000000 --- a/android/scripts/build-release.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -export BUILDTYPE=Release - -./android/scripts/common.sh $1 diff --git a/android/scripts/common.sh b/android/scripts/common.sh deleted file mode 100755 index 0d610909b..000000000 --- a/android/scripts/common.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -NAME=$1 - -case `uname -s` in - 'Darwin') export JOBS=`sysctl -n hw.ncpu` ;; - 'Linux') export JOBS=`nproc` ;; - *) export JOBS=1 ;; -esac - - -export CC=clang CXX=clang++ -export MASON_PLATFORM=android - -mkdir -p ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw/ -echo "${MAPBOX_ACCESS_TOKEN}" >> ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw/token.txt - -make android -j$JOBS BUILDTYPE=$BUILDTYPE JOBS=$JOBS - -S3_PREFIX=s3://mapbox/mapbox-gl-native/android/build/${NAME} -APK_OUTPUTS=./android/java/MapboxGLAndroidSDKTestApp/build/outputs/apk - -# Upload the shared object. -aws s3 cp \ - ./build/android-${ANDROID_ABI}/${BUILDTYPE}/lib.target/libmapbox-gl.so \ - ${S3_PREFIX}/libmapbox-gl.so - -# Upload either the debug or the release build -if [ ${BUILDTYPE} == "Debug" ] ; then - aws s3 cp \ - ${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-debug.apk \ - ${S3_PREFIX}/MapboxGLAndroidSDKTestApp-debug.apk -elif [ ${BUILDTYPE} == "Release" ] ; then - aws s3 cp \ - ${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-release-unsigned.apk \ - ${S3_PREFIX}/MapboxGLAndroidSDKTestApp-release-unsigned.apk -fi diff --git a/android/scripts/run-build.sh b/android/scripts/run-build.sh deleted file mode 100755 index 9fa15a02b..000000000 --- a/android/scripts/run-build.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -cwd=$(pwd) - -region="us-east-1" -region_ami="ami-022e0c6a" -sleep=10 -instance_name="android-gl-build-$TRAVIS_REPO_SLUG-$TRAVIS_JOB_NUMBER" -echo $ami_name - -NAME=$TRAVIS_JOB_ID - -user_data="#!/bin/bash - cd /android - git clone git://github.com/mapbox/mapbox-gl-native.git - - pushd mapbox-gl-native - if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then - git checkout $TRAVIS_COMMIT - else - git fetch origin +refs/pull/$TRAVIS_PULL_REQUEST/merge: - git checkout FETCH_HEAD - fi - git submodule update --init --recursive - - export ANDROID_NDK_PATH=/android/android-ndk-r10d - export JAVA_HOME=/android/jdk1.7.0_71 - export ANDROID_HOME=/android/android-sdk-linux - export PATH=\$PATH:/android/jdk1.7.0_71/bin - export MAPBOX_ACCESS_TOKEN=$MAPBOX_ACCESS_TOKEN - export TESTMUNK_KEY=$TESTMUNK_KEY - export TESTMUNK=$TESTMUNK - export MASON_ANDROID_ABI=$MASON_ANDROID_ABI - export ANDROID_ABI=$MASON_ANDROID_ABI - - if ./android/scripts/build-$CONFIG.sh $NAME &>../build.log; then - echo 'ANDROID BUILD PASSED' - else - echo 'ANDROID BUILD FAILED' - fi - popd - - aws s3 cp --region us-east-1 build.log s3://mapbox/mapbox-gl-native/android/build/${NAME}/build-log.txt - shutdown -P now" - -id=$(aws ec2 run-instances \ - --region $region \ - --image-id $region_ami \ - --count 1 \ - --instance-type m3.large \ - --iam-instance-profile Arn="$ANDROID_BUILD_INSTANCE_PROFILE" \ - --instance-initiated-shutdown-behavior terminate \ - --user-data "$user_data" | jq -r '.Instances[0].InstanceId') - -echo "Instance: $region $id" - -sleep 10 - -result=$(aws ec2 create-tags --region $region --resources $id --tags "Key=Name,Value=$instance_name") - -instance_status_terminated=$(aws ec2 describe-instances --region $region --instance-id $id | jq -r '.Reservations[0].Instances[0].State.Name') - -until [ "$instance_status_terminated" = "terminated" ]; do - instance_status_terminated=$(aws ec2 describe-instances --region $region --instance-id $id | jq -r '.Reservations[0].Instances[0].State.Name') - echo "Instance terminating status $region $id: $instance_status_terminated" - sleep $sleep -done - -echo "Build finished" - -output=$(aws ec2 get-console-output --region $region --instance-id $id | jq -r '.Output') - -aws s3 cp --region $region s3://mapbox/mapbox-gl-native/android/build/${NAME}/build-log.txt build.log -cat build.log - -if [[ $output == *"ANDROID BUILD PASSED"* ]]; then - echo "ANDROID BUILD PASSED" - exit 0 -else - echo "ANDROID BUILD FAILED" - exit 1 -fi diff --git a/bin/render.cpp b/bin/render.cpp index cd7a54f48..33e216f52 100644 --- a/bin/render.cpp +++ b/bin/render.cpp @@ -39,6 +39,7 @@ int main(int argc, char *argv[]) { std::string cache_file = "cache.sqlite"; std::vector classes; std::string token; + bool debug = false; po::options_description desc("Allowed options"); desc.add_options() @@ -51,6 +52,7 @@ int main(int argc, char *argv[]) { ("height,h", po::value(&height)->value_name("pixels")->default_value(height), "Image height") ("class,c", po::value(&classes)->value_name("name"), "Class name") ("token,t", po::value(&token)->value_name("key")->default_value(token), "Mapbox access token") + ("debug", po::bool_switch(&debug)->default_value(debug), "Debug mode") ("output,o", po::value(&output)->value_name("file")->default_value(output), "Output file name") ("cache,d", po::value(&cache_file)->value_name("file")->default_value(cache_file), "Cache database file name") ; @@ -79,11 +81,8 @@ int main(int argc, char *argv[]) { } } - HeadlessView view; - Map map(view, fileSource); - - map.start(Map::Mode::Still); + Map map(view, fileSource, MapMode::Still); // Set access token if present if (token.size()) { @@ -93,10 +92,14 @@ int main(int argc, char *argv[]) { map.setStyleJSON(style, "."); map.setClasses(classes); - view.resize(width, height, pixelRatio); + map.resize(width, height, pixelRatio); map.setLatLngZoom({ lat, lon }, zoom); map.setBearing(bearing); + if (debug) { + map.setDebug(debug); + } + uv_async_t *async = new uv_async_t; uv_async_init(uv_default_loop(), async, [](uv_async_t *as, int) { std::unique_ptr image(reinterpret_cast(as->data)); @@ -115,6 +118,4 @@ int main(int argc, char *argv[]) { // This loop will terminate once the async was fired. uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - map.stop(); } diff --git a/bin/render.gypi b/bin/render.gypi index b205e7a95..2e1dbd8f7 100644 --- a/bin/render.gypi +++ b/bin/render.gypi @@ -34,12 +34,11 @@ 'ldflags': [ '<@(glfw3_ldflags)', '<@(uv_ldflags)', - '<@(boost_ldflags)', - '-lboost_program_options' ], 'libraries': [ '<@(glfw3_static_libs)', '<@(uv_static_libs)', + '<@(boost_program_options_static_libs)' ], }, diff --git a/config/defaults.mk b/config/defaults.mk index 2aa11ccbe..1449bf8e1 100644 --- a/config/defaults.mk +++ b/config/defaults.mk @@ -31,32 +31,32 @@ LIBS_linux += -Dcache_lib=$(word 1,$(CACHE) sqlite) LIBS_linux += --depth=. -Goutput_dir=. ANDROID_ABIS += android-lib-arm-v8 -ENV_android-arm-v8 = $(shell MASON_ANDROID_ABI=arm-v8 ./scripts/android_env.sh) +ENV_android-arm-v8 = $(shell MASON_ANDROID_ABI=arm-v8 ./scripts/android/toolchain.sh) CONFIG_android-arm-v8 = -Dhost=android -Iconfig/android-arm-v8.gypi ANDROID_ABIS += android-lib-arm-v7 -ENV_android-arm-v7 = $(shell MASON_ANDROID_ABI=arm-v7 ./scripts/android_env.sh) +ENV_android-arm-v7 = $(shell MASON_ANDROID_ABI=arm-v7 ./scripts/android/toolchain.sh) CONFIG_android-arm-v7 = -Dhost=android -Iconfig/android-arm-v7.gypi ANDROID_ABIS += android-lib-arm-v5 -ENV_android-arm-v5 = $(shell MASON_ANDROID_ABI=arm-v5 ./scripts/android_env.sh) +ENV_android-arm-v5 = $(shell MASON_ANDROID_ABI=arm-v5 ./scripts/android/toolchain.sh) CONFIG_android-arm-v5 = -Dhost=android -Iconfig/android-arm-v5.gypi ANDROID_ABIS += android-lib-x86 -ENV_android-x86 = $(shell MASON_ANDROID_ABI=x86 ./scripts/android_env.sh) +ENV_android-x86 = $(shell MASON_ANDROID_ABI=x86 ./scripts/android/toolchain.sh) CONFIG_android-x86 = -Dhost=android -Iconfig/android-x86.gypi # OpenSSL build is incomplete. # ANDROID_ABIS += android-lib-x86-64 -# ENV_android-x86-64 = $(shell MASON_ANDROID_ABI=x86-64 ./scripts/android_env.sh) +# ENV_android-x86-64 = $(shell MASON_ANDROID_ABI=x86-64 ./scripts/android/toolchain.sh) # CONFIG_android-x86-64 = -Dhost=android -Iconfig/android-x86-64.gypi ANDROID_ABIS += android-lib-mips -ENV_android-mips = $(shell MASON_ANDROID_ABI=mips ./scripts/android_env.sh) +ENV_android-mips = $(shell MASON_ANDROID_ABI=mips ./scripts/android/toolchain.sh) CONFIG_android-mips = -Dhost=android -Iconfig/android-mips.gypi ANDROID_ABIS += android-lib-mips-64 -ENV_android-mips-64 = $(shell MASON_ANDROID_ABI=mips-64 ./scripts/android_env.sh) +ENV_android-mips-64 = $(shell MASON_ANDROID_ABI=mips-64 ./scripts/android/toolchain.sh) CONFIG_android-mips-64 = -Dhost=android -Iconfig/android-mips-64.gypi LIBS_android = -Dheadless_lib=none diff --git a/configure b/configure index 1d68f5e54..c1f7f6da1 100755 --- a/configure +++ b/configure @@ -15,7 +15,8 @@ function finish { trap finish EXIT # Install mason -. ./scripts/local_mason.sh +git submodule update --init .mason +export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason" case ${MASON_PLATFORM} in 'ios') @@ -44,7 +45,8 @@ case ${MASON_PLATFORM} in LIBCURL_VERSION=system LIBUV_VERSION=0.10.28 ZLIB_VERSION=system - BOOST_VERSION=system + BOOST_VERSION=1.57.0 + BOOST_PROGRAM_OPTIONS_VERSION=1.57.0 NUNICODE_VERSION=1.5.1 LIBZIP_VERSION=0.11.2 ;; @@ -103,7 +105,11 @@ CONFIG="# Do not edit. Generated by the configure script. if [ ! -z ${BOOST_VERSION} ]; then mason install boost ${BOOST_VERSION} CONFIG+=" 'boost_cflags%': $(quote_flags $(mason cflags boost ${BOOST_VERSION})),"$LN - CONFIG+=" 'boost_ldflags%': $(quote_flags $(mason ldflags boost ${BOOST_VERSION})),"$LN +fi + +if [ ! -z ${BOOST_PROGRAM_OPTIONS_VERSION} ]; then + mason install boost_libprogram_options ${BOOST_PROGRAM_OPTIONS_VERSION} + CONFIG+=" 'boost_program_options_static_libs%': $(quote_flags $(mason static_libs boost_libprogram_options ${BOOST_VERSION})),"$LN fi if [ ! -z ${OPENSSL_VERSION} ]; then diff --git a/docker/linux/test.sh b/docker/linux/test.sh deleted file mode 100755 index 9ef9bf51f..000000000 --- a/docker/linux/test.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -export TRAVIS_OS_NAME=linux - -cd build - -source ./scripts/local_mason.sh -mason install mesa 10.4.3 -export LD_LIBRARY_PATH=`mason prefix mesa 10.4.3`/lib - -export DISPLAY=:99.0 -Xvfb :99 -ac -screen 0 1024x768x24 & - -if [[ ${CXX} == "g++" ]]; then - export CXX="g++-4.8" - export CC="gcc-4.8" -fi - -source ./scripts/install_node.sh - -make linux -j`nproc` -make test-* -j`nproc` -./scripts/compare_images.sh diff --git a/gyp/common.gypi b/gyp/common.gypi index fbfa68711..d7d21f761 100644 --- a/gyp/common.gypi +++ b/gyp/common.gypi @@ -8,11 +8,11 @@ ['OS=="mac"', { 'xcode_settings': { 'CLANG_CXX_LIBRARY': 'libc++', - 'CLANG_CXX_LANGUAGE_STANDARD': 'c++11', 'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0', 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', 'GCC_ENABLE_CPP_RTTI': 'YES', 'OTHER_CPLUSPLUSFLAGS': [ + '-std=c++1y', '-Werror', '-Wall', '-Wextra', @@ -27,14 +27,14 @@ }, }, { 'cflags_cc': [ - '-std=c++11', + '-std=c++14', '-Werror', '-Wall', '-Wextra', '-Wshadow', '-Wno-variadic-macros', '-Wno-error=unused-parameter', - '-Wno-unknown-warning-option', + '-Wno-c++1y-extensions', '-frtti', '-fexceptions', ], diff --git a/gyp/ios.gyp b/gyp/ios.gyp new file mode 100644 index 000000000..f26ec3772 --- /dev/null +++ b/gyp/ios.gyp @@ -0,0 +1,6 @@ +{ + 'includes': [ + '../ios/app/mapboxgl-app.gypi', + '../ios/benchmark/benchmark-ios.gypi', + ], +} diff --git a/gyp/linux.gyp b/gyp/linux.gyp new file mode 100644 index 000000000..0f7126934 --- /dev/null +++ b/gyp/linux.gyp @@ -0,0 +1,7 @@ +{ + 'includes': [ + '../linux/mapboxgl-app.gypi', + '../test/test.gypi', + '../bin/render.gypi', + ], +} diff --git a/gyp/osx.gyp b/gyp/osx.gyp new file mode 100644 index 000000000..64663540b --- /dev/null +++ b/gyp/osx.gyp @@ -0,0 +1,8 @@ +{ + 'includes': [ + '../macosx/mapboxgl-app.gypi', + '../linux/mapboxgl-app.gypi', + '../test/test.gypi', + '../bin/render.gypi', + ], +} diff --git a/gyp/platform-android.gypi b/gyp/platform-android.gypi index bfaac7d4f..7701393bb 100644 --- a/gyp/platform-android.gypi +++ b/gyp/platform-android.gypi @@ -12,6 +12,7 @@ 'sources': [ '../platform/android/log_android.cpp', '../platform/android/asset_root.cpp', + '../platform/default/thread.cpp', '../platform/default/string_stdlib.cpp', '../platform/default/image.cpp', '../platform/default/image_reader.cpp', diff --git a/gyp/platform-ios.gypi b/gyp/platform-ios.gypi index f70743118..0034831a9 100644 --- a/gyp/platform-ios.gypi +++ b/gyp/platform-ios.gypi @@ -15,22 +15,29 @@ '../platform/darwin/application_root.mm', '../platform/darwin/asset_root.mm', '../platform/darwin/image.mm', + '../platform/darwin/nsthread.mm', '../platform/darwin/reachability.m', '../include/mbgl/ios/MapboxGL.h', - '../include/mbgl/ios/MGLMapboxEvents.h', + '../platform/ios/MGLMapboxEvents.h', '../platform/ios/MGLMapboxEvents.m', '../include/mbgl/ios/MGLMapView.h', '../include/mbgl/ios/MGLMapView+IBAdditions.h', '../platform/ios/MGLMapView.mm', + '../platform/ios/MGLFileCache.h', + '../platform/ios/MGLFileCache.mm', + '../include/mbgl/ios/MGLAccountManager.h', + '../platform/ios/MGLAccountManager.m', '../include/mbgl/ios/MGLAnnotation.h', '../include/mbgl/ios/MGLUserLocation.h', '../platform/ios/MGLUserLocation_Private.h', '../platform/ios/MGLUserLocation.m', '../platform/ios/MGLUserLocationAnnotationView.h', '../platform/ios/MGLUserLocationAnnotationView.m', - '../include/mbgl/ios/MGLMetricsLocationManager.h', - '../platform/ios/MGLMetricsLocationManager.m', '../include/mbgl/ios/MGLTypes.h', + '../platform/ios/MGLTypes.m', + '../platform/ios/NSBundle+MGLAdditions.h', + '../platform/ios/NSBundle+MGLAdditions.m', + '../platform/ios/NSException+MGLAdditions.h', '../platform/ios/NSProcessInfo+MGLAdditions.h', '../platform/ios/NSProcessInfo+MGLAdditions.m', '../platform/ios/NSString+MGLAdditions.h', diff --git a/gyp/platform-linux.gypi b/gyp/platform-linux.gypi index 30715f828..394433870 100644 --- a/gyp/platform-linux.gypi +++ b/gyp/platform-linux.gypi @@ -14,6 +14,7 @@ '../platform/default/string_stdlib.cpp', '../platform/default/application_root.cpp', '../platform/default/asset_root.cpp', + '../platform/default/thread.cpp', '../platform/default/image.cpp', '../platform/default/image_reader.cpp', '../platform/default/png_reader.cpp', diff --git a/gyp/platform-osx.gypi b/gyp/platform-osx.gypi index 6d6c35b29..ae5194761 100644 --- a/gyp/platform-osx.gypi +++ b/gyp/platform-osx.gypi @@ -15,6 +15,7 @@ '../platform/darwin/application_root.mm', '../platform/darwin/asset_root.mm', '../platform/darwin/image.mm', + '../platform/darwin/nsthread.mm', ], 'variables': { diff --git a/gyp/project.gyp b/gyp/project.gyp deleted file mode 100644 index 9f53eef51..000000000 --- a/gyp/project.gyp +++ /dev/null @@ -1,19 +0,0 @@ -{ - 'conditions': [ - ['host == "osx"', { - 'includes': [ - '../macosx/mapboxgl-app.gypi', - '../linux/mapboxgl-app.gypi', - '../test/test.gypi', - '../bin/render.gypi', - ] - }], - ['host == "linux"', { - 'includes': [ - '../linux/mapboxgl-app.gypi', - '../test/test.gypi', - '../bin/render.gypi', - ] - }], - ], -} diff --git a/gyp/styles.gypi b/gyp/styles.gypi index 8b3032b58..06121f2d4 100644 --- a/gyp/styles.gypi +++ b/gyp/styles.gypi @@ -14,21 +14,22 @@ ], }, { - 'target_name': 'bundle_styles', + 'target_name': 'bundle_styles', # use this only for targets that create an App bundle 'type': 'none', 'hard_dependency': 1, 'dependencies': [ 'touch_styles' ], # required for xcode http://openradar.appspot.com/7232149 - 'conditions': [ - ['platform_lib == "osx" or platform_lib == "ios"', { - 'direct_dependent_settings': { - 'mac_bundle_resources': [ '../styles/styles' ], - } - }, { - 'direct_dependent_settings': { - 'copies': [{ 'files': [ '../styles/styles' ], 'destination': '<(PRODUCT_DIR)' }], - } - }] - ], - } + 'direct_dependent_settings': { + 'mac_bundle_resources': [ '../styles/styles' ], + } + }, + { + 'target_name': 'copy_styles', # use this only for targets that don't create an App bundle + 'type': 'none', + 'hard_dependency': 1, + 'dependencies': [ 'touch_styles' ], + 'direct_dependent_settings': { + 'copies': [{ 'files': [ '../styles/styles' ], 'destination': '<(PRODUCT_DIR)' }], + } + }, ] } diff --git a/include/mbgl/android/native_map_view.hpp b/include/mbgl/android/native_map_view.hpp index 14ccaba3f..fae239e07 100644 --- a/include/mbgl/android/native_map_view.hpp +++ b/include/mbgl/android/native_map_view.hpp @@ -23,7 +23,7 @@ public: void activate() override; void deactivate() override; void notify() override; - void invalidate() override; + void invalidate(std::function render) override; void notifyMapChange(mbgl::MapChange change, Duration delay = Duration::zero()) override; @@ -39,17 +39,12 @@ public: void createSurface(ANativeWindow *window); void destroySurface(); - void start(); - void stop(); - void resume(); - void pause(bool waitForPause = false); + void pause(); void enableFps(bool enable); void updateFps(); - void resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight); - private: EGLConfig chooseConfig(const EGLConfig configs[], EGLint numConfigs); @@ -60,11 +55,6 @@ private: jobject obj = nullptr; ANativeWindow *window = nullptr; - - mbgl::SQLiteCache fileCache; - mbgl::DefaultFileSource fileSource; - mbgl::Map map; - EGLDisplay display = EGL_NO_DISPLAY; EGLSurface surface = EGL_NO_SURFACE; EGLContext context = EGL_NO_CONTEXT; @@ -79,6 +69,12 @@ private: bool fpsEnabled = false; double fps = 0.0; + + // Ensure these are initialised last + mbgl::SQLiteCache fileCache; + mbgl::DefaultFileSource fileSource; + mbgl::Map map; + }; } } diff --git a/include/mbgl/ios/MGLAccountManager.h b/include/mbgl/ios/MGLAccountManager.h new file mode 100644 index 000000000..7ec4135f1 --- /dev/null +++ b/include/mbgl/ios/MGLAccountManager.h @@ -0,0 +1,29 @@ +#import + +/** The MGLAccountManager object provides a global way to set a Mapbox API access token, as well as other settings used framework-wide. */ +@interface MGLAccountManager : NSObject + +/** @name Authorizing Access */ + +/** Set the Mapbox API access token for the framework. +* +* You can set an access token on MGLAccountManager or on an individual map view. The same token is used throughout the framework. +* @param accessToken The Mapbox API access token. */ ++ (void)setAccessToken:(NSString *)accessToken; + +/** Retreive the Mapbox API access token for the framework. +* +* You can set an access token on MGLAccountManager or on an individual map view. The same token is used throughout the framework. +* @return accessToken The Mapbox API access token. */ ++ (NSString *)accessToken; + +/** @name Providing User Metrics Opt-Out */ + +/** Certain Mapbox plans require the collection of user metrics. If you aren't using a preference switch in an existing or new `Settings.bundle` in your application, set this value to `YES` to indicate that you are providing a metrics opt-out for users within your app's interface directly. +* @param showsOptOut Whether your application's interface provides a user opt-out preference. The default value is `NO`, meaning a `Settings.bundle` is expected for providing a user opt-out preference. */ ++ (void)setMapboxMetricsEnabledSettingShownInApp:(BOOL)showsOptOut; + +/** Whether in-app user metrics opt-out is configured. If set to the default value of `NO`, a user opt-out preference is expected in a `Settings.bundle` that shows in the application's section within the system Settings app. */ ++ (BOOL)mapboxMetricsEnabledSettingShownInApp; + +@end diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index 8717b5e8a..9d7b5c901 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -20,6 +20,11 @@ IB_DESIGNABLE /** @name Initializing a Map View */ +/** Initialize a map view with the default style, given frame, and access token set in MapboxGL singleton. +* @param frame The frame with which to initialize the map view. +* @return An initialized map view, or `nil` if the map view was unable to be initialized. */ +- (instancetype)initWithFrame:(CGRect)frame; + /** Initialize a map view with the default style and a given frame and access token. * @param frame The frame with which to initialize the map view. * @param accessToken A Mapbox API access token. @@ -33,8 +38,6 @@ IB_DESIGNABLE * @return An initialized map view, or `nil` if the map view was unable to be initialized. */ - (instancetype)initWithFrame:(CGRect)frame accessToken:(NSString *)accessToken styleURL:(NSURL *)styleURL; -- (instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("Instantiating an MGLMapView requires setting a style and/or an access token."))); - #pragma mark - Authorizing Access /** @name Authorizing Access */ @@ -46,11 +49,6 @@ IB_DESIGNABLE /** @name Managing Constraints */ -/** A view controller whose top and bottom layout guides to use for proper setup of constraints in the map view internals. -* -* Certain components of the map view, such as the heading compass and the data attribution button, need to be aware of the view controller layout in order to avoid positioning content under a top navigation bar or a bottom toolbar. */ -@property (nonatomic, weak) IBOutlet UIViewController *viewControllerForLayoutGuides; - #pragma mark - Accessing Map Properties /** @name Accessing Map Properties */ @@ -184,13 +182,17 @@ IB_DESIGNABLE /** Currently active style classes, represented as an array of string identifiers. */ @property (nonatomic) NSArray *styleClasses; -/** Returns a Boolean value indicating whether the style class with the given identifier is currently active. */ +/** Returns a Boolean value indicating whether the style class with the given identifier is currently active. + @param styleClass The style class to query for. + @return Whether the style class is currently active. */ - (BOOL)hasStyleClass:(NSString *)styleClass; -/** Activates the style class with the given identifier. */ +/** Activates the style class with the given identifier. + @param styleClass The style class to activate. */ - (void)addStyleClass:(NSString *)styleClass; -/** Deactivates the style class with the given identifier. */ +/** Deactivates the style class with the given identifier. + @param styleClass The style class to deactivate. */ - (void)removeStyleClass:(NSString *)styleClass; #pragma mark - Annotating the Map diff --git a/include/mbgl/ios/MGLMetricsLocationManager.h b/include/mbgl/ios/MGLMetricsLocationManager.h deleted file mode 100644 index 5f3b56818..000000000 --- a/include/mbgl/ios/MGLMetricsLocationManager.h +++ /dev/null @@ -1,11 +0,0 @@ -#import - -@interface MGLMetricsLocationManager : NSObject - -// These methods can be called from any thread. -// -+ (instancetype)sharedManager; -+ (void) startUpdatingLocation; -+ (void) stopUpdatingLocation; - -@end diff --git a/include/mbgl/ios/MGLTypes.h b/include/mbgl/ios/MGLTypes.h index 9a393b2fd..d4bc6c2ce 100644 --- a/include/mbgl/ios/MGLTypes.h +++ b/include/mbgl/ios/MGLTypes.h @@ -1,5 +1,7 @@ #import +extern NSString * const MGLErrorDomain; + /** The mode used to track the user location on the map. */ typedef NS_ENUM(NSUInteger, MGLUserTrackingMode) { diff --git a/include/mbgl/ios/MapboxGL.h b/include/mbgl/ios/MapboxGL.h index c32915bc7..a6d23d328 100644 --- a/include/mbgl/ios/MapboxGL.h +++ b/include/mbgl/ios/MapboxGL.h @@ -1,3 +1,4 @@ +#import "MGLAccountManager.h" #import "MGLAnnotation.h" #import "MGLMapView.h" #import "MGLTypes.h" diff --git a/include/mbgl/map/environment.hpp b/include/mbgl/map/environment.hpp index 1cd33a5e6..d8068187e 100644 --- a/include/mbgl/map/environment.hpp +++ b/include/mbgl/map/environment.hpp @@ -39,7 +39,6 @@ public: // ############################################################################################# // File request APIs - void requestAsync(const Resource&, std::function); Request* request(const Resource&, std::function); void cancelRequest(Request*); @@ -54,11 +53,6 @@ public: // Only call this while the OpenGL context is exclusive to this thread. void performCleanup(); - // ############################################################################################# - - // Request to terminate the environment. - void terminate(); - private: unsigned id; FileSource& fileSource; @@ -67,9 +61,6 @@ private: std::vector abandonedVAOs; std::vector abandonedBuffers; std::vector abandonedTextures; - -public: - uv_loop_t* const loop; }; class EnvironmentScope final { diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index f9738debe..e71c5f5b4 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -1,96 +1,56 @@ #ifndef MBGL_MAP_MAP #define MBGL_MAP_MAP -#include #include #include +#include #include -#include #include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include - -namespace uv { class async; } +#include +#include namespace mbgl { -class Painter; -class GlyphStore; -class LayerDescription; -class Sprite; -class Style; -class StyleLayer; -class TexturePool; class FileSource; class View; -class GlyphAtlas; -class SpriteAtlas; -class LineAtlas; -class Environment; -class EnvironmentScope; -class AnnotationManager; class MapData; -class Worker; +class MapContext; class StillImage; +namespace util { +template class Thread; +} + class Map : private util::noncopyable { friend class View; public: - enum class Mode : uint8_t { - None, // we're not doing any processing - Continuous, // continually updating map - Still, // a once-off still image. - }; - - explicit Map(View&, FileSource&); + explicit Map(View&, FileSource&, + MapMode mode = MapMode::Continuous); ~Map(); - // Start the map render thread. It is asynchronous. - void start(bool startPaused = false, Mode mode = Mode::Continuous); - inline void start(Mode renderMode) { start(false, renderMode); } - - // Stop the map render thread. This call will block until the map rendering thread stopped. - // The optional callback function will be invoked repeatedly until the map thread is stopped. - // The callback function should wait until it is woken up again by view.notify(), otherwise - // this will be a busy waiting loop. - void stop(std::function callback = std::function()); - // Pauses the render thread. The render thread will stop running but will not be terminated and will not lose state until resumed. - void pause(bool waitForPause = false); + void pause(); // Resumes a paused render thread void resume(); + // Register a callback that will get called (on the render thread) when all resources have + // been loaded and a complete render occurs. using StillImageCallback = std::function)>; void renderStill(StillImageCallback callback); // Triggers a synchronous or asynchronous render. void renderSync(); - - // Unconditionally performs a render with the current map state. May only be called from the Map - // thread. - void render(); + void renderAsync(); // Notifies the Map thread that the state has changed and an update might be necessary. - void triggerUpdate(Update = Update::Nothing); - - // Triggers a render. Can be called from any thread. - void triggerRender(); - - // Releases resources immediately - void terminate(); + void update(Update update = Update::Nothing); // Styling void addClass(const std::string&); @@ -134,18 +94,23 @@ public: double getBearing() const; void resetNorth(); + // Size + void resize(uint16_t width, uint16_t height, float ratio = 1); + uint16_t getWidth() const; + uint16_t getHeight() const; + // API void setAccessToken(const std::string &token); std::string getAccessToken() const; // Projection - inline void getWorldBoundsMeters(ProjectedMeters &sw, ProjectedMeters &ne) const { Projection::getWorldBoundsMeters(sw, ne); } - inline void getWorldBoundsLatLng(LatLng &sw, LatLng &ne) const { Projection::getWorldBoundsLatLng(sw, ne); } - inline double getMetersPerPixelAtLatitude(const double lat, const double zoom) const { return Projection::getMetersPerPixelAtLatitude(lat, zoom); } - inline const ProjectedMeters projectedMetersForLatLng(const LatLng latLng) const { return Projection::projectedMetersForLatLng(latLng); } - inline const LatLng latLngForProjectedMeters(const ProjectedMeters projectedMeters) const { return Projection::latLngForProjectedMeters(projectedMeters); } - inline const vec2 pixelForLatLng(const LatLng latLng) const { return state.pixelForLatLng(latLng); } - inline const LatLng latLngForPixel(const vec2 pixel) const { return state.latLngForPixel(pixel); } + void getWorldBoundsMeters(ProjectedMeters &sw, ProjectedMeters &ne) const; + void getWorldBoundsLatLng(LatLng &sw, LatLng &ne) const; + double getMetersPerPixelAtLatitude(const double lat, const double zoom) const; + const ProjectedMeters projectedMetersForLatLng(const LatLng latLng) const; + const LatLng latLngForProjectedMeters(const ProjectedMeters projectedMeters) const; + const vec2 pixelForLatLng(const LatLng latLng) const; + const LatLng latLngForPixel(const vec2 pixel) const; // Annotations void setDefaultPointAnnotationSymbol(const std::string&); @@ -160,112 +125,18 @@ public: // Memory void setSourceTileCacheSize(size_t); - size_t getSourceTileCacheSize() const { return sourceCacheSize; } void onLowMemory(); // Debug void setDebug(bool value); void toggleDebug(); bool getDebug() const; - - inline const TransformState &getState() const { return state; } - TimePoint getTime() const; - inline AnnotationManager& getAnnotationManager() const { return *annotationManager; } + bool isFullyLoaded() const; private: - // Runs the map event loop. ONLY run this function when you want to get render a single frame - // with this map object. It will *not* spawn a separate thread and instead block until the - // frame is completely rendered. - void run(); - - // This may only be called by the View object. - void resize(uint16_t width, uint16_t height, float ratio = 1); - void resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight); - - util::ptr getSprite(); - Worker& getWorker(); - - // Checks if render thread needs to pause - void checkForPause(); - - // Setup - void setup(); - - void updateTiles(); - - // Triggered by triggerUpdate(); - void update(); - - // Loads the style set in the data object. Called by Update::StyleInfo - void reloadStyle(); - void loadStyleJSON(const std::string& json, const std::string& base); - - // Prepares a map render by updating the tiles we need for the current view, as well as updating - // the stylesheet. - void prepare(); - - // Runs the function in the map thread. - void invokeTask(std::function&&); - template auto invokeSyncTask(const Fn& fn) -> decltype(fn()); - - void processTasks(); - - void updateAnnotationTiles(const std::vector&); - - size_t sourceCacheSize; - - Mode mode = Mode::None; - - const std::unique_ptr env; - std::unique_ptr scope; - View &view; - -private: - std::unique_ptr workers; - std::thread thread; - std::unique_ptr asyncTerminate; - std::unique_ptr asyncUpdate; - std::unique_ptr asyncInvoke; - std::unique_ptr asyncRender; - - bool terminating = false; - bool pausing = false; - bool isPaused = false; - std::mutex mutexRun; - std::condition_variable condRun; - std::mutex mutexPause; - std::condition_variable condPause; - - // Used to signal that rendering completed. - bool rendered = false; - std::condition_variable condRendered; - std::mutex mutexRendered; - - // Stores whether the map thread has been stopped already. - std::atomic_bool isStopped; - - Transform transform; - TransformState state; - - FileSource& fileSource; - - util::ptr