From 9a1b54c8beb2b37213612a1ae34ac33c517b6b52 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Mon, 9 Apr 2018 16:37:29 -0400 Subject: WIP: view annotation benchmark --- platform/ios/app/MBXViewController.m | 2 +- .../MBXAnnotationViewBenchViewController.h | 13 ++ .../MBXAnnotationViewBenchViewController.mm | 153 +++++++++++++++++++++ platform/ios/benchmark/MBXBenchAppDelegate.m | 4 +- platform/ios/benchmark/MBXBenchViewController.mm | 30 ++-- platform/ios/benchmark/assets/styles/empty.json | 1 + platform/ios/benchmark/locations.cpp | 31 +++-- platform/ios/ios.xcodeproj/project.pbxproj | 16 ++- .../xcshareddata/xcschemes/iosapp.xcscheme | 2 +- platform/ios/src/MGLMapView.mm | 3 + 10 files changed, 224 insertions(+), 31 deletions(-) create mode 100644 platform/ios/benchmark/MBXAnnotationViewBenchViewController.h create mode 100644 platform/ios/benchmark/MBXAnnotationViewBenchViewController.mm create mode 100644 platform/ios/benchmark/assets/styles/empty.json diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 02652b5490..ddbb96493b 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -1562,7 +1562,7 @@ CLLocationCoordinate2D randomWorldCoordinate() { [annotations removeObjectAtIndex:0]; MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:nextAnnotation.coordinate fromDistance:10 - pitch:arc4random_uniform(60) + pitch:0//arc4random_uniform(60) heading:arc4random_uniform(360)]; __weak MBXViewController *weakSelf = self; [self.mapView flyToCamera:camera completionHandler:^{ diff --git a/platform/ios/benchmark/MBXAnnotationViewBenchViewController.h b/platform/ios/benchmark/MBXAnnotationViewBenchViewController.h new file mode 100644 index 0000000000..1368260bef --- /dev/null +++ b/platform/ios/benchmark/MBXAnnotationViewBenchViewController.h @@ -0,0 +1,13 @@ +// +// MBXAnnotationViewBenchViewController.h +// bench +// +// Created by Jason Wray on 4/5/18. +// Copyright © 2018 Mapbox. All rights reserved. +// + +#import + +@interface MBXAnnotationViewBenchViewController : UIViewController + +@end diff --git a/platform/ios/benchmark/MBXAnnotationViewBenchViewController.mm b/platform/ios/benchmark/MBXAnnotationViewBenchViewController.mm new file mode 100644 index 0000000000..238de3b8f7 --- /dev/null +++ b/platform/ios/benchmark/MBXAnnotationViewBenchViewController.mm @@ -0,0 +1,153 @@ +#import "MBXAnnotationViewBenchViewController.h" + +#import +#import "MGLMapView_Private.h" + +#include "locations.hpp" + +#include + +@interface CustomAnnotationView : MGLAnnotationView +@end + +@implementation CustomAnnotationView + +- (void)layoutSubviews { + [super layoutSubviews]; + + // Force the annotation view to maintain a constant size when the map is tilted. + self.scalesWithViewingDistance = YES; + + // Use CALayer’s corner radius to turn this view into a circle. + self.layer.cornerRadius = self.frame.size.width / 2; + self.layer.borderWidth = 2; + self.layer.borderColor = [UIColor whiteColor].CGColor; +} + +@end + + +@interface MBXAnnotationViewBenchViewController () + +@property (nonatomic) MGLMapView *mapView; + +@end + +@implementation MBXAnnotationViewBenchViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[NSURL URLWithString:@"asset://styles/empty.json"]]; + self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.mapView.delegate = self; + self.mapView.userInteractionEnabled = NO; + + [self.view addSubview:self.mapView]; +} + +- (void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView { + [self fillMapWithAnnotations]; +} + +- (void)mapView:(MGLMapView *)mapView didAddAnnotationViews:(NSArray *)annotationViews { + NSLog(@"Added %lu annotation views", (unsigned long)annotationViews.count); + [self startBenchmarkIteration]; +} + +- (void)fillMapWithAnnotations { + NSMutableArray *annotations = [NSMutableArray array]; + + for (NSInteger latitude = -89; latitude <= 90; latitude += 10) + { + for (NSInteger longitude = -180; longitude <= 180; longitude += 2) + { + //if (annotations.count >= 3000) break; + + MGLPointAnnotation *annotation = [[MGLPointAnnotation alloc] init]; + annotation.coordinate = CLLocationCoordinate2DMake(latitude, longitude); + [annotations addObject:annotation]; + } + } + + [self.mapView addAnnotations:annotations]; +} + +- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id)annotation { + // Use the point annotation’s longitude value (as a string) as the reuse identifier for its view. + NSString *reuseIdentifier = [NSString stringWithFormat:@"%f", annotation.coordinate.longitude]; + + // For better performance, always try to reuse existing annotations. + CustomAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier]; + + // If there’s no reusable annotation view available, initialize a new one. + if (!annotationView) { + annotationView = [[CustomAnnotationView alloc] initWithReuseIdentifier:reuseIdentifier]; + annotationView.frame = CGRectMake(0, 0, 40, 40); + + // Set the annotation view’s background color to a value determined by its longitude. + CGFloat hue = (CGFloat)annotation.coordinate.longitude / 100; + annotationView.backgroundColor = [UIColor colorWithHue:hue saturation:0.5 brightness:1 alpha:1]; + } + + return annotationView; +} + + +size_t idx = 0; +enum class State { None, WarmingUp, Benchmarking } state = State::None; +int frames = 0; +std::chrono::steady_clock::time_point started; +std::vector> result; + + +- (void)startBenchmarkIteration +{ + if (mbgl::bench::locations.size() > idx) { + const auto& location = mbgl::bench::locations[idx]; + + if (state != State::Benchmarking) state = State::WarmingUp; + + MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:CLLocationCoordinate2DMake(location.latitude, location.longitude) + fromDistance:location.zoom * 1000000 + pitch:30 + heading:location.bearing]; + [self.mapView setCamera:camera withDuration:1.0 animationTimingFunction:NULL completionHandler:^{ + // Start benchmarking the next location. + idx++; + [self startBenchmarkIteration]; + }]; + + NSLog(@"Benchmarking \"%s\"", location.name.c_str()); + } else { + // Do nothing. The benchmark is completed. + state = State::None; + NSLog(@"Benchmark completed."); + NSLog(@"Result:"); + // Report FPS + const auto duration = std::chrono::duration_cast(std::chrono::steady_clock::now() - started).count() ; + const auto fps = double(frames * 1e6) / duration; + NSLog(@"Total frames: %.1d", frames); + NSLog(@"FPS: %.1f", fps); + exit(0); + } +} + +- (void)mapViewDidFinishRenderingFrame:(MGLMapView *)mapView fullyRendered:(__unused BOOL)fullyRendered +{ + if (state == State::Benchmarking) + { + frames++; + + return; + } + else if (state == State::WarmingUp) + { + frames = 0; + state = State::Benchmarking; + started = std::chrono::steady_clock::now(); + + return; + } +} +@end diff --git a/platform/ios/benchmark/MBXBenchAppDelegate.m b/platform/ios/benchmark/MBXBenchAppDelegate.m index 684c90d336..52e3bdbe23 100644 --- a/platform/ios/benchmark/MBXBenchAppDelegate.m +++ b/platform/ios/benchmark/MBXBenchAppDelegate.m @@ -1,5 +1,5 @@ #import "MBXBenchAppDelegate.h" -#import "MBXBenchViewController.h" +#import "MBXAnnotationViewBenchViewController.h" #import NSString * const MBXMapboxAccessTokenDefaultsKey = @"MBXMapboxAccessToken"; @@ -23,7 +23,7 @@ NSString * const MBXMapboxAccessTokenDefaultsKey = @"MBXMapboxAccessToken"; } self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - self.window.rootViewController = [MBXBenchViewController new]; + self.window.rootViewController = [MBXAnnotationViewBenchViewController new]; [self.window makeKeyAndVisible]; return YES; diff --git a/platform/ios/benchmark/MBXBenchViewController.mm b/platform/ios/benchmark/MBXBenchViewController.mm index 84c2790d50..fe4d098458 100644 --- a/platform/ios/benchmark/MBXBenchViewController.mm +++ b/platform/ios/benchmark/MBXBenchViewController.mm @@ -1,10 +1,10 @@ #import "MBXBenchViewController.h" -#import "MBXBenchAppDelegate.h" - #import #import "MGLMapView_Private.h" +#import "MBXBenchAppDelegate.h" + #include "locations.hpp" #include @@ -19,25 +19,25 @@ #pragma mark - Setup -+ (void)initialize -{ - if (self == [MBXBenchViewController class]) - { - [[NSUserDefaults standardUserDefaults] registerDefaults:@{ - @"MBXUserTrackingMode": @(MGLUserTrackingModeNone), - @"MBXShowsUserLocation": @NO, - @"MBXDebug": @NO, - }]; - } -} +//+ (void)initialize +//{ +// if (self == [MBXBenchViewController class]) +// { +// [[NSUserDefaults standardUserDefaults] registerDefaults:@{ +// @"MBXUserTrackingMode": @(MGLUserTrackingModeNone), +// @"MBXShowsUserLocation": @NO, +// @"MBXDebug": @NO, +// }]; +// } +//} - (void)viewDidLoad { [super viewDidLoad]; // Use a local style and local assets if they’ve been downloaded. - NSURL *tileSourceURL = [[NSBundle mainBundle] URLForResource:@"mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6" withExtension:nil subdirectory:@"tiles"]; - NSURL *url = [NSURL URLWithString:tileSourceURL ? @"asset://styles/streets-v8.json" : @"mapbox://styles/mapbox/streets-v8"]; + NSURL *tileSourceURL = [[NSBundle mainBundle] URLForResource:@"mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7" withExtension:nil subdirectory:@"tiles"]; + NSURL *url = [NSURL URLWithString:tileSourceURL ? @"asset://styles/streets-v10.json" : @"mapbox://styles/mapbox/streets-v10"]; self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:url]; self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.mapView.delegate = self; diff --git a/platform/ios/benchmark/assets/styles/empty.json b/platform/ios/benchmark/assets/styles/empty.json new file mode 100644 index 0000000000..3986412580 --- /dev/null +++ b/platform/ios/benchmark/assets/styles/empty.json @@ -0,0 +1 @@ +{"version":8,"sources":{},"layers":[]} diff --git a/platform/ios/benchmark/locations.cpp b/platform/ios/benchmark/locations.cpp index 9f53877e40..d42c930f72 100644 --- a/platform/ios/benchmark/locations.cpp +++ b/platform/ios/benchmark/locations.cpp @@ -3,15 +3,30 @@ namespace mbgl { namespace bench { +//const std::vector 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 }, +// { "east asia", 126.5, 33.35, 5, 0.0 }, +//}; + const std::vector 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 }, + { "paris", 2.3411, 48.8664, 15, 0.0 }, + { "paris2", 2.3516, 48.8356, 60, 280.0 }, + { "alps", 10.6107, 46.9599, 50, 0.0 }, + { "us east", -84.3395, 36.9400, 15, 0.0 }, + { "greater la", -117.9529, 34.0259, 60, 0.0 }, + { "sf", -122.4202, 37.7625, 50, 280.0 }, + { "germany", 9.2280, 50.9262, 15, 0.0 }, + { "east asia", 126.5, 33.35, 60, 0.0 }, + { "paris3", 2.3411, 48.8664, 60, 0.0 }, + { "east asia2", 126.5, 33.35, 60, 0.0 }, + { "sf2", -122.4202, 37.7625, 60, 0.0 }, }; } diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 0951a94218..e6ddda9d87 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -339,6 +339,7 @@ 967C864D210A9D3C004DF794 /* UIDevice+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 967C864A210A9D3C004DF794 /* UIDevice+MGLAdditions.m */; }; 967C864E210A9D3C004DF794 /* UIDevice+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 967C864A210A9D3C004DF794 /* UIDevice+MGLAdditions.m */; }; 968F36B51E4D128D003A5522 /* MGLDistanceFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3557F7AE1E1D27D300CCA5E6 /* MGLDistanceFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 96C3CCF92076971D002588B5 /* MBXAnnotationViewBenchViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C3CCF82076971D002588B5 /* MBXAnnotationViewBenchViewController.mm */; }; 96E027231E57C76E004B8E66 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96E027251E57C76E004B8E66 /* Localizable.strings */; }; 96E516DC2000547000A02306 /* MGLPolyline_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9654C1251FFC1AB900DB6A19 /* MGLPolyline_Private.h */; }; 96E516DD200054F200A02306 /* MGLPolygon_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9654C1271FFC1CC000DB6A19 /* MGLPolygon_Private.h */; }; @@ -572,7 +573,6 @@ DAAF722E1DA903C700312FA4 /* MGLStyleValue_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAAF722A1DA903C700312FA4 /* MGLStyleValue_Private.h */; }; DABCABAC1CB80692000A7C39 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DABCABAB1CB80692000A7C39 /* main.m */; }; DABCABAF1CB80692000A7C39 /* MBXBenchAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DABCABAE1CB80692000A7C39 /* MBXBenchAppDelegate.m */; }; - DABCABB21CB80692000A7C39 /* MBXBenchViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = DABCABB11CB80692000A7C39 /* MBXBenchViewController.mm */; }; DABCABB71CB80692000A7C39 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DABCABB61CB80692000A7C39 /* Assets.xcassets */; }; DABCABBA1CB80692000A7C39 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DABCABB81CB80692000A7C39 /* LaunchScreen.storyboard */; }; DABCABC21CB8071D000A7C39 /* locations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DABCABBF1CB80717000A7C39 /* locations.cpp */; }; @@ -1005,6 +1005,8 @@ 967C8649210A9D3C004DF794 /* UIDevice+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIDevice+MGLAdditions.h"; sourceTree = ""; }; 967C864A210A9D3C004DF794 /* UIDevice+MGLAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIDevice+MGLAdditions.m"; sourceTree = ""; }; 968F36B41E4D0FC6003A5522 /* ja */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; + 96C3CCF72076971D002588B5 /* MBXAnnotationViewBenchViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBXAnnotationViewBenchViewController.h; sourceTree = ""; }; + 96C3CCF82076971D002588B5 /* MBXAnnotationViewBenchViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MBXAnnotationViewBenchViewController.mm; sourceTree = ""; }; 96E027241E57C76E004B8E66 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; 96E027271E57C77A004B8E66 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; 96E027281E57C7DB004B8E66 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; @@ -2022,6 +2024,8 @@ DABCABAE1CB80692000A7C39 /* MBXBenchAppDelegate.m */, DABCABB01CB80692000A7C39 /* MBXBenchViewController.h */, DABCABB11CB80692000A7C39 /* MBXBenchViewController.mm */, + 96C3CCF72076971D002588B5 /* MBXAnnotationViewBenchViewController.h */, + 96C3CCF82076971D002588B5 /* MBXAnnotationViewBenchViewController.mm */, DABCABBF1CB80717000A7C39 /* locations.cpp */, DABCABC01CB80717000A7C39 /* locations.hpp */, DABCABB61CB80692000A7C39 /* Assets.xcassets */, @@ -2652,6 +2656,7 @@ }; DA1DC9491CB6C1C2006E619F = { CreatedOnToolsVersion = 7.3; + DevelopmentTeam = GJZR2MEM28; LastSwiftMigration = 0820; }; DA2E88501CC036F400F24E7B = { @@ -2670,6 +2675,7 @@ }; DABCABA71CB80692000A7C39 = { CreatedOnToolsVersion = 7.3; + DevelopmentTeam = GJZR2MEM28; }; }; }; @@ -3173,7 +3179,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DABCABB21CB80692000A7C39 /* MBXBenchViewController.mm in Sources */, + 96C3CCF92076971D002588B5 /* MBXAnnotationViewBenchViewController.mm in Sources */, DABCABAF1CB80692000A7C39 /* MBXBenchAppDelegate.m in Sources */, DABCABC21CB8071D000A7C39 /* locations.cpp in Sources */, DABCABAC1CB80692000A7C39 /* main.m in Sources */, @@ -3596,7 +3602,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = GJZR2MEM28; INFOPLIST_FILE = "$(SRCROOT)/app/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL; @@ -3609,7 +3615,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = GJZR2MEM28; INFOPLIST_FILE = "$(SRCROOT)/app/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL; @@ -3845,6 +3851,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = GJZR2MEM28; INFOPLIST_FILE = "$(SRCROOT)/benchmark/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.bench; @@ -3856,6 +3863,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = GJZR2MEM28; INFOPLIST_FILE = "$(SRCROOT)/benchmark/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.bench; diff --git a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme index 1f8969faf7..ac1a5fb65d 100644 --- a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme +++ b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme @@ -42,7 +42,7 @@ + + - (void)validateDisplayLink { BOOL isVisible = self.superview && self.window; -- cgit v1.2.1