Merge pull request #1380 from mapbox/benchmark

Add benchmarking application for iOS
This commit is contained in:
Konstantin Käfer
2015-05-05 12:14:20 +02:00
54 changed files with 8817 additions and 9 deletions

4
.gitignore vendored
View File

@@ -22,3 +22,7 @@
/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*/

View File

@@ -120,7 +120,11 @@ ios-proj: Xcode/ios
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/gyp/ios.xcodeproj -configuration Release -target iosapp -jobs $(JOBS) $(XCPRETTY)
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

View File

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

View File

@@ -0,0 +1,14 @@
#import <UIKit/UIKit.h>
@interface MGLMapView ()
#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

View File

@@ -132,6 +132,7 @@ public:
void setDebug(bool value);
void toggleDebug();
bool getDebug() const;
bool isFullyLoaded() const;
private:
const std::unique_ptr<MapData> data;

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,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,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,64 @@
{
'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',
'../../include/mbgl/ios/MGLMapView_private.h',
'./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

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-miterlimit:1.41421;">
<image x="0" y="0" width="15px" height="15px" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAQ0lEQVQokcXP2wkAIAxD0Sidvqu5jhTxVXdIPsz/4ZLi3hLkKgsBwOjsX3zBcztKeSvllQKeSlnCQ8GhfA5cHvfk8QNc8hvDN5gIKwAAAABJRU5ErkJggg=="/>
<path id="path7143" d="M9.48355,2.89095C8.18827,3.22425 6.67888,4.56018 5.90484,6.38831L4.93731,6.63727C4.23814,6.81719 3.97174,7.44212 3.83781,8.06502L3.65856,8.89868L5.40366,8.44963L7.68238,9.79563L8.13143,11.5407L8.77503,10.9814C9.25592,10.5634 9.67465,10.0284 9.49474,9.32928L9.24577,8.36174C10.4732,6.80143 10.9147,4.8347 10.5814,3.53941L10.3567,2.66627L9.48355,2.89095ZM8.40657,5.10044C8.73798,5.01516 9.08086,5.2177 9.16614,5.54911C9.25142,5.88052 9.04888,6.2234 8.71747,6.30868C8.38606,6.39396 8.04318,6.19142 7.9579,5.86001C7.87262,5.5286 8.07516,5.18572 8.40657,5.10044L8.40657,5.10044ZM5.41251,9.7356L5.18818,10.1154C4.86414,10.664 4.97269,11.7811 4.97269,11.7811C4.97269,11.7811 5.9677,11.3976 6.32753,10.7884L6.55187,10.4086L5.41251,9.7356Z" style="fill:white;fill-rule:nonzero;stroke-width:0.62px;stroke:white;"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

View File

@@ -0,0 +1,18 @@
#include "locations.hpp"
namespace mbgl {
namespace bench {
const std::vector<Location> locations = {
{ "paris", 2.3411, 48.8664, 11, 0.0 },
{ "paris2", 2.3516, 48.8356, 13, 273.8 },
{ "alps", 10.6107, 46.9599, 6, 0.0 },
{ "us east", -84.3395, 36.9400, 5, 0.0 },
{ "greater la", -117.9529, 34.0259, 9, 0.0 },
{ "sf", -122.4202, 37.7625, 14, 0.0 },
{ "oakland", -122.2328, 37.8267, 12, 0.0 },
{ "germany", 9.2280, 50.9262, 6, 0.0 },
};
}
}

View File

@@ -0,0 +1,23 @@
#ifndef MBGL_BENCH_LOCATIONS
#define MBGL_BENCH_LOCATIONS
#include <vector>
#include <string>
namespace mbgl {
namespace bench {
struct Location {
const std::string name;
const double longitude;
const double latitude;
const double zoom;
const double bearing;
};
extern const std::vector<Location> locations;
}
}
#endif

10
ios/benchmark/main.m Normal file
View File

@@ -0,0 +1,10 @@
#import <UIKit/UIKit.h>
#import "MBXBenchAppDelegate.h"
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([MBXBenchAppDelegate class]));
}
}

View File

@@ -3,6 +3,7 @@
#include <mbgl/storage/response.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/url.hpp>
#include <mbgl/util/uv.hpp>
#include <uv.h>
@@ -58,10 +59,10 @@ AssetRequest::AssetRequest(const Resource& resource_, Callback callback_, uv_loo
std::string path;
if (url.size() <= 8 || url[8] == '/') {
// This is an empty or absolute path.
path = url.substr(8);
path = mbgl::util::percentDecode(url.substr(8));
} else {
// This is a relative path. Prefix with the application root.
path = assetRoot + "/" + url.substr(8);
path = assetRoot + "/" + mbgl::util::percentDecode(url.substr(8));
}
uv_fs_open(loop, &req, path.c_str(), O_RDONLY, S_IRUSR, fileOpened);

View File

@@ -613,6 +613,8 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
{
if ( ! self.glSnapshotView || self.glSnapshotView.hidden)
{
[self notifyMapChange:@(mbgl::MapChangeWillStartRenderingMap)];
_mbglMap->resize(rect.size.width, rect.size.height, view.contentScaleFactor);
CGFloat zoomFactor = _mbglMap->getMaxZoom() - _mbglMap->getMinZoom() + 1;
@@ -626,6 +628,8 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
_mbglMap->setSourceTileCacheSize(cacheSize);
_mbglMap->renderSync();
[self notifyMapChange:@(mbgl::MapChangeDidFinishRenderingMap)];
}
}
@@ -2415,6 +2419,11 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
[self notifyMapChange:@(mbgl::MapChangeRegionIsChanging)];
}
- (BOOL)isFullyLoaded
{
return _mbglMap->isFullyLoaded();
}
- (void)prepareForInterfaceBuilder
{
[super prepareForInterfaceBuilder];

16
scripts/ios/benchmark.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -e
set -o pipefail
set -u
if [ -z "$(which ios-deploy)" ] ; then
npm install -g ios-deploy
fi
(cd ios/benchmark/assets/tiles && ./download.sh)
(cd ios/benchmark/assets/glyphs && ./download.sh)
make ibench
ios-deploy --debug --noninteractive --bundle "gyp/build/Release-iphoneos/Bench GL.app"

View File

@@ -286,6 +286,10 @@ bool Map::getDebug() const {
return data->getDebug();
}
bool Map::isFullyLoaded() const {
return data->getFullyLoaded();
}
void Map::addClass(const std::string& klass) {
if (data->addClass(klass)) {
update(Update::Classes);

View File

@@ -220,6 +220,16 @@ void MapContext::update() {
updateTiles();
if (sprite->isLoaded() && style->isLoaded()) {
if (!data.getFullyLoaded()) {
data.setFullyLoaded(true);
}
} else {
if (data.getFullyLoaded()) {
data.setFullyLoaded(false);
}
}
view.invalidate([this] { render(); });
}
@@ -276,7 +286,7 @@ void MapContext::setSourceTileCacheSize(size_t size) {
for (const auto &source : style->sources) {
source->setCacheSize(sourceCacheSize);
}
env.performCleanup();
view.invalidate([this] { render(); });
}
}
@@ -286,7 +296,7 @@ void MapContext::onLowMemory() {
for (const auto &source : style->sources) {
source->onLowMemory();
}
env.performCleanup();
view.invalidate([this] { render(); });
}
}

View File

@@ -64,6 +64,13 @@ public:
debug = value;
}
inline bool getFullyLoaded() const {
return loaded;
}
inline void setFullyLoaded(bool value) {
loaded = value;
}
inline TimePoint getAnimationTime() const {
// We're casting the TimePoint to and from a Duration because libstdc++
// has a bug that doesn't allow TimePoints to be atomic.
@@ -91,6 +98,7 @@ private:
std::string accessToken;
std::vector<std::string> classes;
std::atomic<uint8_t> debug { false };
std::atomic<bool> loaded { false };
std::atomic<Duration> animationTime;
std::atomic<Duration> defaultTransitionDuration;

View File

@@ -85,13 +85,14 @@ void Style::loadJSON(const uint8_t *const data) {
layers = parser.getLayers();
sprite_url = parser.getSprite();
glyph_url = parser.getGlyphURL();
loaded = true;
}
bool Style::isLoaded() const {
// TODO: move loading into Style
// if (!loaded) {
// return false;
// }
if (!loaded) {
return false;
}
for (const auto& source : sources) {
if (!source->isLoaded()) {

View File

@@ -41,6 +41,7 @@ public:
std::string base;
private:
bool loaded = false;
std::string sprite_url;
PropertyTransition defaultTransition;
std::unique_ptr<uv::rwlock> mtx;

View File

@@ -154,7 +154,7 @@ GlyphPBF::GlyphPBF(const std::string &glyphURL,
env.requestAsync({ Resource::Kind::Glyphs, url }, [&, url](const Response &res) {
if (res.status != Response::Successful) {
// Something went wrong with loading the glyph pbf. Pass on the error to the future listeners.
const std::string msg = std::string { "[ERROR] failed to load glyphs: " } + res.message;
const std::string msg = std::string { "[ERROR] failed to load glyphs: " } + url + " message: " + res.message;
promise.set_exception(std::make_exception_ptr(std::runtime_error(msg)));
} else {
// Transfer the data to the GlyphSet and signal its availability.