From d28b6f37190dc1c9cbb1e3973f8a4534b507865c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Fri, 6 May 2016 08:47:18 -0700 Subject: [PATCH] [ios, osx] Avoid recomputing tile cache size on every redraw The tile cache size is only recomputed when an input changes. Fixes #4026. --- platform/ios/src/MGLMapView.mm | 40 ++++++++++++++++++++++++---------- platform/osx/src/MGLMapView.mm | 30 +++++++++++++++++-------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index eecc71ad2..8a3faa6a2 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -381,6 +381,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) // setup mbgl map mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource; _mbglMap = new mbgl::Map(*_mbglView, *mbglFileSource, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None); + [self validateTileCacheSize]; // start paused if in IB if (_isTargetingInterfaceBuilder || background) { @@ -646,15 +647,37 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) - (void)setFrame:(CGRect)frame { [super setFrame:frame]; - - [self setNeedsLayout]; + if ( ! CGRectEqualToRect(frame, self.frame)) + { + [self validateTileCacheSize]; + } } - (void)setBounds:(CGRect)bounds { [super setBounds:bounds]; + if ( ! CGRectEqualToRect(bounds, self.bounds)) + { + [self validateTileCacheSize]; + } +} - [self setNeedsLayout]; +- (void)validateTileCacheSize +{ + if ( ! _mbglMap) + { + return; + } + + CGFloat zoomFactor = self.maximumZoomLevel - self.minimumZoomLevel + 1; + CGFloat cpuFactor = [NSProcessInfo processInfo].processorCount; + CGFloat memoryFactor = (CGFloat)[NSProcessInfo processInfo].physicalMemory / 1000 / 1000 / 1000; + CGFloat sizeFactor = (CGRectGetWidth(self.bounds) / mbgl::util::tileSize) * + (CGRectGetHeight(self.bounds) / mbgl::util::tileSize); + + NSUInteger cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5; + + _mbglMap->setSourceTileCacheSize(cacheSize); } + (BOOL)requiresConstraintBasedLayout @@ -830,15 +853,6 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) { if ( ! self.dormant) { - CGFloat zoomFactor = _mbglMap->getMaxZoom() - _mbglMap->getMinZoom() + 1; - CGFloat cpuFactor = (CGFloat)[[NSProcessInfo processInfo] processorCount]; - CGFloat memoryFactor = (CGFloat)[[NSProcessInfo processInfo] physicalMemory] / 1000 / 1000 / 1000; - CGFloat sizeFactor = ((CGFloat)_mbglMap->getWidth() / mbgl::util::tileSize) * - ((CGFloat)_mbglMap->getHeight() / mbgl::util::tileSize); - - NSUInteger cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5; - - _mbglMap->setSourceTileCacheSize(cacheSize); _mbglMap->render(); [self updateUserLocationAnnotationView]; @@ -2175,6 +2189,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) - (void)setMinimumZoomLevel:(double)minimumZoomLevel { _mbglMap->setMinZoom(minimumZoomLevel); + [self validateTileCacheSize]; } - (double)minimumZoomLevel @@ -2185,6 +2200,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) - (void)setMaximumZoomLevel:(double)maximumZoomLevel { _mbglMap->setMaxZoom(maximumZoomLevel); + [self validateTileCacheSize]; } - (double)maximumZoomLevel diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm index 91410e98a..b4963535d 100644 --- a/platform/osx/src/MGLMapView.mm +++ b/platform/osx/src/MGLMapView.mm @@ -262,6 +262,7 @@ public: mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource; _mbglMap = new mbgl::Map(*_mbglView, *mbglFileSource, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None); + [self validateTileCacheSize]; // Install the OpenGL layer. Interface Builder’s synchronous drawing means // we can’t display a map, so don’t even bother to have a map layer. @@ -607,6 +608,9 @@ public: - (void)setFrame:(NSRect)frame { super.frame = frame; + if (!NSEqualRects(frame, self.frame)) { + [self validateTileCacheSize]; + } if (!_isTargetingInterfaceBuilder) { _mbglMap->update(mbgl::Update::Dimensions); } @@ -705,15 +709,6 @@ public: - (void)renderSync { if (!self.dormant) { - CGFloat zoomFactor = _mbglMap->getMaxZoom() - _mbglMap->getMinZoom() + 1; - CGFloat cpuFactor = (CGFloat)[NSProcessInfo processInfo].processorCount; - CGFloat memoryFactor = (CGFloat)[NSProcessInfo processInfo].physicalMemory / 1000 / 1000 / 1000; - CGFloat sizeFactor = ((CGFloat)_mbglMap->getWidth() / mbgl::util::tileSize) * ((CGFloat)_mbglMap->getHeight() / mbgl::util::tileSize); - - NSUInteger cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5; - - _mbglMap->setSourceTileCacheSize(cacheSize); - // Enable vertex buffer objects. mbgl::gl::InitializeExtensions([](const char *name) { static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); @@ -742,6 +737,21 @@ public: } } +- (void)validateTileCacheSize { + if (!_mbglMap) { + return; + } + + CGFloat zoomFactor = self.maximumZoomLevel - self.minimumZoomLevel + 1; + CGFloat cpuFactor = [NSProcessInfo processInfo].processorCount; + CGFloat memoryFactor = (CGFloat)[NSProcessInfo processInfo].physicalMemory / 1000 / 1000 / 1000; + CGFloat sizeFactor = (NSWidth(self.bounds) / mbgl::util::tileSize) * (NSHeight(self.bounds) / mbgl::util::tileSize); + + NSUInteger cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5; + + _mbglMap->setSourceTileCacheSize(cacheSize); +} + - (void)invalidate { MGLAssertIsMainThread(); @@ -947,11 +957,13 @@ public: - (void)setMinimumZoomLevel:(double)minimumZoomLevel { _mbglMap->setMinZoom(minimumZoomLevel); + [self validateTileCacheSize]; } - (void)setMaximumZoomLevel:(double)maximumZoomLevel { _mbglMap->setMaxZoom(maximumZoomLevel); + [self validateTileCacheSize]; } - (double)maximumZoomLevel {