Merge branch 'master' into new-labelling

Conflicts:
	src/mbgl/map/tile_parser.cpp
	src/mbgl/map/tile_parser.hpp
	src/mbgl/renderer/painter.hpp
	src/mbgl/renderer/painter_symbol.cpp
	src/mbgl/renderer/symbol_bucket.cpp
	src/mbgl/renderer/symbol_bucket.hpp
	src/mbgl/text/collision.cpp
	src/mbgl/text/collision.hpp
	src/mbgl/text/placement.cpp
This commit is contained in:
Ansis Brammanis
2015-05-19 11:09:33 -04:00
548 changed files with 36596 additions and 5382 deletions

7
.gitignore vendored
View File

@@ -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*/

2
.mason

Submodule .mason updated: 03869fd11e...c43967404c

View File

@@ -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

13
CHANGELOG.md Normal file
View File

@@ -0,0 +1,13 @@
# Changelog
## 0.3.1
- Temporarily removed `IBDesignable` support on iOS.
## 0.3.0
- Initial iOS beta release.
Known issues:
- None.

View File

@@ -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 ####################################################

View File

@@ -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

View File

@@ -1,5 +1,6 @@
#include <cstdint>
#include <cinttypes>
#include <cassert>
#include <string>
#include <locale>
@@ -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<NativeMapView *>(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<NativeMapView *>(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<NativeMapView *>(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<NativeMapView *>(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<NativeMapView *>(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<void *>(&nativeCreateSurface)},
{"nativeDestroySurface", "(J)V", reinterpret_cast<void *>(&nativeDestroySurface)},
{"nativeStart", "(J)V", reinterpret_cast<void *>(&nativeStart)},
{"nativeStop", "(J)V", reinterpret_cast<void *>(&nativeStop)},
{"nativePause", "(J)V", reinterpret_cast<void *>(&nativePause)},
{"nativeResume", "(J)V", reinterpret_cast<void *>(&nativeResume)},
{"nativeUpdate", "(J)V", reinterpret_cast<void *>(&nativeUpdate)},
{"nativeTerminate", "(J)V", reinterpret_cast<void *>(&nativeTerminate)},
{"nativeResize", "(JIIFII)V",
reinterpret_cast<void *>(static_cast<void JNICALL (
*)(JNIEnv *, jobject, jlong, jint, jint, jfloat, jint, jint)>(&nativeResize))},

View File

@@ -1,5 +1,6 @@
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <memory>
#include <list>
#include <tuple>
@@ -16,9 +17,6 @@
#include <mbgl/platform/gl.hpp>
#include <mbgl/util/std.hpp>
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<void()> 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<mbgl::gl::glProc>(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<const char *>(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<gl::PFNGLBINDVERTEXARRAYPROC>(
eglGetProcAddress("glBindVertexArrayOES"));
gl::DeleteVertexArrays = reinterpret_cast<gl::PFNGLDELETEVERTEXARRAYSPROC>(
eglGetProcAddress("glDeleteVertexArraysOES"));
gl::GenVertexArrays = reinterpret_cast<gl::PFNGLGENVERTEXARRAYSPROC>(
eglGetProcAddress("glGenVertexArraysOES"));
gl::IsVertexArray =
reinterpret_cast<gl::PFNGLISVERTEXARRAYPROC>(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<gl::PFNGLDEBUGMESSAGECONTROLPROC>(
eglGetProcAddress("glDebugMessageControl"));
gl::DebugMessageInsert = reinterpret_cast<gl::PFNGLDEBUGMESSAGEINSERTPROC>(
eglGetProcAddress("glDebugMessageInsert"));
gl::DebugMessageCallback = reinterpret_cast<gl::PFNGLDEBUGMESSAGECALLBACKPROC>(
eglGetProcAddress("glDebugMessageCallback"));
gl::GetDebugMessageLog = reinterpret_cast<gl::PFNGLGETDEBUGMESSAGELOGPROC>(
eglGetProcAddress("glGetDebugMessageLog"));
gl::GetPointerv =
reinterpret_cast<gl::PFNGLGETPOINTERVPROC>(eglGetProcAddress("glGetPointerv"));
gl::PushDebugGroup =
reinterpret_cast<gl::PFNGLPUSHDEBUGGROUPPROC>(eglGetProcAddress("glPushDebugGroup"));
gl::PopDebugGroup =
reinterpret_cast<gl::PFNGLPOPDEBUGGROUPPROC>(eglGetProcAddress("glPopDebugGroup"));
gl::ObjectLabel =
reinterpret_cast<gl::PFNGLOBJECTLABELPROC>(eglGetProcAddress("glObjectLabel"));
gl::GetObjectLabel =
reinterpret_cast<gl::PFNGLGETOBJECTLABELPROC>(eglGetProcAddress("glGetObjectLabel"));
gl::ObjectPtrLabel =
reinterpret_cast<gl::PFNGLOBJECTPTRLABELPROC>(eglGetProcAddress("glObjectPtrLabel"));
gl::GetObjectPtrLabel = reinterpret_cast<gl::PFNGLGETOBJECTPTRLABELPROC>(
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<gl::PFNGLINSERTEVENTMARKEREXTPROC>(
eglGetProcAddress("glInsertEventMarkerEXT"));
gl::PushGroupMarkerEXT = reinterpret_cast<gl::PFNGLPUSHGROUPMARKEREXTPROC>(
eglGetProcAddress("glPushGroupMarkerEXT"));
gl::PopGroupMarkerEXT = reinterpret_cast<gl::PFNGLPOPGROUPMARKEREXTPROC>(
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<gl::PFNGLLABELOBJECTEXTPROC>(
eglGetProcAddress("glLabelObjectEXT"));
gl::GetObjectLabelEXT = reinterpret_cast<gl::PFNGLGETOBJECTLABELEXTPROC>(
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);
}
}
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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'
}

View File

@@ -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;

View File

@@ -12,12 +12,10 @@
<string name="compass_desc">Map compass. Click to reset the map rotation to North.</string>
<string-array name="style_list">
<item>Bright</item>
<item>Basic</item>
<item>Outdoors</item>
<item>Satellite</item>
<item>Pencil</item>
<item>Empty</item>
<item>Mapbox Streets</item>
<item>Emerald</item>
<item>Light</item>
<item>Dark</item>
</string-array>
<string-array name="outdoors_class_list">
@@ -25,10 +23,4 @@
<item>Night</item>
</string-array>
<string-array name="satellite_class_list">
<item>Labels + Contours</item>
<item>Labels Only</item>
<item>No Labels</item>
</string-array>
</resources>

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env bash
set -e
set -o pipefail
export BUILDTYPE=Debug
./android/scripts/common.sh $1

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env bash
set -e
set -o pipefail
export BUILDTYPE=Release
./android/scripts/common.sh $1

View File

@@ -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

View File

@@ -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

View File

@@ -39,6 +39,7 @@ int main(int argc, char *argv[]) {
std::string cache_file = "cache.sqlite";
std::vector<std::string> 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<const StillImage> image(reinterpret_cast<const StillImage *>(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();
}

View File

@@ -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)'
],
},

View File

@@ -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

12
configure vendored
View File

@@ -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

View File

@@ -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

View File

@@ -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',
],

6
gyp/ios.gyp Normal file
View File

@@ -0,0 +1,6 @@
{
'includes': [
'../ios/app/mapboxgl-app.gypi',
'../ios/benchmark/benchmark-ios.gypi',
],
}

7
gyp/linux.gyp Normal file
View File

@@ -0,0 +1,7 @@
{
'includes': [
'../linux/mapboxgl-app.gypi',
'../test/test.gypi',
'../bin/render.gypi',
],
}

8
gyp/osx.gyp Normal file
View File

@@ -0,0 +1,8 @@
{
'includes': [
'../macosx/mapboxgl-app.gypi',
'../linux/mapboxgl-app.gypi',
'../test/test.gypi',
'../bin/render.gypi',
],
}

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -15,6 +15,7 @@
'../platform/darwin/application_root.mm',
'../platform/darwin/asset_root.mm',
'../platform/darwin/image.mm',
'../platform/darwin/nsthread.mm',
],
'variables': {

View File

@@ -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',
]
}],
],
}

View File

@@ -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)' }],
}
},
]
}

View File

@@ -23,7 +23,7 @@ public:
void activate() override;
void deactivate() override;
void notify() override;
void invalidate() override;
void invalidate(std::function<void()> 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;
};
}
}

View File

@@ -0,0 +1,29 @@
#import <Foundation/Foundation.h>
/** 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

View File

@@ -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

View File

@@ -1,11 +0,0 @@
#import <Foundation/Foundation.h>
@interface MGLMetricsLocationManager : NSObject
// These methods can be called from any thread.
//
+ (instancetype)sharedManager;
+ (void) startUpdatingLocation;
+ (void) stopUpdatingLocation;
@end

View File

@@ -1,5 +1,7 @@
#import <Foundation/Foundation.h>
extern NSString * const MGLErrorDomain;
/** The mode used to track the user location on the map. */
typedef NS_ENUM(NSUInteger, MGLUserTrackingMode)
{

View File

@@ -1,3 +1,4 @@
#import "MGLAccountManager.h"
#import "MGLAnnotation.h"
#import "MGLMapView.h"
#import "MGLTypes.h"

View File

@@ -39,7 +39,6 @@ public:
// #############################################################################################
// File request APIs
void requestAsync(const Resource&, std::function<void(const Response&)>);
Request* request(const Resource&, std::function<void(const Response&)>);
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<uint32_t> abandonedVAOs;
std::vector<uint32_t> abandonedBuffers;
std::vector<uint32_t> abandonedTextures;
public:
uv_loop_t* const loop;
};
class EnvironmentScope final {

View File

@@ -1,96 +1,56 @@
#ifndef MBGL_MAP_MAP
#define MBGL_MAP_MAP
#include <mbgl/map/transform.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/map/update.hpp>
#include <mbgl/map/mode.hpp>
#include <mbgl/util/geo.hpp>
#include <mbgl/util/projection.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/vec.hpp>
#include <cstdint>
#include <atomic>
#include <thread>
#include <iosfwd>
#include <set>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <string>
#include <functional>
namespace uv { class async; }
#include <vector>
#include <memory>
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 T> 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<void ()> callback = std::function<void ()>());
// 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(std::unique_ptr<const StillImage>)>;
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<double> pixelForLatLng(const LatLng latLng) const { return state.pixelForLatLng(latLng); }
inline const LatLng latLngForPixel(const vec2<double> 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<double> pixelForLatLng(const LatLng latLng) const;
const LatLng latLngForPixel(const vec2<double> 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<Sprite> 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<void()>&&);
template <typename Fn> auto invokeSyncTask(const Fn& fn) -> decltype(fn());
void processTasks();
void updateAnnotationTiles(const std::vector<TileID>&);
size_t sourceCacheSize;
Mode mode = Mode::None;
const std::unique_ptr<Environment> env;
std::unique_ptr<EnvironmentScope> scope;
View &view;
private:
std::unique_ptr<Worker> workers;
std::thread thread;
std::unique_ptr<uv::async> asyncTerminate;
std::unique_ptr<uv::async> asyncUpdate;
std::unique_ptr<uv::async> asyncInvoke;
std::unique_ptr<uv::async> 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<Style> style;
std::unique_ptr<GlyphAtlas> glyphAtlas;
util::ptr<GlyphStore> glyphStore;
std::unique_ptr<SpriteAtlas> spriteAtlas;
util::ptr<Sprite> sprite;
std::unique_ptr<LineAtlas> lineAtlas;
util::ptr<TexturePool> texturePool;
std::unique_ptr<Painter> painter;
std::unique_ptr<AnnotationManager> annotationManager;
const std::unique_ptr<MapData> data;
std::atomic<UpdateType> updated;
std::mutex mutexTask;
std::queue<std::function<void()>> tasks;
StillImageCallback callback;
const std::unique_ptr<util::Thread<MapContext>> context;
bool paused = false;
};
}

15
include/mbgl/map/mode.hpp Normal file
View File

@@ -0,0 +1,15 @@
#ifndef MBGL_MAP_MODE
#define MBGL_MAP_MODE
#include <cstdint>
namespace mbgl {
enum class MapMode : uint8_t {
Continuous, // continually updating map
Still, // a once-off still image
};
}
#endif

View File

@@ -9,8 +9,6 @@ using UpdateType = uint32_t;
enum class Update : UpdateType {
Nothing = 0,
StyleInfo = 1 << 0,
Debug = 1 << 1,
DefaultTransitionDuration = 1 << 2,
Classes = 1 << 3,
Zoom = 1 << 4,

View File

@@ -2,6 +2,7 @@
#define MBGL_MAP_VIEW
#include <mbgl/util/chrono.hpp>
#include <functional>
#include <memory>
@@ -39,13 +40,13 @@ public:
virtual void notify() = 0;
// Called from the render thread. The implementation must trigger a rerender.
// (i.e. map->renderSync() or map->renderAsync() must be called as a result of this)
virtual void invalidate() = 0;
// Called from the render thread. The implementation should resize the framebuffer.
virtual void resize(uint16_t width, uint16_t height, float pixelRatio);
// Called from the render (=GL) thread. Signals that the contents of the contents
// may be discarded. The default is a no-op.
virtual void discard();
// Called from the render thread. The implementation must trigger a rerender.
// (i.e. either the passed render() function for rendering immediately on the map thread,
// or map->renderSync() from the main thread must be called as a result of this)
virtual void invalidate(std::function<void()> render) = 0;
// Reads the pixel data from the current framebuffer. If your View implementation
// doesn't support reading from the framebuffer, return a null pointer.
@@ -58,10 +59,6 @@ public:
MapChange change,
Duration delay = Duration::zero());
protected:
// Resizes the view
void resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight);
protected:
mbgl::Map *map = nullptr;
};

View File

@@ -17,7 +17,7 @@ public:
void activate() override;
void deactivate() override;
void notify() override;
void invalidate() override;
void invalidate(std::function<void()> render) override;
static void onKey(GLFWwindow *window, int key, int scancode, int action, int mods);
static void onScroll(GLFWwindow *window, double xoffset, double yoffset);
@@ -25,19 +25,28 @@ public:
static void onMouseClick(GLFWwindow *window, int button, int action, int modifiers);
static void onMouseMove(GLFWwindow *window, double x, double y);
int run();
// Callback called when the user presses the key mapped to style change.
// The expected action is to set a new style, different to the current one.
void setChangeStyleCallback(std::function<void()> callback);
void setShouldClose();
void setWindowTitle(const std::string&);
void run();
void fps();
public:
private:
bool fullscreen = false;
double lastX = 0, lastY = 0;
bool tracking = false;
bool rotating = false;
double lastX = 0, lastY = 0;
double lastClick = -1;
std::function<void()> changeStyleCallback;
GLFWwindow *window = nullptr;
};

View File

@@ -17,6 +17,7 @@ typedef XID GLXPbuffer;
#include <mbgl/platform/gl.hpp>
#include <memory>
#include <thread>
namespace mbgl {
@@ -28,13 +29,11 @@ public:
HeadlessView(std::shared_ptr<HeadlessDisplay> display, uint16_t width = 256, uint16_t height = 256, float pixelRatio = 1);
~HeadlessView();
void resize(uint16_t width, uint16_t height, float pixelRatio);
void activate() override;
void deactivate() override;
void notify() override;
void invalidate() override;
void discard() override;
void resize(uint16_t width, uint16_t height, float pixelRatio) override;
void invalidate(std::function<void()> render) override;
std::unique_ptr<StillImage> readStillImage() override;
private:
@@ -56,12 +55,7 @@ private:
float pixelRatio = 0;
};
// These are the values that represent the state of the current framebuffer.
Dimensions current;
// These are the values that will be used after the next discard() event.
std::mutex prospectiveMutex;
Dimensions prospective;
Dimensions dimensions;
#if MBGL_USE_CGL
CGLContextObj glContext = nullptr;

View File

@@ -10,10 +10,9 @@ extern "C"
}
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wshadow"
#endif
#include <boost/iostreams/stream.hpp>
#pragma GCC diagnostic pop

View File

@@ -12,10 +12,9 @@ extern "C"
#include <memory>
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wshadow"
#endif
#include <boost/iostreams/stream.hpp>
#pragma GCC diagnostic pop

View File

@@ -3,6 +3,7 @@
#include <string>
#include <stdexcept>
#include <vector>
#if __APPLE__
#include "TargetConditionals.h"
@@ -39,150 +40,42 @@ struct Error : ::std::runtime_error {
void checkError(const char *cmd, const char *file, int line);
#if defined(DEBUG)
#define MBGL_CHECK_ERROR(cmd) ([&]() { struct _ { inline ~_() { ::mbgl::gl::checkError(#cmd, __FILE__, __LINE__); } } _; return cmd; }())
#define MBGL_CHECK_ERROR(cmd) ([&]() { struct __MBGL_C_E { inline ~__MBGL_C_E() { ::mbgl::gl::checkError(#cmd, __FILE__, __LINE__); } } __MBGL_C_E; return cmd; }())
#else
#define MBGL_CHECK_ERROR(cmd) (cmd)
#endif
// GL_KHR_debug / GL_ARB_debug_output
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
#define GL_DEBUG_SOURCE_API 0x8246
#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
#define GL_DEBUG_SOURCE_APPLICATION 0x824A
#define GL_DEBUG_SOURCE_OTHER 0x824B
#define GL_DEBUG_TYPE_ERROR 0x824C
#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
#define GL_DEBUG_TYPE_PORTABILITY 0x824F
#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
#define GL_DEBUG_TYPE_OTHER 0x8251
#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
#define GL_DEBUG_LOGGED_MESSAGES 0x9145
#define GL_DEBUG_SEVERITY_HIGH 0x9146
#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
#define GL_DEBUG_SEVERITY_LOW 0x9148
#define GL_DEBUG_TYPE_MARKER 0x8268
#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
#define GL_DEBUG_TYPE_POP_GROUP 0x826A
#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
#define GL_BUFFER 0x82E0
#define GL_SHADER 0x82E1
#define GL_PROGRAM 0x82E2
#define GL_QUERY 0x82E3
#define GL_PROGRAM_PIPELINE 0x82E4
#define GL_SAMPLER 0x82E6
#define GL_MAX_LABEL_LENGTH 0x82E8
#define GL_DEBUG_OUTPUT 0x92E0
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
#define GL_DISPLAY_LIST 0x82E7
#define GL_VERTEX_ARRAY 0x8074
#define GL_TRANSFORM_FEEDBACK 0x8E22
#define GL_TEXTURE 0x1702
#define GL_RENDERBUFFER 0x8D41
#define GL_FRAMEBUFFER 0x8D40
typedef void (* GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
typedef void (* PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
typedef void (* PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
typedef void (* PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
typedef GLuint (* PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
typedef void (* PFNGLGETPOINTERVPROC) (GLenum pname, void **params);
typedef void (* PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
typedef void (* PFNGLPOPDEBUGGROUPPROC) (void);
typedef void (* PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
typedef void (* PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
typedef void (* PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label);
typedef void (* PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
extern PFNGLDEBUGMESSAGECONTROLPROC DebugMessageControl;
extern PFNGLDEBUGMESSAGEINSERTPROC DebugMessageInsert;
extern PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback;
extern PFNGLGETDEBUGMESSAGELOGPROC GetDebugMessageLog;
extern PFNGLGETPOINTERVPROC GetPointerv;
extern PFNGLPUSHDEBUGGROUPPROC PushDebugGroup;
extern PFNGLPOPDEBUGGROUPPROC PopDebugGroup;
extern PFNGLOBJECTLABELPROC ObjectLabel;
extern PFNGLGETOBJECTLABELPROC GetObjectLabel;
extern PFNGLOBJECTPTRLABELPROC ObjectPtrLabel;
extern PFNGLGETOBJECTPTRLABELPROC GetObjectPtrLabel;
void debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
// GL_EXT_debug_marker
typedef void (* PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker);
typedef void (* PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker);
typedef void (* PFNGLPOPGROUPMARKEREXTPROC) (void);
extern PFNGLINSERTEVENTMARKEREXTPROC InsertEventMarkerEXT;
extern PFNGLPUSHGROUPMARKEREXTPROC PushGroupMarkerEXT;
extern PFNGLPOPGROUPMARKEREXTPROC PopGroupMarkerEXT;
// GL_EXT_debug_label
#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F
#define GL_PROGRAM_OBJECT_EXT 0x8B40
#define GL_SHADER_OBJECT_EXT 0x8B48
#define GL_BUFFER_OBJECT_EXT 0x9151
#define GL_QUERY_OBJECT_EXT 0x9153
#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154
typedef void (* PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label);
typedef void (* PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
extern PFNGLLABELOBJECTEXTPROC LabelObjectEXT;
extern PFNGLGETOBJECTLABELEXTPROC GetObjectLabelEXT;
// GL_ARB_vertex_array_object / GL_OES_vertex_array_object
#define GL_VERTEX_ARRAY_BINDING 0x85B5
typedef void (* PFNGLBINDVERTEXARRAYPROC) (GLuint array);
typedef void (* PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays);
typedef void (* PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays);
typedef GLboolean (* PFNGLISVERTEXARRAYPROC) (GLuint array);
extern PFNGLBINDVERTEXARRAYPROC BindVertexArray;
extern PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays;
extern PFNGLGENVERTEXARRAYSPROC GenVertexArrays;
extern PFNGLISVERTEXARRAYPROC IsVertexArray;
// GL_EXT_packed_depth_stencil / GL_OES_packed_depth_stencil
extern bool isPackedDepthStencilSupported;
#define GL_DEPTH24_STENCIL8 0x88F0
// GL_OES_depth24
extern bool isDepth24Supported;
#define GL_DEPTH_COMPONENT24 0x81A6
// Debug group markers, useful for debugging on iOS
#if defined(DEBUG)
// static int indent = 0;
inline void start_group(const std::string &str) {
if (gl::PushDebugGroup != nullptr) {
MBGL_CHECK_ERROR(gl::PushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, GLsizei(str.size()), str.c_str()));
} else if (gl::PushGroupMarkerEXT != nullptr) {
MBGL_CHECK_ERROR(gl::PushGroupMarkerEXT(GLsizei(str.size()), str.c_str()));
}
// fprintf(stderr, "%s%s\n", std::string(indent * 4, ' ').c_str(), str.c_str());
// indent++;
}
inline void end_group() {
if (gl::PopDebugGroup != nullptr) {
MBGL_CHECK_ERROR(gl::PopDebugGroup());
} else if (gl::PopGroupMarkerEXT != nullptr) {
MBGL_CHECK_ERROR(gl::PopGroupMarkerEXT());
}
// indent--;
}
#else
inline void start_group(const std::string &) {}
inline void end_group() {}
#endif
struct group {
inline group(const std::string &str) { start_group(str); }
~group() { end_group(); };
class ExtensionFunctionBase {
public:
static std::vector<ExtensionFunctionBase*>& functions();
typedef std::pair<const char *, const char *> Probe;
std::vector<Probe> probes;
void (*ptr)();
};
template <class>
class ExtensionFunction;
template <class R, class... Args>
class ExtensionFunction<R (Args...)> : protected ExtensionFunctionBase {
public:
ExtensionFunction(std::initializer_list<Probe> probes_) {
probes = probes_;
ExtensionFunctionBase::functions().push_back(this);
}
explicit operator bool() const {
return ptr;
}
R operator()(Args... args) const {
return (*reinterpret_cast<R (*)(Args...)>(ptr))(std::forward<Args>(args)...);
}
};
using glProc = void (*)();
void InitializeExtensions(glProc (*getProcAddress)(const char *));
}
}

View File

@@ -21,6 +21,9 @@ const std::string &applicationRoot();
// Returns the path to the asset location.
const std::string &assetRoot();
// Makes the current thread low priority.
void makeThreadLowPriority();
// Shows an alpha image with the specified dimensions in a named window.
void showDebugImage(std::string name, const char *data, size_t width, size_t height);

View File

@@ -16,12 +16,8 @@ public:
~DefaultFileSource() override;
// FileSource API
Request *request(const Resource &resource, uv_loop_t *loop, const Environment &env,
Callback callback) override;
void cancel(Request *request) override;
void request(const Resource &resource, const Environment &env, Callback callback) override;
void abort(const Environment &env) override;
Request* request(const Resource&, uv_loop_t*, Callback) override;
void cancel(Request*) override;
public:
class Impl;

View File

@@ -15,7 +15,6 @@ typedef struct uv_loop_s uv_loop_t;
namespace mbgl {
class Request;
class Environment;
class FileSource : private util::noncopyable {
protected:
@@ -28,19 +27,8 @@ public:
// These can be called from any thread. The callback will be invoked in the loop.
// You can only cancel a request from the same thread it was created in.
virtual Request *request(const Resource &resource, uv_loop_t *loop, const Environment &env,
Callback callback) = 0;
virtual void cancel(Request *request) = 0;
// These can be called from any thread. The callback will be invoked in an arbitrary other thread.
// You cannot cancel these requests.
virtual void request(const Resource &resource, const Environment &env, Callback callback) = 0;
// This can be called from any thread. All requests with the environment pointer env should be
// notified as errored. Note that this is /different/ from canceling requests; a canceled
// request's callback is never called, while an aborted request's callback is called with
// a error message.
virtual void abort(const Environment &env) = 0;
virtual Request* request(const Resource&, uv_loop_t*, Callback) = 0;
virtual void cancel(Request*) = 0;
};
}

View File

@@ -11,20 +11,17 @@
#include <functional>
#include <memory>
typedef struct uv_async_s uv_async_t;
typedef struct uv_loop_s uv_loop_t;
namespace uv { class async; }
namespace mbgl {
class Response;
class Environment;
class Request : private util::noncopyable {
MBGL_STORE_THREAD(tid)
public:
using Callback = std::function<void(const Response &)>;
Request(const Resource &resource, uv_loop_t *loop, const Environment &env, Callback callback);
Request(const Resource &resource, uv_loop_t *loop, Callback callback);
public:
// May be called from any thread.
@@ -40,7 +37,7 @@ private:
void notifyCallback();
private:
uv_async_t *async = nullptr;
std::unique_ptr<uv::async> async;
struct Canceled;
std::unique_ptr<Canceled> canceled;
Callback callback;
@@ -48,11 +45,6 @@ private:
public:
const Resource resource;
// The environment ref is used to associate requests with a particular environment. This allows
// us to only terminate requests associated with that environment, e.g. when the map the env
// belongs to is discarded.
const Environment &env;
};
}

View File

@@ -20,8 +20,9 @@ public:
void get(const Resource &resource, Callback callback) override;
void put(const Resource &resource, std::shared_ptr<const Response> response, Hint hint) override;
private:
class Impl;
private:
const std::unique_ptr<util::Thread<Impl>> thread;
};

View File

@@ -1,95 +0,0 @@
#ifndef MBGL_UTIL_ASYNC_QUEUE
#define MBGL_UTIL_ASYNC_QUEUE
#include "std.hpp"
#include <uv.h>
#include <thread>
#include <mutex>
#include <functional>
#include <queue>
#include <string>
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
#define UV_ASYNC_PARAMS(handle) uv_async_t *handle, int
#else
#define UV_ASYNC_PARAMS(handle) uv_async_t *handle
#endif
namespace mbgl {
namespace util {
template <typename T>
class AsyncQueue {
public:
AsyncQueue(uv_loop_t *loop, std::function<void(T &)> fn) :
callback(fn) {
async.data = this;
uv_async_init(loop, &async, [](UV_ASYNC_PARAMS(handle)) {
auto q = reinterpret_cast<AsyncQueue *>(handle->data);
q->process();
});
}
void send(T &&data) {
{
std::lock_guard<std::mutex> lock(mutex);
queue.push(util::make_unique<T>(std::move(data)));
}
uv_async_send(&async);
}
void send(std::unique_ptr<T> data) {
{
std::lock_guard<std::mutex> lock(mutex);
queue.push(std::move(data));
}
uv_async_send(&async);
}
void stop() {
uv_close((uv_handle_t *)&async, [](uv_handle_t *handle) {
delete reinterpret_cast<AsyncQueue *>(handle->data);
});
}
void ref() {
uv_ref((uv_handle_t *)&async);
}
void unref() {
uv_unref((uv_handle_t *)&async);
}
private:
~AsyncQueue() {
}
void process() {
std::unique_ptr<T> item;
while (true) {
mutex.lock();
if (queue.empty()) {
mutex.unlock();
break;
}
item = std::move(queue.front());
queue.pop();
mutex.unlock();
callback(*item);
}
}
private:
std::mutex mutex;
uv_async_t async;
std::queue<std::unique_ptr<T>> queue;
std::function<void(T &)> callback;
};
}
}
#endif

View File

@@ -3,6 +3,7 @@
#include <cmath>
#include <string>
#include <vector>
namespace mbgl {

View File

@@ -0,0 +1,87 @@
#ifndef MBGL_UTIL_GL_HELPER
#define MBGL_UTIL_GL_HELPER
#include <mbgl/platform/gl.hpp>
#include <array>
namespace {
template <typename T, T (*Create)(), void (*Destroy)(const T&)>
class Preserve {
public:
Preserve() : data(Create()) {}
~Preserve() { Destroy(data); }
private:
const T data;
};
inline bool getBlend() {
return glIsEnabled(GL_BLEND);
}
inline void setBlend(const bool& enabled) {
enabled ? MBGL_CHECK_ERROR(glEnable(GL_BLEND)) : MBGL_CHECK_ERROR(glDisable(GL_BLEND));
}
inline std::array<double, 4> getClearColor() {
std::array<double, 4> color;
MBGL_CHECK_ERROR(glGetDoublev(GL_COLOR_CLEAR_VALUE, color.data()));
return color;
}
inline void setClearColor(const std::array<double, 4>& color) {
MBGL_CHECK_ERROR(glClearColor(color[0], color[1], color[2], color[3]));
}
inline std::array<GLenum, 2> getBlendFunc() {
GLint func[2];
glGetIntegerv(GL_BLEND_SRC, &func[0]);
glGetIntegerv(GL_BLEND_DST, &func[1]);
return {{ static_cast<GLenum>(func[0]), static_cast<GLenum>(func[1]) }};
}
inline void setBlendFunc(const std::array<GLenum, 2>& func) {
MBGL_CHECK_ERROR(glBlendFunc(func[0], func[1]));
}
inline std::array<double, 2> getPixelZoom() {
std::array<double, 2> zoom;
glGetDoublev(GL_ZOOM_X, &zoom[0]);
glGetDoublev(GL_ZOOM_Y, &zoom[1]);
return zoom;
}
inline void setPixelZoom(const std::array<double, 2>& func) {
MBGL_CHECK_ERROR(glPixelZoom(func[0], func[1]));
}
inline std::array<double, 4> getRasterPos() {
std::array<double, 4> pos;
MBGL_CHECK_ERROR(glGetDoublev(GL_CURRENT_RASTER_POSITION, pos.data()));
return pos;
}
inline void setRasterPos(const std::array<double, 4>& pos) {
MBGL_CHECK_ERROR(glRasterPos4d(pos[0], pos[1], pos[2], pos[3]));
}
} // end anonymous namespace
namespace mbgl {
namespace gl {
using PreserveBlend = Preserve<bool, getBlend, setBlend>;
using PreserveClearColor = Preserve<std::array<double, 4>, getClearColor, setClearColor>;
using PreserveBlendFunc = Preserve<std::array<GLenum, 2>, getBlendFunc, setBlendFunc>;
using PreservePixelZoom = Preserve<std::array<double, 2>, getPixelZoom, setPixelZoom>;
using PreserveRasterPos = Preserve<std::array<double, 4>, getRasterPos, setRasterPos>;
}
}
#endif

View File

@@ -100,7 +100,11 @@ inline T mag(const S& a) {
template <typename S>
inline S unit(const S& a) {
return a * (1 / mag(a));
auto magnitude = mag(a);
if (magnitude == 0) {
return a;
}
return a * (1 / magnitude);
}
template <typename T>

View File

@@ -4,9 +4,8 @@
#include <string>
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
#include <boost/lexical_cast.hpp>
#pragma GCC diagnostic pop

View File

@@ -1,15 +1,16 @@
Pod::Spec.new do |m|
m.name = 'MapboxGL'
m.version = '0.2.15'
m.version = '0.3.1'
m.summary = 'Open source vector map solution for iOS with full styling capabilities.'
m.description = 'Open source OpenGL-based vector map solution for iOS with full styling capabilities and Cocoa bindings.'
m.homepage = 'https://www.mapbox.com/blog/mapbox-gl/'
m.homepage = 'https://www.mapbox.com/mapbox-gl-ios/'
m.license = 'BSD'
m.author = { 'Mapbox' => 'mobile@mapbox.com' }
m.screenshot = 'https://raw.githubusercontent.com/mapbox/mapbox-gl-native/master/ios/screenshot.png'
m.social_media_url = 'https://twitter.com/mapbox'
m.documentation_url = 'https://www.mapbox.com/mapbox-gl-ios'
m.source = {
:http => "http://mapbox.s3.amazonaws.com/mapbox-gl-native/ios/builds/mapbox-gl-ios-#{m.version.to_s}.zip",
@@ -22,11 +23,10 @@ Pod::Spec.new do |m|
m.requires_arc = true
m.preserve_paths = '**'
m.source_files = 'Headers/*.h'
m.source_files = 'Headers/*.h', 'MGLDummy.m'
m.resource_bundle = { 'MapboxGL' => 'MapboxGL.bundle/*' }
m.vendored_library = 'libMapboxGL.a'
m.frameworks = 'CoreLocation', 'CoreTelephony', 'GLKit', 'ImageIO', 'MobileCoreServices', 'QuartzCore', 'SystemConfiguration'
m.libraries = 'c++', 'sqlite3', 'z'
m.xcconfig = { 'OTHER_CPLUSPLUSFLAGS' => '-std=gnu++11 -stdlib=libc++' }

View File

@@ -1,68 +1,7 @@
# Mapbox GL for iOS
Use or edit this project to get access to vector maps (via [Mapbox Vector Tiles](https://www.mapbox.com/blog/vector-tiles)) and dynamic OpenGL-based styling in your iOS apps by using `MGLMapView`.
An open source OpenGL-based vector map solution for iOS with full styling capabilities and Cocoa bindings.
![](./screenshot.png)
For more information, check out [our online overview](https://www.mapbox.com/mapbox-gl-ios/).
## Installation
Currently in flux. See the parent `mapbox-gl-native` project `README` for details on building this library yourself.
Static and dynamic prebuilt binaries are coming back, as is CocoaPods support.
## Example usage
### Objective-C
```objective-c
MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)
accessToken:@"<access token string>"];
[mapView setCenterCoordinate:CLLocationCoordinate2DMake(28.369334, -80.743779)
zoomLevel:13
animated:NO];
[mapView useBundledStyleNamed:@"outdoors"];
[self.view addSubview:mapView];
```
### Swift
```swift
let mapView = MGLMapView(frame: CGRect(x: 0, y: 0, width: 400, height: 400),
accessToken: "<access token string>")
mapView.setCenterCoordinate(CLLocationCoordinate2D(latitude: 46.049900, longitude: -122.095678),
zoomLevel: 12,
animated: false)
mapView.useBundledStyleNamed("outdoors")
view.addSubview(mapView)
```
## Development
If you'd like to contribute to this project, go up to [Mapbox GL native](https://github.com/mapbox/mapbox-gl-native) and clone the project.
## Testing
Currently in flux and not functioning.
## Requirements
* iOS 7+
* a sense of adventure
## Styling
See the [online style reference](https://www.mapbox.com/mapbox-gl-style-spec/) for the latest documentation. Contained within the `MapboxGL.bundle` assets are a couple of starter styles in JSON format.
The project will eventually get a programmatic styling API as well.
## Related Projects
* https://github.com/mapbox/mapbox-gl-style-spec
* https://github.com/mapbox/mapbox-gl-js
* https://github.com/mapbox/vector-tile-spec
![](https://raw.githubusercontent.com/mapbox/mapbox-gl-native/master/ios/screenshot.png)

View File

@@ -1,11 +1,30 @@
#import "MBXAppDelegate.h"
#import "MBXViewController.h"
#import <mbgl/ios/MGLMapboxEvents.h>
#import <mbgl/ios/MapboxGL.h>
@implementation MBXAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Set Access Token
NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"];
if (accessToken) {
// Store to preferences so that we can launch the app later on without having to specify
// token.
[[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"access_token"];
} else {
// Try to retrieve from preferences, maybe we've stored them there previously and can reuse
// the token.
accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"];
}
if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work.");
// Signal To SDK That Opt Out Is In App UI
// [MGLAccountManager setMapboxMetricsEnabledSettingShownInApp:YES];
// Start Mapbox GL SDK
[MGLAccountManager setAccessToken:accessToken];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[MBXViewController new]];
[self.window makeKeyAndVisible];
@@ -13,26 +32,4 @@
return YES;
}
/**
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Example of how to resume Metrics Collection
// Reasons for needing to resume:
// 1. In UIBackground and app starts listening for Location Updates where it previously had not been listening.
// 2. App is entering foreground where it had called pauseMetricsCollection.
[MGLMapboxEvents resumeMetricsCollection];
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Example of how to pause Metrics Collection
// Reason for needing to pause:
// 1. Either entering or already in UIBackground and app stops listening for Location Updates
// via any CLLocationManager instance it may have.
[MGLMapboxEvents pauseMetricsCollection];
}
*/
@end

View File

@@ -52,22 +52,8 @@ mbgl::Settings_NSUserDefaults *settings = nullptr;
{
[super viewDidLoad];
NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"];
if (accessToken) {
// Store to preferences so that we can launch the app later on without having to specify
// token.
[[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"access_token"];
} else {
// Try to retrieve from preferences, maybe we've stored them there previously and can reuse
// the token.
accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"];
}
if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work.");
self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:accessToken];
self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.mapView.viewControllerForLayoutGuides = self;
self.mapView.showsUserLocation = YES;
self.mapView.delegate = self;
[self.view addSubview:self.mapView];
@@ -97,10 +83,7 @@ mbgl::Settings_NSUserDefaults *settings = nullptr;
[self restoreState:nil];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
- (void)saveState:(NSNotification *)notification
- (void)saveState:(__unused NSNotification *)notification
{
if (self.mapView && settings)
{
@@ -115,7 +98,7 @@ mbgl::Settings_NSUserDefaults *settings = nullptr;
}
}
- (void)restoreState:(NSNotification *)notification
- (void)restoreState:(__unused NSNotification *)notification
{
if (self.mapView && settings) {
settings->load();
@@ -127,8 +110,6 @@ mbgl::Settings_NSUserDefaults *settings = nullptr;
}
}
#pragma clang diagnostic pop
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
@@ -291,17 +272,14 @@ mbgl::Settings_NSUserDefaults *settings = nullptr;
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma mark - MGLMapViewDelegate
- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id <MGLAnnotation>)annotation
- (BOOL)mapView:(__unused MGLMapView *)mapView annotationCanShowCallout:(__unused id <MGLAnnotation>)annotation
{
return YES;
}
- (void)mapView:(MGLMapView *)mapView didChangeUserTrackingMode:(MGLUserTrackingMode)mode animated:(BOOL)animated
- (void)mapView:(__unused MGLMapView *)mapView didChangeUserTrackingMode:(MGLUserTrackingMode)mode animated:(__unused BOOL)animated
{
UIImage *newButtonImage;
@@ -324,6 +302,4 @@ mbgl::Settings_NSUserDefaults *settings = nullptr;
}];
}
#pragma clang diagnostic pop
@end

View File

@@ -4,7 +4,7 @@
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<dict>
<key>Title</key>
<string>Privacy Settings</string>
<key>Type</key>
@@ -16,7 +16,7 @@
<key>DefaultValue</key>
<true/>
<key>Key</key>
<string>mapbox_metrics_enabled_preference</string>
<string>MGLMapboxMetricsEnabled</string>
<key>Title</key>
<string>Mapbox Metrics</string>
<key>Type</key>

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>MBGL</string>
<key>CFBundleVersion</key>
<string>0.0.2</string>
<string>0.0.3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSHumanReadableCopyright</key>
@@ -47,5 +47,7 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>MGLMetricsTestServerURL</key>
<string>https://cloudfront-staging.tilestream.net</string>
</dict>
</plist>

View File

@@ -9,18 +9,18 @@
'product_extension': 'app',
'mac_bundle': 1,
'mac_bundle_resources': [
'<!@(find ./img -type f)',
'<!@(find ../ios/app/img -type f)',
'./features.geojson',
'./Settings.bundle/'
],
'dependencies': [
'../../mbgl.gyp:bundle_styles',
'../../mbgl.gyp:core',
'../../mbgl.gyp:platform-<(platform_lib)',
'../../mbgl.gyp:http-<(http_lib)',
'../../mbgl.gyp:asset-<(asset_lib)',
'../../mbgl.gyp:cache-<(cache_lib)',
'../mbgl.gyp:bundle_styles',
'../mbgl.gyp:core',
'../mbgl.gyp:platform-<(platform_lib)',
'../mbgl.gyp:http-<(http_lib)',
'../mbgl.gyp:asset-<(asset_lib)',
'../mbgl.gyp:cache-<(cache_lib)',
],
'sources': [
@@ -38,7 +38,7 @@
'SDKROOT': 'iphoneos',
'SUPPORTED_PLATFORMS': 'iphonesimulator iphoneos',
'IPHONEOS_DEPLOYMENT_TARGET': '7.0',
'INFOPLIST_FILE': 'app-info.plist',
'INFOPLIST_FILE': '../ios/app/app-info.plist',
'TARGETED_DEVICE_FAMILY': '1,2',
'COMBINE_HIDPI_IMAGES': 'NO', # don't merge @2x.png images into .tiff files
'CLANG_ENABLE_OBJC_ARC': 'YES',

View File

@@ -0,0 +1,7 @@
#import <UIKit/UIKit.h>
@interface MBXBenchAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@@ -0,0 +1,15 @@
#import "MBXBenchAppDelegate.h"
#import "MBXBenchViewController.h"
@implementation MBXBenchAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [MBXBenchViewController new];
[self.window makeKeyAndVisible];
return YES;
}
@end

View File

@@ -0,0 +1,5 @@
#import <UIKit/UIKit.h>
@interface MBXBenchViewController : UIViewController
@end

View File

@@ -0,0 +1,148 @@
#import "MBXBenchViewController.h"
#import <mbgl/ios/MGLMapView.h>
#include "locations.hpp"
#include <chrono>
@interface MGLMapView (MBXBenchmarkAdditions)
#pragma mark - Debugging
/** Triggers another render pass even when it is not necessary. */
- (void)invalidate;
/** Returns whether the map view is currently loading or processing any assets required to render the map */
- (BOOL)isFullyLoaded;
@end
@interface MBXBenchViewController () <MGLMapViewDelegate>
@property (nonatomic) MGLMapView *mapView;
@end
@implementation MBXBenchViewController
#pragma mark - Setup
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL* url = [[NSURL alloc] initWithString:@"asset://styles/mapbox-streets-v7.json"];
self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:nil styleURL:url];
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.mapView.delegate = self;
self.mapView.zoomEnabled = NO;
self.mapView.scrollEnabled = NO;
self.mapView.rotateEnabled = NO;
self.mapView.userInteractionEnabled = YES;
[self.mapView setDebugActive:NO];
[self startBenchmarkIteration];
[self.view addSubview:self.mapView];
}
using Clock = std::chrono::steady_clock;
using TimePoint = Clock::time_point;
template <typename Duration>
inline int64_t Microseconds(Duration d) {
return std::chrono::duration_cast<std::chrono::microseconds>(d).count();
}
size_t idx = 0;
enum class State { None, WaitingForAssets, WarmingUp, Benchmarking } state = State::None;
int frames = 0;
TimePoint started;
std::vector<std::pair<std::string, double>> result;
static const int warmupDuration = 20; // frames
static const int benchmarkDuration = 200; // frames
- (void)startBenchmarkIteration
{
if (mbgl::bench::locations.size() > idx) {
const auto& location = mbgl::bench::locations[idx];
[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(location.latitude, location.longitude) zoomLevel:location.zoom animated:NO];
self.mapView.direction = location.bearing;
state = State::WaitingForAssets;
NSLog(@"Benchmarking \"%s\"", location.name.c_str());
NSLog(@"- Loading assets...");
} else {
// Do nothing. The benchmark is completed.
NSLog(@"Benchmark completed.");
NSLog(@"Result:");
size_t colWidth = 0;
for (const auto& row : result) {
colWidth = std::max(row.first.size(), colWidth);
}
for (const auto& row : result) {
NSLog(@"| %-*s | %4.1f fps |", int(colWidth), row.first.c_str(), row.second);
}
exit(0);
}
}
- (void)mapViewDidFinishRenderingMap:(MGLMapView *)mapView fullyRendered:(__unused BOOL)fullyRendered
{
if (state == State::Benchmarking)
{
frames++;
if (frames >= benchmarkDuration)
{
state = State::None;
// Report FPS
const auto duration = Microseconds(Clock::now() - started);
const auto fps = double(frames * 1e6) / duration;
result.emplace_back(mbgl::bench::locations[idx].name, fps);
NSLog(@"- FPS: %.1f", fps);
// Start benchmarking the next location.
idx++;
[self startBenchmarkIteration];
} else {
[mapView invalidate];
}
return;
}
else if (state == State::WarmingUp)
{
frames++;
if (frames >= warmupDuration)
{
frames = 0;
state = State::Benchmarking;
started = Clock::now();
NSLog(@"- Benchmarking for %d frames...", benchmarkDuration);
}
[mapView invalidate];
return;
}
else if (state == State::WaitingForAssets)
{
if ([mapView isFullyLoaded])
{
// Start the benchmarking timer.
state = State::WarmingUp;
[self.mapView emptyMemoryCache];
NSLog(@"- Warming up for %d frames...", warmupDuration);
[mapView invalidate];
}
return;
}
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
@end

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.mapbox.GL.benchmark</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.0.2</string>
<key>CFBundleSignature</key>
<string>MBGL</string>
<key>CFBundleVersion</key>
<string>0.0.3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>(c) 2015 Mapbox</string>
<key>UIApplicationExitsOnSuspend</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>Default</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -u
LIST=(
"DIN%20Offc%20Pro%20Regular%2c%20Arial%20Unicode%20MS%20Regular/0-255.pbf"
"DIN%20Offc%20Pro%20Medium%2c%20Arial%20Unicode%20MS%20Bold/0-255.pbf"
"DIN%20Offc%20Pro%20Medium%2c%20Arial%20Unicode%20MS%20Regular/0-255.pbf"
"DIN%20Offc%20Pro%20Medium%2c%20Arial%20Unicode%20MS%20Regular/8192-8447.pbf"
"DIN%20Offc%20Pro%20Bold%2c%20Arial%20Unicode%20MS%20Regular/0-255.pbf"
"DIN%20Offc%20Pro%20Regular%2c%20Arial%20Unicode%20MS%20Regular/256-511.pbf"
"DIN%20Offc%20Pro%20Regular%2c%20Arial%20Unicode%20MS%20Regular/8192-8447.pbf"
"DIN%20Offc%20Pro%20Italic%2c%20Arial%20Unicode%20MS%20Regular/0-255.pbf"
"DIN%20Offc%20Pro%20Medium%2c%20Arial%20Unicode%20MS%20Regular/256-511.pbf"
)
# from https://gist.github.com/cdown/1163649
urldecode() {
local url_encoded="${1//+/ }"
printf '%b' "${url_encoded//%/\x}"
}
for i in ${LIST[@]} ; do
OUTPUT=`urldecode "$i"`
if [ ! -f "${OUTPUT}" ] ; then
mkdir -p "`dirname "${OUTPUT}"`"
echo "Downloading glyph '${OUTPUT}'"
curl -# "https://api.tiles.mapbox.com/v4/fontstack/${i}?access_token=${MAPBOX_ACCESS_TOKEN}" | gunzip > "${OUTPUT}"
fi
done

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
#!/usr/bin/env bash
set -u
LIST=(
# paris
"mapbox.mapbox-streets-v6/11/1037/704.vector.pbf"
"mapbox.mapbox-streets-v6/11/1037/705.vector.pbf"
"mapbox.mapbox-streets-v6/11/1038/704.vector.pbf"
"mapbox.mapbox-streets-v6/11/1038/705.vector.pbf"
"mapbox.mapbox-streets-v6/11/1036/704.vector.pbf"
"mapbox.mapbox-streets-v6/11/1037/703.vector.pbf"
"mapbox.mapbox-streets-v6/11/1036/705.vector.pbf"
"mapbox.mapbox-streets-v6/11/1038/703.vector.pbf"
"mapbox.mapbox-streets-v6/11/1036/703.vector.pbf"
"mapbox.mapbox-terrain-v2/11/1037/704.vector.pbf"
"mapbox.mapbox-terrain-v2/11/1037/705.vector.pbf"
"mapbox.mapbox-terrain-v2/11/1038/704.vector.pbf"
"mapbox.mapbox-terrain-v2/11/1038/705.vector.pbf"
"mapbox.mapbox-terrain-v2/11/1036/704.vector.pbf"
"mapbox.mapbox-terrain-v2/11/1037/703.vector.pbf"
"mapbox.mapbox-terrain-v2/11/1036/705.vector.pbf"
"mapbox.mapbox-terrain-v2/11/1038/703.vector.pbf"
"mapbox.mapbox-terrain-v2/11/1036/703.vector.pbf"
# paris2
"mapbox.mapbox-streets-v6/13/4150/2819.vector.pbf"
"mapbox.mapbox-streets-v6/13/4149/2819.vector.pbf"
"mapbox.mapbox-streets-v6/13/4150/2818.vector.pbf"
"mapbox.mapbox-streets-v6/13/4149/2820.vector.pbf"
"mapbox.mapbox-streets-v6/13/4148/2819.vector.pbf"
"mapbox.mapbox-streets-v6/13/4149/2818.vector.pbf"
"mapbox.mapbox-streets-v6/13/4150/2817.vector.pbf"
"mapbox.mapbox-streets-v6/13/4148/2820.vector.pbf"
"mapbox.mapbox-streets-v6/13/4148/2818.vector.pbf"
"mapbox.mapbox-streets-v6/13/4149/2817.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4150/2819.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4149/2819.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4150/2818.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4149/2820.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4148/2819.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4149/2818.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4150/2817.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4148/2820.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4148/2818.vector.pbf"
"mapbox.mapbox-terrain-v2/13/4149/2817.vector.pbf"
# alps
"mapbox.mapbox-streets-v6/6/34/23.vector.pbf"
"mapbox.mapbox-streets-v6/6/34/22.vector.pbf"
"mapbox.mapbox-streets-v6/6/33/23.vector.pbf"
"mapbox.mapbox-streets-v6/6/33/22.vector.pbf"
"mapbox.mapbox-streets-v6/6/34/21.vector.pbf"
"mapbox.mapbox-streets-v6/6/32/23.vector.pbf"
"mapbox.mapbox-streets-v6/6/32/22.vector.pbf"
"mapbox.mapbox-streets-v6/6/33/21.vector.pbf"
"mapbox.mapbox-streets-v6/6/32/21.vector.pbf"
"mapbox.mapbox-terrain-v2/6/34/23.vector.pbf"
"mapbox.mapbox-terrain-v2/6/34/22.vector.pbf"
"mapbox.mapbox-terrain-v2/6/33/23.vector.pbf"
"mapbox.mapbox-terrain-v2/6/33/22.vector.pbf"
"mapbox.mapbox-terrain-v2/6/34/21.vector.pbf"
"mapbox.mapbox-terrain-v2/6/32/23.vector.pbf"
"mapbox.mapbox-terrain-v2/6/32/22.vector.pbf"
"mapbox.mapbox-terrain-v2/6/33/21.vector.pbf"
"mapbox.mapbox-terrain-v2/6/32/21.vector.pbf"
# us east
"mapbox.mapbox-streets-v6/5/9/12.vector.pbf"
"mapbox.mapbox-streets-v6/5/8/12.vector.pbf"
"mapbox.mapbox-streets-v6/5/9/13.vector.pbf"
"mapbox.mapbox-streets-v6/5/8/13.vector.pbf"
"mapbox.mapbox-streets-v6/5/9/11.vector.pbf"
"mapbox.mapbox-streets-v6/5/7/12.vector.pbf"
"mapbox.mapbox-streets-v6/5/8/11.vector.pbf"
"mapbox.mapbox-streets-v6/5/7/13.vector.pbf"
"mapbox.mapbox-streets-v6/5/7/11.vector.pbf"
"mapbox.mapbox-terrain-v2/5/9/12.vector.pbf"
"mapbox.mapbox-terrain-v2/5/8/12.vector.pbf"
"mapbox.mapbox-terrain-v2/5/9/13.vector.pbf"
"mapbox.mapbox-terrain-v2/5/8/13.vector.pbf"
"mapbox.mapbox-terrain-v2/5/9/11.vector.pbf"
"mapbox.mapbox-terrain-v2/5/7/12.vector.pbf"
"mapbox.mapbox-terrain-v2/5/8/11.vector.pbf"
"mapbox.mapbox-terrain-v2/5/7/13.vector.pbf"
"mapbox.mapbox-terrain-v2/5/7/11.vector.pbf"
# greater la
"mapbox.mapbox-streets-v6/9/88/204.vector.pbf"
"mapbox.mapbox-streets-v6/9/88/205.vector.pbf"
"mapbox.mapbox-streets-v6/9/89/204.vector.pbf"
"mapbox.mapbox-streets-v6/9/89/205.vector.pbf"
"mapbox.mapbox-streets-v6/9/87/204.vector.pbf"
"mapbox.mapbox-streets-v6/9/88/203.vector.pbf"
"mapbox.mapbox-streets-v6/9/87/205.vector.pbf"
"mapbox.mapbox-streets-v6/9/89/203.vector.pbf"
"mapbox.mapbox-streets-v6/9/87/203.vector.pbf"
"mapbox.mapbox-terrain-v2/9/88/204.vector.pbf"
"mapbox.mapbox-terrain-v2/9/88/205.vector.pbf"
"mapbox.mapbox-terrain-v2/9/89/204.vector.pbf"
"mapbox.mapbox-terrain-v2/9/89/205.vector.pbf"
"mapbox.mapbox-terrain-v2/9/87/204.vector.pbf"
"mapbox.mapbox-terrain-v2/9/88/203.vector.pbf"
"mapbox.mapbox-terrain-v2/9/87/205.vector.pbf"
"mapbox.mapbox-terrain-v2/9/89/203.vector.pbf"
"mapbox.mapbox-terrain-v2/9/87/203.vector.pbf"
# sf
"mapbox.mapbox-streets-v6/14/2621/6333.vector.pbf"
"mapbox.mapbox-streets-v6/14/2620/6333.vector.pbf"
"mapbox.mapbox-streets-v6/14/2621/6334.vector.pbf"
"mapbox.mapbox-streets-v6/14/2620/6334.vector.pbf"
"mapbox.mapbox-streets-v6/14/2621/6332.vector.pbf"
"mapbox.mapbox-streets-v6/14/2619/6333.vector.pbf"
"mapbox.mapbox-streets-v6/14/2620/6332.vector.pbf"
"mapbox.mapbox-streets-v6/14/2619/6334.vector.pbf"
"mapbox.mapbox-streets-v6/14/2619/6332.vector.pbf"
"mapbox.mapbox-terrain-v2/14/2621/6333.vector.pbf"
"mapbox.mapbox-terrain-v2/14/2620/6333.vector.pbf"
"mapbox.mapbox-terrain-v2/14/2621/6334.vector.pbf"
"mapbox.mapbox-terrain-v2/14/2620/6334.vector.pbf"
"mapbox.mapbox-terrain-v2/14/2621/6332.vector.pbf"
"mapbox.mapbox-terrain-v2/14/2619/6333.vector.pbf"
"mapbox.mapbox-terrain-v2/14/2620/6332.vector.pbf"
"mapbox.mapbox-terrain-v2/14/2619/6334.vector.pbf"
"mapbox.mapbox-terrain-v2/14/2619/6332.vector.pbf"
# oakland
"mapbox.mapbox-streets-v6/12/657/1582.vector.pbf"
"mapbox.mapbox-streets-v6/12/657/1583.vector.pbf"
"mapbox.mapbox-streets-v6/12/658/1582.vector.pbf"
"mapbox.mapbox-streets-v6/12/658/1583.vector.pbf"
"mapbox.mapbox-streets-v6/12/656/1582.vector.pbf"
"mapbox.mapbox-streets-v6/12/657/1581.vector.pbf"
"mapbox.mapbox-streets-v6/12/656/1583.vector.pbf"
"mapbox.mapbox-streets-v6/12/658/1581.vector.pbf"
"mapbox.mapbox-streets-v6/12/656/1581.vector.pbf"
"mapbox.mapbox-terrain-v2/12/657/1582.vector.pbf"
"mapbox.mapbox-terrain-v2/12/657/1583.vector.pbf"
"mapbox.mapbox-terrain-v2/12/658/1582.vector.pbf"
"mapbox.mapbox-terrain-v2/12/658/1583.vector.pbf"
"mapbox.mapbox-terrain-v2/12/656/1582.vector.pbf"
"mapbox.mapbox-terrain-v2/12/657/1581.vector.pbf"
"mapbox.mapbox-terrain-v2/12/656/1583.vector.pbf"
"mapbox.mapbox-terrain-v2/12/658/1581.vector.pbf"
"mapbox.mapbox-terrain-v2/12/656/1581.vector.pbf"
# germany
"mapbox.mapbox-streets-v6/6/34/21.vector.pbf"
"mapbox.mapbox-streets-v6/6/34/22.vector.pbf"
"mapbox.mapbox-streets-v6/6/33/21.vector.pbf"
"mapbox.mapbox-streets-v6/6/33/22.vector.pbf"
"mapbox.mapbox-streets-v6/6/34/20.vector.pbf"
"mapbox.mapbox-streets-v6/6/32/21.vector.pbf"
"mapbox.mapbox-streets-v6/6/33/20.vector.pbf"
"mapbox.mapbox-streets-v6/6/32/22.vector.pbf"
"mapbox.mapbox-streets-v6/6/32/20.vector.pbf"
"mapbox.mapbox-terrain-v2/6/34/21.vector.pbf"
"mapbox.mapbox-terrain-v2/6/34/22.vector.pbf"
"mapbox.mapbox-terrain-v2/6/33/21.vector.pbf"
"mapbox.mapbox-terrain-v2/6/33/22.vector.pbf"
"mapbox.mapbox-terrain-v2/6/34/20.vector.pbf"
"mapbox.mapbox-terrain-v2/6/32/21.vector.pbf"
"mapbox.mapbox-terrain-v2/6/33/20.vector.pbf"
"mapbox.mapbox-terrain-v2/6/32/22.vector.pbf"
"mapbox.mapbox-terrain-v2/6/32/20.vector.pbf"
)
for OUTPUT in ${LIST[@]} ; do
if [ ! -f "${OUTPUT}" ] ; then
mkdir -p "`dirname "${OUTPUT}"`"
echo "Downloading tile '${OUTPUT}'"
curl -# "https://a.tiles.mapbox.com/v4/${OUTPUT}?access_token=${MAPBOX_ACCESS_TOKEN}" | gunzip > "${OUTPUT}"
fi
done

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"attribution":"<a href=\"https://www.mapbox.com/about/maps/\" target=\"_blank\">&copy; Mapbox &copy; OpenStreetMap</a> <a class=\"mapbox-improve-map\" href=\"https://www.mapbox.com/map-feedback/\" target=\"_blank\">Improve this map</a>","bounds":[-180,-85.0511,180,85.0511],"center":[0,0,3],"description":"","filesize":0,"format":"pbf","id":"mapbox.mapbox-terrain-v2","maskLevel":9,"maxzoom":14,"minzoom":0,"name":"Mapbox Terrain V2","private":true,"scheme":"xyz","tilejson":"2.0.0","tiles":["asset://tiles/mapbox.mapbox-terrain-v2/{z}/{x}/{y}.vector.pbf"],"vector_layers":[{"description":"Generalized landcover classification","fields":{"class":"One of: wood, scrub, grass, crop, snow"},"id":"landcover","maxzoom":22,"minzoom":0},{"description":"","fields":{"class":"One of: shadow, highlight","level":"Brightness %. One of: 94, 90, 89, 78, 67, 56"},"id":"hillshade","maxzoom":22,"minzoom":0},{"description":"Elevation contour polygons","fields":{"ele":"Integer. The elevation of the contour in meters.","index":"Indicator for every 2nd, 5th, or 10th contour. Coastlines are given -1. One of: 2, 5, 10, -1, null"},"id":"contour","maxzoom":22,"minzoom":0}]}

View File

@@ -0,0 +1,63 @@
{
'includes': [
'../../gyp/common.gypi',
],
'targets': [
{ 'target_name': 'ios-bench',
'product_name': 'Bench GL',
'type': 'executable',
'product_extension': 'app',
'mac_bundle': 1,
'mac_bundle_resources': [
'<!@(find ../ios/benchmark/img -type f)',
'assets/glyphs',
'assets/sprites',
'assets/styles',
'assets/tiles',
],
'dependencies': [
'../mbgl.gyp:core',
'../mbgl.gyp:platform-<(platform_lib)',
'../mbgl.gyp:http-<(http_lib)',
'../mbgl.gyp:asset-<(asset_lib)',
'../mbgl.gyp:cache-<(cache_lib)',
],
'sources': [
'./main.m',
'./MBXBenchAppDelegate.h',
'./MBXBenchAppDelegate.m',
'./MBXBenchViewController.h',
'./MBXBenchViewController.mm',
'./locations.hpp',
'./locations.cpp',
],
'xcode_settings': {
'SDKROOT': 'iphoneos',
'SUPPORTED_PLATFORMS': 'iphoneos',
'IPHONEOS_DEPLOYMENT_TARGET': '7.0',
'INFOPLIST_FILE': '../ios/benchmark/app-info.plist',
'TARGETED_DEVICE_FAMILY': '1,2',
'COMBINE_HIDPI_IMAGES': 'NO', # don't merge @2x.png images into .tiff files
'CLANG_ENABLE_OBJC_ARC': 'YES',
'CLANG_ENABLE_MODULES': 'YES',
},
'configurations': {
'Debug': {
'xcode_settings': {
'CODE_SIGN_IDENTITY': 'iPhone Developer',
},
},
'Release': {
'xcode_settings': {
'CODE_SIGN_IDENTITY': 'iPhone Distribution',
'ARCHS': [ "arm64" ],
},
},
},
}
]
}

View File

@@ -0,0 +1,140 @@
#import "MBXBenchViewController.h"
#import <mbgl/ios/MGLMapView.h>
#import <mbgl/ios/MGLMapView_private.h>
#include "locations.hpp"
#include <chrono>
@interface MBXBenchViewController () <MGLMapViewDelegate>
@property (nonatomic) MGLMapView *mapView;
@end
@implementation MBXBenchViewController
#pragma mark - Setup
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL* url = [[NSURL alloc] initWithString:@"asset://styles/mapbox-streets-v7.json"];
self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:nil styleURL:url];
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.mapView.delegate = self;
self.mapView.zoomEnabled = NO;
self.mapView.scrollEnabled = NO;
self.mapView.rotateEnabled = NO;
self.mapView.userInteractionEnabled = YES;
[self.mapView setDebugActive:NO];
[self startBenchmarkIteration];
[self.view addSubview:self.mapView];
}
using Clock = std::chrono::steady_clock;
using TimePoint = Clock::time_point;
template <typename Duration>
inline int64_t Microseconds(Duration d) {
return std::chrono::duration_cast<std::chrono::microseconds>(d).count();
}
size_t idx = 0;
enum class State { None, WaitingForAssets, WarmingUp, Benchmarking } state = State::None;
int frames = 0;
TimePoint started;
std::vector<std::pair<std::string, double>> result;
static const int warmupDuration = 20; // frames
static const int benchmarkDuration = 200; // frames
- (void)startBenchmarkIteration
{
if (mbgl::bench::locations.size() > idx) {
const auto& location = mbgl::bench::locations[idx];
[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(location.latitude, location.longitude) zoomLevel:location.zoom animated:NO];
self.mapView.direction = location.bearing;
state = State::WaitingForAssets;
NSLog(@"Benchmarking \"%s\"", location.name.c_str());
NSLog(@"- Loading assets...");
} else {
// Do nothing. The benchmark is completed.
NSLog(@"Benchmark completed.");
NSLog(@"Result:");
size_t colWidth = 0;
for (const auto& row : result) {
colWidth = std::max(row.first.size(), colWidth);
}
for (const auto& row : result) {
NSLog(@"| %-*s | %4.1f fps |", int(colWidth), row.first.c_str(), row.second);
}
exit(0);
}
}
- (void)mapViewDidFinishRenderingMap:(MGLMapView *)mapView fullyRendered:(BOOL)fullyRendered
{
(void)mapView;
(void)fullyRendered;
if (state == State::Benchmarking)
{
frames++;
if (frames >= benchmarkDuration)
{
state = State::None;
// Report FPS
const auto duration = Microseconds(Clock::now() - started);
const auto fps = double(frames * 1e6) / duration;
result.emplace_back(mbgl::bench::locations[idx].name, fps);
NSLog(@"- FPS: %.1f", fps);
// Start benchmarking the next location.
idx++;
[self startBenchmarkIteration];
} else {
[mapView invalidate];
}
return;
}
else if (state == State::WarmingUp)
{
frames++;
if (frames >= warmupDuration)
{
frames = 0;
state = State::Benchmarking;
started = Clock::now();
NSLog(@"- Benchmarking for %d frames...", benchmarkDuration);
}
[mapView invalidate];
return;
}
else if (state == State::WaitingForAssets)
{
if ([mapView isFullyLoaded])
{
// Start the benchmarking timer.
state = State::WarmingUp;
[self.mapView emptyMemoryCache];
NSLog(@"- Warming up for %d frames...", warmupDuration);
[mapView invalidate];
}
return;
}
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
@end

View File

@@ -0,0 +1,63 @@
{
'includes': [
'../../gyp/common.gypi',
],
'targets': [
{ 'target_name': 'ios-bench',
'product_name': 'Bench GL',
'type': 'executable',
'product_extension': 'app',
'mac_bundle': 1,
'mac_bundle_resources': [
'<!@(find ../ios/benchmark/img -type f)',
'assets/glyphs',
'assets/sprites',
'assets/styles',
'assets/tiles',
],
'dependencies': [
'../mbgl.gyp:core',
'../mbgl.gyp:platform-<(platform_lib)',
'../mbgl.gyp:http-<(http_lib)',
'../mbgl.gyp:asset-<(asset_lib)',
'../mbgl.gyp:cache-<(cache_lib)',
],
'sources': [
'./main.m',
'./MBXBenchAppDelegate.h',
'./MBXBenchAppDelegate.m',
'./MBXBenchViewController.h',
'./MBXBenchViewController.mm',
'./locations.hpp',
'./locations.cpp',
],
'xcode_settings': {
'SDKROOT': 'iphoneos',
'SUPPORTED_PLATFORMS': 'iphoneos',
'IPHONEOS_DEPLOYMENT_TARGET': '7.0',
'INFOPLIST_FILE': '../ios/benchmark/app-info.plist',
'TARGETED_DEVICE_FAMILY': '1,2',
'COMBINE_HIDPI_IMAGES': 'NO', # don't merge @2x.png images into .tiff files
'CLANG_ENABLE_OBJC_ARC': 'YES',
'CLANG_ENABLE_MODULES': 'YES',
},
'configurations': {
'Debug': {
'xcode_settings': {
'CODE_SIGN_IDENTITY': 'iPhone Developer',
},
},
'Release': {
'xcode_settings': {
'CODE_SIGN_IDENTITY': 'iPhone Distribution',
'ARCHS': [ "arm64" ],
},
},
},
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1009 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
ios/benchmark/img/Icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Some files were not shown because too many files have changed in this diff Show More