Merge pull request #1469 from mapbox/1435-android-gl-crash
Android GL Crash
This commit is contained in:
@@ -61,9 +61,11 @@ NativeMapView::NativeMapView(JNIEnv *env, jobject obj_)
|
||||
: mbgl::View(*this),
|
||||
fileCache(mbgl::android::cachePath + "/mbgl-cache.db"),
|
||||
fileSource(&fileCache),
|
||||
map(*this, fileSource, MapMode::Continuous, true) {
|
||||
map(*this, fileSource, MapMode::Continuous) {
|
||||
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::NativeMapView");
|
||||
|
||||
map.pause();
|
||||
|
||||
assert(env != nullptr);
|
||||
assert(obj_ != nullptr);
|
||||
|
||||
@@ -116,10 +118,14 @@ 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,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;
|
||||
@@ -74,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;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,7 @@ class Map : private util::noncopyable {
|
||||
|
||||
public:
|
||||
explicit Map(View&, FileSource&,
|
||||
MapMode mode = MapMode::Continuous,
|
||||
bool startPaused = false);
|
||||
MapMode mode = MapMode::Continuous);
|
||||
~Map();
|
||||
|
||||
// Pauses the render thread. The render thread will stop running but will not be terminated and will not lose state until resumed.
|
||||
@@ -137,6 +136,7 @@ public:
|
||||
private:
|
||||
const std::unique_ptr<MapData> data;
|
||||
const std::unique_ptr<util::Thread<MapContext>> context;
|
||||
bool paused = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ using UpdateType = uint32_t;
|
||||
|
||||
enum class Update : UpdateType {
|
||||
Nothing = 0,
|
||||
Debug = 1 << 1,
|
||||
DefaultTransitionDuration = 1 << 2,
|
||||
Classes = 1 << 3,
|
||||
Zoom = 1 << 4,
|
||||
|
||||
@@ -175,27 +175,27 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
- (void)setStyleURL:(NSURL *)styleURL
|
||||
{
|
||||
if (_isTargetingInterfaceBuilder) return;
|
||||
|
||||
|
||||
if ( ! styleURL)
|
||||
{
|
||||
styleURL = MGLURLForBundledStyleNamed([NSString stringWithFormat:@"%@-v%@",
|
||||
MGLDefaultStyleName.lowercaseString,
|
||||
MGLStyleVersion]);
|
||||
}
|
||||
|
||||
|
||||
if ( ! [styleURL scheme])
|
||||
{
|
||||
// Assume a relative path into the developer’s bundle.
|
||||
styleURL = [[NSBundle mainBundle] URLForResource:styleURL.path withExtension:nil];
|
||||
}
|
||||
|
||||
|
||||
_mbglMap->setStyleURL([[styleURL absoluteString] UTF8String]);
|
||||
}
|
||||
|
||||
- (BOOL)commonInit
|
||||
{
|
||||
_isTargetingInterfaceBuilder = NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent;
|
||||
|
||||
|
||||
// create context
|
||||
//
|
||||
_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
|
||||
@@ -210,7 +210,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
// setup accessibility
|
||||
//
|
||||
self.accessibilityLabel = @"Map";
|
||||
|
||||
|
||||
// metrics: initial setup
|
||||
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
|
||||
NSString *appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
|
||||
@@ -234,7 +234,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
[self insertSubview:_glView atIndex:0];
|
||||
|
||||
_glView.contentMode = UIViewContentModeCenter;
|
||||
|
||||
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.clipsToBounds = YES;
|
||||
|
||||
@@ -274,7 +274,10 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
_mbglFileSource = new mbgl::DefaultFileSource([MGLFileCache obtainSharedCacheWithObject:self]);
|
||||
|
||||
// Start paused on the IB canvas
|
||||
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous, _isTargetingInterfaceBuilder);
|
||||
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous);
|
||||
if (_isTargetingInterfaceBuilder) {
|
||||
_mbglMap->pause();
|
||||
}
|
||||
_mbglMap->resize(self.bounds.size.width, self.bounds.size.height, _glView.contentScaleFactor);
|
||||
|
||||
// Notify map object when network reachability status changes.
|
||||
@@ -447,7 +450,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
- (void)setDelegate:(id<MGLMapViewDelegate>)delegate
|
||||
{
|
||||
if (_delegate == delegate) return;
|
||||
|
||||
|
||||
_delegate = delegate;
|
||||
}
|
||||
|
||||
@@ -653,7 +656,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
|
||||
if ( ! _isTargetingInterfaceBuilder)
|
||||
{
|
||||
_mbglMap->update();
|
||||
@@ -778,7 +781,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
_mbglMap->moveBy(delta.x, delta.y);
|
||||
|
||||
self.centerPoint = CGPointMake(self.centerPoint.x + delta.x, self.centerPoint.y + delta.y);
|
||||
|
||||
|
||||
[self notifyMapChange:@(mbgl::MapChangeRegionDidChangeAnimated)];
|
||||
}
|
||||
else if (pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateCancelled)
|
||||
@@ -789,7 +792,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
// Not enough velocity to overcome friction
|
||||
velocity = CGPointZero;
|
||||
}
|
||||
|
||||
|
||||
CGFloat duration = UIScrollViewDecelerationRateNormal;
|
||||
if ( ! CGPointEqualToPoint(velocity, CGPointZero))
|
||||
{
|
||||
@@ -869,7 +872,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
velocity = 0;
|
||||
}
|
||||
CGFloat duration = velocity > 0 ? 1 : 0.25;
|
||||
|
||||
|
||||
CGFloat scale = self.scale * pinch.scale;
|
||||
CGFloat newScale = scale;
|
||||
if (velocity >= 0)
|
||||
@@ -880,22 +883,22 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
{
|
||||
newScale += scale / (velocity * duration) * 0.1;
|
||||
}
|
||||
|
||||
|
||||
if (newScale <= 0 || log2(newScale) < _mbglMap->getMinZoom())
|
||||
{
|
||||
velocity = 0;
|
||||
}
|
||||
|
||||
|
||||
if (velocity)
|
||||
{
|
||||
CGPoint pinchCenter = [pinch locationInView:pinch.view];
|
||||
_mbglMap->setScale(newScale, pinchCenter.x, pinchCenter.y, secondsAsDuration(duration));
|
||||
}
|
||||
|
||||
|
||||
_mbglMap->setGestureInProgress(false);
|
||||
|
||||
|
||||
[self unrotateIfNeededAnimated:YES];
|
||||
|
||||
|
||||
if (velocity)
|
||||
{
|
||||
self.animatingGesture = YES;
|
||||
@@ -951,37 +954,37 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
else if (rotate.state == UIGestureRecognizerStateEnded || rotate.state == UIGestureRecognizerStateCancelled)
|
||||
{
|
||||
CGFloat velocity = rotate.velocity;
|
||||
|
||||
|
||||
if (fabs(velocity) > 3)
|
||||
{
|
||||
CGFloat radians = self.angle + rotate.rotation;
|
||||
CGFloat duration = UIScrollViewDecelerationRateNormal;
|
||||
CGFloat newRadians = radians + velocity * duration * 0.1;
|
||||
CGFloat newDegrees = [MGLMapView radiansToDegrees:newRadians] * -1;
|
||||
|
||||
|
||||
_mbglMap->setBearing(newDegrees, secondsAsDuration(duration));
|
||||
|
||||
|
||||
_mbglMap->setGestureInProgress(false);
|
||||
|
||||
|
||||
self.animatingGesture = YES;
|
||||
|
||||
|
||||
__weak MGLMapView *weakSelf = self;
|
||||
|
||||
|
||||
[self animateWithDelay:duration animations:^
|
||||
{
|
||||
weakSelf.animatingGesture = NO;
|
||||
|
||||
|
||||
[weakSelf unrotateIfNeededAnimated:YES];
|
||||
|
||||
|
||||
[weakSelf notifyMapChange:@(mbgl::MapChangeRegionDidChangeAnimated)];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
_mbglMap->setGestureInProgress(false);
|
||||
|
||||
|
||||
[self unrotateIfNeededAnimated:YES];
|
||||
|
||||
|
||||
[self notifyMapChange:@(mbgl::MapChangeRegionDidChange)];
|
||||
}
|
||||
}
|
||||
@@ -1444,14 +1447,14 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
|
||||
// NOTE: does not disrupt tracking mode
|
||||
|
||||
CLLocationCoordinate2D center = CLLocationCoordinate2DMake((northEastCoordinate.latitude + southWestCoordinate.latitude) / 2, (northEastCoordinate.longitude + southWestCoordinate.longitude) / 2);
|
||||
|
||||
|
||||
CGFloat scale = _mbglMap->getScale();
|
||||
CGFloat scaleX = _mbglMap->getWidth() / (northEastCoordinate.longitude - southWestCoordinate.longitude);
|
||||
CGFloat scaleY = _mbglMap->getHeight() / (northEastCoordinate.latitude - southWestCoordinate.latitude);
|
||||
CGFloat minZoom = _mbglMap->getMinZoom();
|
||||
CGFloat maxZoom = _mbglMap->getMaxZoom();
|
||||
CGFloat zoomLevel = MAX(MIN(log(scale * MIN(scaleX, scaleY)) / log(2), maxZoom), minZoom);
|
||||
|
||||
|
||||
[self setCenterCoordinate:center zoomLevel:zoomLevel animated:animated];
|
||||
}
|
||||
|
||||
@@ -1723,7 +1726,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
{
|
||||
assert([annotation conformsToProtocol:@protocol(MGLAnnotation)]);
|
||||
|
||||
annotationIDsToRemove.push_back([[[self.annotationIDsByAnnotation objectForKey:annotation]
|
||||
annotationIDsToRemove.push_back([[[self.annotationIDsByAnnotation objectForKey:annotation]
|
||||
objectForKey:MGLAnnotationIDKey] unsignedIntValue]);
|
||||
[self.annotationIDsByAnnotation removeObjectForKey:annotation];
|
||||
|
||||
@@ -1759,7 +1762,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
if ( ! annotation) return;
|
||||
|
||||
if ( ! [self viewportBounds].contains(coordinateToLatLng(annotation.coordinate))) return;
|
||||
|
||||
|
||||
if (annotation == self.selectedAnnotation) return;
|
||||
|
||||
self.userTrackingMode = MGLUserTrackingModeNone;
|
||||
@@ -1878,22 +1881,22 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
- (void)setShowsUserLocation:(BOOL)showsUserLocation
|
||||
{
|
||||
if (showsUserLocation == _showsUserLocation) return;
|
||||
|
||||
|
||||
_showsUserLocation = showsUserLocation;
|
||||
|
||||
|
||||
if (showsUserLocation)
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(mapViewWillStartLocatingUser:)])
|
||||
{
|
||||
[self.delegate mapViewWillStartLocatingUser:self];
|
||||
}
|
||||
|
||||
|
||||
self.userLocationAnnotationView = [[MGLUserLocationAnnotationView alloc] initInMapView:self];
|
||||
self.userLocationAnnotationView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |
|
||||
UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
|
||||
|
||||
|
||||
self.locationManager = [CLLocationManager new];
|
||||
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
|
||||
// enable iOS 8+ location authorization API
|
||||
//
|
||||
@@ -1906,7 +1909,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
[self.locationManager requestWhenInUseAuthorization];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
self.locationManager.headingFilter = 5.0;
|
||||
self.locationManager.delegate = self;
|
||||
[self.locationManager startUpdatingLocation];
|
||||
@@ -1924,7 +1927,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
}
|
||||
|
||||
[self setUserTrackingMode:MGLUserTrackingModeNone animated:YES];
|
||||
|
||||
|
||||
[self.userLocationAnnotationView removeFromSuperview];
|
||||
self.userLocationAnnotationView = nil;
|
||||
}
|
||||
@@ -2089,7 +2092,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
CLLocationCoordinate2D actualNorthEast = [self convertPoint:CGPointMake(userLocationPoint.x + pixelRadius,
|
||||
userLocationPoint.y + pixelRadius)
|
||||
toCoordinateFromView:self];
|
||||
|
||||
|
||||
if (desiredNorthEast.latitude != actualNorthEast.latitude ||
|
||||
desiredNorthEast.longitude != actualNorthEast.longitude ||
|
||||
desiredSouthWest.latitude != actualSouthWest.latitude ||
|
||||
@@ -2492,17 +2495,17 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
- (void)prepareForInterfaceBuilder
|
||||
{
|
||||
[super prepareForInterfaceBuilder];
|
||||
|
||||
|
||||
self.layer.borderColor = [UIColor colorWithWhite:184/255. alpha:1].CGColor;
|
||||
self.layer.borderWidth = 1;
|
||||
|
||||
|
||||
if (self.accessToken)
|
||||
{
|
||||
self.layer.backgroundColor = [UIColor colorWithRed:59/255.
|
||||
green:178/255.
|
||||
blue:208/255.
|
||||
alpha:0.8].CGColor;
|
||||
|
||||
|
||||
UIImage *image = [[self class] resourceImageNamed:@"mapbox.png"];
|
||||
UIImageView *previewView = [[UIImageView alloc] initWithImage:image];
|
||||
previewView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
@@ -2529,7 +2532,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
UIView *diagnosticView = [[UIView alloc] init];
|
||||
diagnosticView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self addSubview:diagnosticView];
|
||||
|
||||
|
||||
// Headline
|
||||
UILabel *headlineLabel = [[UILabel alloc] init];
|
||||
headlineLabel.text = @"No Access Token";
|
||||
@@ -2540,7 +2543,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
[headlineLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
|
||||
forAxis:UILayoutConstraintAxisHorizontal];
|
||||
[diagnosticView addSubview:headlineLabel];
|
||||
|
||||
|
||||
// Explanation
|
||||
UILabel *explanationLabel = [[UILabel alloc] init];
|
||||
explanationLabel.text = @"To display a map here, you must provide a Mapbox access token. Get an access token from:";
|
||||
@@ -2550,7 +2553,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
[explanationLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
|
||||
forAxis:UILayoutConstraintAxisHorizontal];
|
||||
[diagnosticView addSubview:explanationLabel];
|
||||
|
||||
|
||||
// Link
|
||||
UIButton *linkButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||
[linkButton setTitle:MGLMapboxAccessTokenManagerURLDisplayString forState:UIControlStateNormal];
|
||||
@@ -2558,7 +2561,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
[linkButton setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
|
||||
forAxis:UILayoutConstraintAxisHorizontal];
|
||||
[diagnosticView addSubview:linkButton];
|
||||
|
||||
|
||||
// More explanation
|
||||
UILabel *explanationLabel2 = [[UILabel alloc] init];
|
||||
explanationLabel2.text = @"and enter it into the Access Token field in the Attributes inspector.";
|
||||
@@ -2568,7 +2571,7 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
|
||||
[explanationLabel2 setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
|
||||
forAxis:UILayoutConstraintAxisHorizontal];
|
||||
[diagnosticView addSubview:explanationLabel2];
|
||||
|
||||
|
||||
// Constraints
|
||||
NSDictionary *views = @{
|
||||
@"container": diagnosticView,
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
Map::Map(View& view, FileSource& fileSource, MapMode mode, bool startPaused)
|
||||
Map::Map(View& view, FileSource& fileSource, MapMode mode)
|
||||
: data(util::make_unique<MapData>(view, mode)),
|
||||
context(util::make_unique<util::Thread<MapContext>>("Map", util::ThreadPriority::Regular, view, fileSource, *data, startPaused))
|
||||
context(util::make_unique<util::Thread<MapContext>>("Map", util::ThreadPriority::Regular, view, fileSource, *data))
|
||||
{
|
||||
view.initialize(this);
|
||||
}
|
||||
@@ -23,13 +23,17 @@ Map::~Map() {
|
||||
void Map::pause() {
|
||||
assert(data->mode == MapMode::Continuous);
|
||||
|
||||
std::unique_lock<std::mutex> lockPause(data->mutexPause);
|
||||
context->invoke(&MapContext::pause);
|
||||
data->condPaused.wait(lockPause);
|
||||
if (!paused) {
|
||||
std::unique_lock<std::mutex> lockPause(data->mutexPause);
|
||||
context->invoke(&MapContext::pause);
|
||||
data->condPaused.wait(lockPause);
|
||||
paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Map::resume() {
|
||||
data->condResume.notify_all();
|
||||
paused = false;
|
||||
}
|
||||
|
||||
void Map::renderStill(StillImageCallback callback) {
|
||||
@@ -274,12 +278,12 @@ LatLngBounds Map::getBoundsForAnnotations(const std::vector<uint32_t>& annotatio
|
||||
|
||||
void Map::setDebug(bool value) {
|
||||
data->setDebug(value);
|
||||
update(Update::Debug);
|
||||
update();
|
||||
}
|
||||
|
||||
void Map::toggleDebug() {
|
||||
data->toggleDebug();
|
||||
update(Update::Debug);
|
||||
update();
|
||||
}
|
||||
|
||||
bool Map::getDebug() const {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
MapContext::MapContext(uv_loop_t* loop, View& view_, FileSource& fileSource, MapData& data_, bool startPaused)
|
||||
MapContext::MapContext(uv_loop_t* loop, View& view_, FileSource& fileSource, MapData& data_)
|
||||
: view(view_),
|
||||
data(data_),
|
||||
env(fileSource),
|
||||
@@ -40,20 +40,12 @@ MapContext::MapContext(uv_loop_t* loop, View& view_, FileSource& fileSource, Map
|
||||
glyphAtlas(util::make_unique<GlyphAtlas>(1024, 1024)),
|
||||
spriteAtlas(util::make_unique<SpriteAtlas>(512, 512)),
|
||||
lineAtlas(util::make_unique<LineAtlas>(512, 512)),
|
||||
texturePool(util::make_unique<TexturePool>()),
|
||||
painter(util::make_unique<Painter>(*spriteAtlas, *glyphAtlas, *lineAtlas))
|
||||
{
|
||||
texturePool(util::make_unique<TexturePool>()) {
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
|
||||
asyncUpdate->unref();
|
||||
|
||||
view.activate();
|
||||
|
||||
if (startPaused) {
|
||||
pause();
|
||||
}
|
||||
|
||||
painter->setup();
|
||||
}
|
||||
|
||||
MapContext::~MapContext() {
|
||||
@@ -173,11 +165,6 @@ void MapContext::update() {
|
||||
updated |= data.transform.updateTransitions(now);
|
||||
transformState = data.transform.currentState();
|
||||
|
||||
if (updated & static_cast<UpdateType>(Update::Debug)) {
|
||||
assert(painter);
|
||||
painter->setDebug(data.getDebug());
|
||||
}
|
||||
|
||||
if (style) {
|
||||
if (updated & static_cast<UpdateType>(Update::DefaultTransitionDuration)) {
|
||||
style->setDefaultTransitionDuration(data.getDefaultTransitionDuration());
|
||||
@@ -230,8 +217,13 @@ void MapContext::render() {
|
||||
env.performCleanup();
|
||||
|
||||
assert(style);
|
||||
assert(painter);
|
||||
|
||||
if (!painter) {
|
||||
painter = util::make_unique<Painter>(*spriteAtlas, *glyphAtlas, *lineAtlas);
|
||||
painter->setup();
|
||||
}
|
||||
|
||||
painter->setDebug(data.getDebug());
|
||||
painter->render(*style, transformState, data.getAnimationTime());
|
||||
|
||||
if (data.mode == MapMode::Still && callback && style->isLoaded() && resourceLoader->getSprite()->isLoaded()) {
|
||||
|
||||
@@ -35,7 +35,7 @@ struct LatLngBounds;
|
||||
|
||||
class MapContext : public ResourceLoader::Observer {
|
||||
public:
|
||||
MapContext(uv_loop_t*, View&, FileSource&, MapData&, bool startPaused);
|
||||
MapContext(uv_loop_t*, View&, FileSource&, MapData&);
|
||||
~MapContext();
|
||||
|
||||
void pause();
|
||||
|
||||
@@ -1,22 +1,59 @@
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/map/map_data.hpp>
|
||||
#include <mbgl/map/map_context.hpp>
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/platform/default/headless_view.hpp>
|
||||
#include <mbgl/platform/default/headless_display.hpp>
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
TEST(MapContext, DoubleStyleLoad) {
|
||||
util::RunLoop runLoop(uv_default_loop());
|
||||
std::shared_ptr<HeadlessDisplay> display = std::make_shared<HeadlessDisplay>();
|
||||
HeadlessView view(display, 512, 512, 1);
|
||||
DefaultFileSource fileSource(nullptr);
|
||||
MapData data(view, MapMode::Continuous);
|
||||
MapContext context(uv_default_loop(), view, fileSource, data, false);
|
||||
TEST(Map, PauseResume) {
|
||||
using namespace mbgl;
|
||||
|
||||
context.setStyleJSON("", "");
|
||||
context.setStyleJSON("", "");
|
||||
auto display = std::make_shared<mbgl::HeadlessDisplay>();
|
||||
HeadlessView view(display);
|
||||
DefaultFileSource fileSource(nullptr);
|
||||
|
||||
Map map(view, fileSource, MapMode::Continuous);
|
||||
|
||||
map.pause();
|
||||
map.resume();
|
||||
}
|
||||
|
||||
TEST(Map, DoublePause) {
|
||||
using namespace mbgl;
|
||||
|
||||
auto display = std::make_shared<mbgl::HeadlessDisplay>();
|
||||
HeadlessView view(display);
|
||||
DefaultFileSource fileSource(nullptr);
|
||||
|
||||
Map map(view, fileSource, MapMode::Continuous);
|
||||
|
||||
map.pause();
|
||||
map.pause();
|
||||
map.resume();
|
||||
}
|
||||
|
||||
TEST(Map, ResumeWithoutPause) {
|
||||
using namespace mbgl;
|
||||
|
||||
auto display = std::make_shared<mbgl::HeadlessDisplay>();
|
||||
HeadlessView view(display);
|
||||
DefaultFileSource fileSource(nullptr);
|
||||
|
||||
Map map(view, fileSource, MapMode::Continuous);
|
||||
|
||||
map.resume();
|
||||
}
|
||||
|
||||
TEST(Map, DestroyPaused) {
|
||||
using namespace mbgl;
|
||||
|
||||
auto display = std::make_shared<mbgl::HeadlessDisplay>();
|
||||
HeadlessView view(display);
|
||||
DefaultFileSource fileSource(nullptr);
|
||||
|
||||
Map map(view, fileSource, MapMode::Continuous);
|
||||
|
||||
map.pause();
|
||||
}
|
||||
|
||||
22
test/miscellaneous/map_context.cpp
Normal file
22
test/miscellaneous/map_context.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/map/map_data.hpp>
|
||||
#include <mbgl/map/map_context.hpp>
|
||||
#include <mbgl/platform/default/headless_view.hpp>
|
||||
#include <mbgl/platform/default/headless_display.hpp>
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
TEST(MapContext, DoubleStyleLoad) {
|
||||
util::RunLoop runLoop(uv_default_loop());
|
||||
std::shared_ptr<HeadlessDisplay> display = std::make_shared<HeadlessDisplay>();
|
||||
HeadlessView view(display, 512, 512, 1);
|
||||
DefaultFileSource fileSource(nullptr);
|
||||
MapData data(view, MapMode::Continuous);
|
||||
MapContext context(uv_default_loop(), view, fileSource, data);
|
||||
|
||||
context.setStyleJSON("", "");
|
||||
context.setStyleJSON("", "");
|
||||
}
|
||||
@@ -46,6 +46,7 @@
|
||||
'miscellaneous/enums.cpp',
|
||||
'miscellaneous/functions.cpp',
|
||||
'miscellaneous/map.cpp',
|
||||
'miscellaneous/map_context.cpp',
|
||||
'miscellaneous/mapbox.cpp',
|
||||
'miscellaneous/merge_lines.cpp',
|
||||
'miscellaneous/rotation_range.cpp',
|
||||
|
||||
Reference in New Issue
Block a user