diff options
26 files changed, 430 insertions, 176 deletions
diff --git a/include/mbgl/style/layers/custom_layer.hpp b/include/mbgl/style/layers/custom_layer.hpp index 87bce06f41..1b62f82a25 100644 --- a/include/mbgl/style/layers/custom_layer.hpp +++ b/include/mbgl/style/layers/custom_layer.hpp @@ -7,8 +7,8 @@ namespace style { /** * Initialize any GL state needed by the custom layer. This method is called once, from the - * rendering thread, at a point when the GL context is active but before rendering for the - * first time. + * main thread, at a point when the GL context is active but before rendering for the first + * time. * * Resources that are acquired in this method must be released in the UninitializeFunction. */ @@ -40,7 +40,7 @@ using CustomLayerRenderFunction = void (*)(void* context, const CustomLayerRende /** * Destroy any GL state needed by the custom layer, and deallocate context, if necessary. This - * method is called once, from the rendering thread, at a point when the GL context is active. + * method is called once, from the main thread, at a point when the GL context is active. * * Note that it may be called even when the InitializeFunction has not been called. */ diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.mm b/platform/darwin/src/MGLBackgroundStyleLayer.mm index 253414852a..0ac25c39fe 100644 --- a/platform/darwin/src/MGLBackgroundStyleLayer.mm +++ b/platform/darwin/src/MGLBackgroundStyleLayer.mm @@ -33,7 +33,7 @@ #pragma mark - Adding to and removing from a map view -- (void)addToMapView:(MGLMapView *)mapView +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer { if (_pendingLayer == nullptr) { [NSException raise:@"MGLRedundantLayerException" @@ -41,11 +41,6 @@ "to the style more than once is invalid.", self, mapView.style]; } - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ if (otherLayer) { const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm index 91f91a7bcd..90026490a6 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.mm +++ b/platform/darwin/src/MGLCircleStyleLayer.mm @@ -73,7 +73,7 @@ namespace mbgl { } #pragma mark - Adding to and removing from a map view -- (void)addToMapView:(MGLMapView *)mapView +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer { if (_pendingLayer == nullptr) { [NSException raise:@"MGLRedundantLayerException" @@ -81,11 +81,6 @@ namespace mbgl { "to the style more than once is invalid.", self, mapView.style]; } - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ if (otherLayer) { const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); diff --git a/platform/darwin/src/MGLFillStyleLayer.mm b/platform/darwin/src/MGLFillStyleLayer.mm index 87a5144c6b..e2808ddc19 100644 --- a/platform/darwin/src/MGLFillStyleLayer.mm +++ b/platform/darwin/src/MGLFillStyleLayer.mm @@ -68,7 +68,7 @@ namespace mbgl { } #pragma mark - Adding to and removing from a map view -- (void)addToMapView:(MGLMapView *)mapView +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer { if (_pendingLayer == nullptr) { [NSException raise:@"MGLRedundantLayerException" @@ -76,11 +76,6 @@ namespace mbgl { "to the style more than once is invalid.", self, mapView.style]; } - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ if (otherLayer) { const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm index 55d739245f..2fc9d9e695 100644 --- a/platform/darwin/src/MGLLineStyleLayer.mm +++ b/platform/darwin/src/MGLLineStyleLayer.mm @@ -80,7 +80,7 @@ namespace mbgl { } #pragma mark - Adding to and removing from a map view -- (void)addToMapView:(MGLMapView *)mapView +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer { if (_pendingLayer == nullptr) { [NSException raise:@"MGLRedundantLayerException" @@ -88,11 +88,6 @@ namespace mbgl { "to the style more than once is invalid.", self, mapView.style]; } - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ if (otherLayer) { const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); diff --git a/platform/darwin/src/MGLOpenGLStyleLayer.h b/platform/darwin/src/MGLOpenGLStyleLayer.h new file mode 100644 index 0000000000..7cb6b147c2 --- /dev/null +++ b/platform/darwin/src/MGLOpenGLStyleLayer.h @@ -0,0 +1,34 @@ +#import <Foundation/Foundation.h> +#import <CoreLocation/CoreLocation.h> + +#import "MGLStyleValue.h" +#import "MGLStyleLayer.h" + +NS_ASSUME_NONNULL_BEGIN + +@class MGLMapView; + +typedef struct MGLStyleLayerDrawingContext { + CGSize size; + CLLocationCoordinate2D centerCoordinate; + double zoomLevel; + CLLocationDirection direction; + CGFloat pitch; + CGFloat perspectiveSkew; +} MGLStyleLayerDrawingContext; + +@interface MGLOpenGLStyleLayer : MGLStyleLayer + +@property (nonatomic, weak, readonly) MGLMapView *mapView; + +- (void)didMoveToMapView:(MGLMapView *)mapView; + +- (void)willMoveFromMapView:(MGLMapView *)mapView; + +- (void)drawInMapView:(MGLMapView *)mapView withContext:(MGLStyleLayerDrawingContext)context; + +- (void)setNeedsDisplay; + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLOpenGLStyleLayer.mm b/platform/darwin/src/MGLOpenGLStyleLayer.mm new file mode 100644 index 0000000000..2e819f0a2b --- /dev/null +++ b/platform/darwin/src/MGLOpenGLStyleLayer.mm @@ -0,0 +1,200 @@ +#import "MGLOpenGLStyleLayer.h" + +#import "MGLMapView_Private.h" +#import "MGLStyle_Private.h" + +#include <mbgl/style/layers/custom_layer.hpp> +#include <mbgl/math/wrap.hpp> + +/** + Runs the preparation handler block contained in the given context, which is + implicitly an instance of `MGLOpenGLStyleLayer`. + + @param context An `MGLOpenGLStyleLayer` instance that was provided as context + when creating an OpenGL style layer. + */ +void MGLPrepareCustomStyleLayer(void *context) { + MGLOpenGLStyleLayer *layer = (__bridge MGLOpenGLStyleLayer *)context; + [layer didMoveToMapView:layer.mapView]; +} + +/** + Runs the drawing handler block contained in the given context, which is + implicitly an instance of `MGLOpenGLStyleLayer`. + + @param context An `MGLOpenGLStyleLayer` instance that was provided as context + when creating an OpenGL style layer. + */ +void MGLDrawCustomStyleLayer(void *context, const mbgl::style::CustomLayerRenderParameters ¶ms) { + MGLOpenGLStyleLayer *layer = (__bridge MGLOpenGLStyleLayer *)context; + MGLStyleLayerDrawingContext drawingContext = { + .size = CGSizeMake(params.width, params.height), + .centerCoordinate = CLLocationCoordinate2DMake(params.latitude, params.longitude), + .zoomLevel = params.zoom, + .direction = mbgl::util::wrap(params.bearing, 0., 360.), + .pitch = params.pitch, + .perspectiveSkew = params.altitude, + }; + [layer drawInMapView:layer.mapView withContext:drawingContext]; +} + +/** + Runs the completion handler block contained in the given context, which is + implicitly an instance of `MGLOpenGLStyleLayer`. + + @param context An `MGLOpenGLStyleLayer` instance that was provided as context + when creating an OpenGL style layer. + */ +void MGLFinishCustomStyleLayer(void *context) { + MGLOpenGLStyleLayer *layer = (__bridge MGLOpenGLStyleLayer *)context; + [layer willMoveFromMapView:layer.mapView]; +} + +/** + An `MGLOpenGLStyleLayer` is a style layer that is rendered by OpenGL code in + Objective-C blocks or Swift closures that you specify. You may initialize a new + OpenGL style layer to add to an `MGLStyle` or obtain one from an `MGLMapView`’s + current style using the `-[MGLStyle layerWithIdentifier:]` method. + + @warning This API is undocumented and therefore unsupported. It may change at + any time without notice. + */ +@interface MGLOpenGLStyleLayer () + +@property (nonatomic) mbgl::style::CustomLayer *rawLayer; + +/** + The map view whose style currently contains the layer. + + If the layer is not currently part of any map view’s style, this property is + set to `nil`. + */ +@property (nonatomic, weak, readwrite) MGLMapView *mapView; + +@end + +@implementation MGLOpenGLStyleLayer { + std::unique_ptr<mbgl::style::CustomLayer> _pendingLayer; +} + +/** + Returns an OpenGL style layer object initialized with the given identifier. + + After initializing and configuring the style layer, add it to a map view’s + style using the `-[MGLStyle addLayer:]` or + `-[MGLStyle insertLayer:belowLayer:]` method. + + @param identifier A string that uniquely identifies the layer in the style to + which it is added. + @return An initialized OpenGL style layer. + */ +- (instancetype)initWithIdentifier:(NSString *)identifier { + if (self = [super initWithIdentifier:identifier]) { + auto layer = std::make_unique<mbgl::style::CustomLayer>(identifier.UTF8String, + MGLPrepareCustomStyleLayer, + MGLDrawCustomStyleLayer, + MGLFinishCustomStyleLayer, + (__bridge void *)self); + _pendingLayer = std::move(layer); + _rawLayer = _pendingLayer.get(); + } + return self; +} + +#pragma mark - Adding to and removing from a map view + +- (void)setMapView:(MGLMapView *)mapView { + if (_mapView && mapView) { + [NSException raise:@"MGLLayerReuseException" + format:@"%@ cannot be added to more than one MGLStyle at a time.", self]; + } + _mapView.style.openGLLayers[self.identifier] = nil; + _mapView = mapView; + _mapView.style.openGLLayers[self.identifier] = self; +} + +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer { + self.mapView = mapView; + if (otherLayer) { + const mbgl::optional<std::string> belowLayerId{ otherLayer.identifier.UTF8String }; + mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); + } else { + mapView.mbglMap->addLayer(std::move(_pendingLayer)); + } +} + +- (void)removeFromMapView:(MGLMapView *)mapView { + auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String); + self.mapView = nil; + if (!removedLayer) { + return; + } + _pendingLayer = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::CustomLayer> &>(removedLayer)); + _rawLayer = _pendingLayer.get(); +} + +/** + Called immediately after a layer is added to a map view’s style. + + This method is intended to be overridden in a subclass. You can use this method + to perform any setup work before the layer is used to draw a frame. For + example, you might use this method to compile an OpenGL shader. The default + implementation of this method does nothing. + + Any resource acquired in this method must be released in + `-willMoveFromMapView:`. + + @param mapView The map view to whose style the layer has been added. + */ +- (void)didMoveToMapView:(MGLMapView *)mapView { + +} + +/** + Called immediately before a layer is removed from a map view’s style. + + This method is intended to be overridden in a subclass. You can use this method + to perform any teardown work once the layer has drawn its last frame and is + about to be removed from the style. The default implementation of this method + does nothing. + + This method may be called even if `-didMoveToMapView:` has not been called. + + @param mapView The map view from whose style the layer is about to be removed. + */ +- (void)willMoveFromMapView:(MGLMapView *)mapView { + +} + +/** + Called each time the layer needs to draw a new frame in a map view. + + This method is intended to be overridden in a subclass. You can use this method + to draw the layer’s content. The default implementation of this method does + nothing. + + Your implementation should not make any assumptions about the OpenGL state, + other than that the current OpenGL context is active. It may make changes to + the OpenGL state. It is not required to reset values such as the depth mask, + stencil mask, or corresponding test flags to their original values. + + Be sure to draw your fragments with a <var>z</var> value of 1 to take advantage + of the opaque fragment culling, in case the style contains any opaque layers + above this layer. + + @param mapView The map view to which the layer draws. + @param context A context structure with information defining the frame to draw. + */ +- (void)drawInMapView:(MGLMapView *)mapView withContext:(MGLStyleLayerDrawingContext)context { + +} + +/** + Forces the map view associated with this style to redraw the receiving layer, + causing its drawing handler to be run. + */ +- (void)setNeedsDisplay { + [self.mapView setNeedsGLDisplay]; +} + +@end diff --git a/platform/darwin/src/MGLRasterStyleLayer.mm b/platform/darwin/src/MGLRasterStyleLayer.mm index 3b2c3bd83b..d54f027432 100644 --- a/platform/darwin/src/MGLRasterStyleLayer.mm +++ b/platform/darwin/src/MGLRasterStyleLayer.mm @@ -32,7 +32,7 @@ } #pragma mark - Adding to and removing from a map view -- (void)addToMapView:(MGLMapView *)mapView +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer { if (_pendingLayer == nullptr) { [NSException raise:@"MGLRedundantLayerException" @@ -40,11 +40,6 @@ "to the style more than once is invalid.", self, mapView.style]; } - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ if (otherLayer) { const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index 99d6ca89b6..36c8787bfb 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -1,4 +1,4 @@ -#import "MGLStyle.h" +#import "MGLStyle_Private.h" #import "MGLMapView_Private.h" #import "MGLStyleLayer.h" @@ -8,6 +8,7 @@ #import "MGLSymbolStyleLayer.h" #import "MGLRasterStyleLayer.h" #import "MGLBackgroundStyleLayer.h" +#import "MGLOpenGLStyleLayer.h" #import "MGLStyle_Private.h" #import "MGLStyleLayer_Private.h" @@ -28,6 +29,7 @@ #include <mbgl/style/layers/raster_layer.hpp> #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/background_layer.hpp> +#include <mbgl/style/layers/custom_layer.hpp> #include <mbgl/style/sources/geojson_source.hpp> #include <mbgl/style/sources/vector_source.hpp> #include <mbgl/style/sources/raster_source.hpp> @@ -43,6 +45,7 @@ @property (nonatomic, readwrite, weak) MGLMapView *mapView; @property (readonly, copy, nullable) NSURL *URL; +@property (nonatomic, readwrite, strong) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLOpenGLStyleLayer *) *openGLLayers; @end @@ -105,6 +108,7 @@ static NSURL *MGLStyleURL_emerald; - (instancetype)initWithMapView:(MGLMapView *)mapView { if (self = [super init]) { _mapView = mapView; + _openGLLayers = [NSMutableDictionary dictionary]; } return self; } @@ -268,7 +272,7 @@ static NSURL *MGLStyleURL_emerald; [NSException raise:NSRangeException format:@"Cannot insert style layer at out-of-bounds index %lu.", (unsigned long)index]; } else if (index == 0) { - [styleLayer addToMapView:self.mapView]; + [styleLayer addToMapView:self.mapView belowLayer:nil]; } else { MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(layers.size() - index)]; [styleLayer addToMapView:self.mapView belowLayer:sibling]; @@ -283,7 +287,8 @@ static NSURL *MGLStyleURL_emerald; format:@"Cannot remove style layer at out-of-bounds index %lu.", (unsigned long)index]; } auto layer = layers.at(layers.size() - 1 - index); - self.mapView.mbglMap->removeLayer(layer->getID()); + MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer]; + [styleLayer removeFromMapView:self.mapView]; } - (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)mbglLayer @@ -307,8 +312,15 @@ static NSURL *MGLStyleURL_emerald; } else if (auto circleLayer = mbglLayer->as<mbgl::style::CircleLayer>()) { MGLSource *source = [self sourceWithIdentifier:@(circleLayer->getSourceID().c_str())]; styleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:identifier source:source]; - } else if (mbglLayer->as<mbgl::style::BackgroundLayer>()) { + } else if (mbglLayer->is<mbgl::style::BackgroundLayer>()) { styleLayer = [[MGLBackgroundStyleLayer alloc] initWithIdentifier:identifier]; + } else if (auto customLayer = mbglLayer->as<mbgl::style::CustomLayer>()) { + styleLayer = self.openGLLayers[identifier]; + if (styleLayer) { + NSAssert(styleLayer.rawLayer == customLayer, @"%@ wraps a CustomLayer that differs from the one associated with the underlying style.", styleLayer); + return styleLayer; + } + styleLayer = [[MGLOpenGLStyleLayer alloc] initWithIdentifier:identifier]; } else { NSAssert(NO, @"Unrecognized layer type"); return nil; @@ -347,7 +359,7 @@ static NSURL *MGLStyleURL_emerald; layer]; } [self willChangeValueForKey:@"layers"]; - [layer addToMapView:self.mapView]; + [layer addToMapView:self.mapView belowLayer:nil]; [self didChangeValueForKey:@"layers"]; } @@ -410,7 +422,7 @@ static NSURL *MGLStyleURL_emerald; @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].", sibling]; } else if (index + 1 == layers.size()) { - [layer addToMapView:self.mapView]; + [layer addToMapView:self.mapView belowLayer:nil]; } else { MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index + 1)]; [layer addToMapView:self.mapView belowLayer:sibling]; diff --git a/platform/darwin/src/MGLStyleLayer.mm b/platform/darwin/src/MGLStyleLayer.mm index 6d9dabf25e..97f8f86b26 100644 --- a/platform/darwin/src/MGLStyleLayer.mm +++ b/platform/darwin/src/MGLStyleLayer.mm @@ -3,6 +3,12 @@ #include <mbgl/style/layer.hpp> +@interface MGLStyleLayer () + +@property (nonatomic) mbgl::style::Layer *rawLayer; + +@end + @implementation MGLStyleLayer - (instancetype)initWithIdentifier:(NSString *)identifier diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs index c89912c1ff..032fbfcc9b 100644 --- a/platform/darwin/src/MGLStyleLayer.mm.ejs +++ b/platform/darwin/src/MGLStyleLayer.mm.ejs @@ -110,7 +110,7 @@ namespace mbgl { <% } -%> #pragma mark - Adding to and removing from a map view -- (void)addToMapView:(MGLMapView *)mapView +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer { if (_pendingLayer == nullptr) { [NSException raise:@"MGLRedundantLayerException" @@ -118,11 +118,6 @@ namespace mbgl { "to the style more than once is invalid.", self, mapView.style]; } - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ if (otherLayer) { const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); diff --git a/platform/darwin/src/MGLStyleLayer_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h index e723c8cf1b..077af9a995 100644 --- a/platform/darwin/src/MGLStyleLayer_Private.h +++ b/platform/darwin/src/MGLStyleLayer_Private.h @@ -5,6 +5,8 @@ #include <mbgl/style/layer.hpp> +NS_ASSUME_NONNULL_BEGIN + /** Assert that the style layer is valid. @@ -40,13 +42,14 @@ @property (nonatomic) mbgl::style::Layer *rawLayer; /** - Adds the mbgl style layer that this object represents to the mbgl map. - + Adds the mbgl style layer that this object represents to the mbgl map below the + specified `otherLayer`. + Once a mbgl style layer is added, ownership of the object is transferred to the `mbgl::Map` and this object no longer has an active unique_ptr reference to the `mbgl::style::Layer`. */ -- (void)addToMapView:(MGLMapView *)mapView; +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(nullable MGLStyleLayer *)otherLayer; /** Removes the mbgl style layer that this object represents from the mbgl map. @@ -57,13 +60,6 @@ */ - (void)removeFromMapView:(MGLMapView *)mapView; -/** - Adds the mbgl style layer that this object represents to the mbgl map below the specified `otherLayer`. - - Once a mbgl style layer is added, ownership of the object is transferred to the - `mbgl::Map` and this object no longer has an active unique_ptr reference to the - `mbgl::style::Layer`. - */ -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer; - @end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyle_Private.h b/platform/darwin/src/MGLStyle_Private.h index b7c2fa4cdb..ee4a30c887 100644 --- a/platform/darwin/src/MGLStyle_Private.h +++ b/platform/darwin/src/MGLStyle_Private.h @@ -5,12 +5,21 @@ #import <mbgl/util/default_styles.hpp> #include <mbgl/mbgl.hpp> +NS_ASSUME_NONNULL_BEGIN + +@class MGLMapView; +@class MGLOpenGLStyleLayer; + @interface MGLStyle (Private) - (instancetype)initWithMapView:(MGLMapView *)mapView; @property (nonatomic, readonly, weak) MGLMapView *mapView; +@property (nonatomic, readonly, strong) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLOpenGLStyleLayer *) *openGLLayers; + - (void)setStyleClasses:(NS_ARRAY_OF(NSString *) *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration; @end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm index 9f4fb27e2b..2561152efc 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.mm +++ b/platform/darwin/src/MGLSymbolStyleLayer.mm @@ -127,7 +127,7 @@ namespace mbgl { } #pragma mark - Adding to and removing from a map view -- (void)addToMapView:(MGLMapView *)mapView +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer { if (_pendingLayer == nullptr) { [NSException raise:@"MGLRedundantLayerException" @@ -135,11 +135,6 @@ namespace mbgl { "to the style more than once is invalid.", self, mapView.style]; } - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ if (otherLayer) { const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 39ee311b79..c7da5e6af7 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -221,6 +221,10 @@ DA6408DC1DA4E7D300908C90 /* MGLVectorStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA6408DD1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */; }; DA6408DE1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */; }; + DA72620B1DEEE3480043BB89 /* MGLOpenGLStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA7262091DEEE3480043BB89 /* MGLOpenGLStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DA72620C1DEEE3480043BB89 /* MGLOpenGLStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA7262091DEEE3480043BB89 /* MGLOpenGLStyleLayer.h */; }; + DA72620D1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA72620A1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm */; }; + DA72620E1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA72620A1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm */; }; DA737EE11D056A4E005BDA16 /* MGLMapViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA737EE21D056A4E005BDA16 /* MGLMapViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA821D061CCC6D59007508D4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DA821D041CCC6D59007508D4 /* LaunchScreen.storyboard */; }; @@ -272,7 +276,6 @@ DA88483B1CBAFB8500AB86E3 /* MGLCalloutView.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848351CBAFB8500AB86E3 /* MGLCalloutView.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA88483C1CBAFB8500AB86E3 /* MGLMapView.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848361CBAFB8500AB86E3 /* MGLMapView.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA88483D1CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848371CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DA88483E1CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848381CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA88483F1CBAFB8500AB86E3 /* MGLUserLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848391CBAFB8500AB86E3 /* MGLUserLocation.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA88484F1CBAFB9800AB86E3 /* MGLAnnotationImage_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848401CBAFB9800AB86E3 /* MGLAnnotationImage_Private.h */; }; DA8848501CBAFB9800AB86E3 /* MGLAnnotationImage.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8848411CBAFB9800AB86E3 /* MGLAnnotationImage.m */; }; @@ -386,7 +389,6 @@ DABFB86E1CBE9A0F00D62B32 /* MGLCalloutView.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848351CBAFB8500AB86E3 /* MGLCalloutView.h */; settings = {ATTRIBUTES = (Public, ); }; }; DABFB86F1CBE9A0F00D62B32 /* MGLMapView.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848361CBAFB8500AB86E3 /* MGLMapView.h */; settings = {ATTRIBUTES = (Public, ); }; }; DABFB8701CBE9A0F00D62B32 /* MGLMapView+IBAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848371CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DABFB8711CBE9A0F00D62B32 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848381CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; DABFB8721CBE9A0F00D62B32 /* MGLUserLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848391CBAFB8500AB86E3 /* MGLUserLocation.h */; settings = {ATTRIBUTES = (Public, ); }; }; DABFB8731CBE9A9900D62B32 /* Mapbox.h in Headers */ = {isa = PBXBuildFile; fileRef = DA88485E1CBAFC2E00AB86E3 /* Mapbox.h */; settings = {ATTRIBUTES = (Public, ); }; }; DAC49C5C1CD02BC9009E1AA3 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DAC49C5F1CD02BC9009E1AA3 /* Localizable.stringsdict */; }; @@ -645,6 +647,8 @@ DA4A26961CB6E795000B7809 /* Mapbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Mapbox.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLVectorStyleLayer.h; sourceTree = "<group>"; }; DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLVectorStyleLayer.m; sourceTree = "<group>"; }; + DA7262091DEEE3480043BB89 /* MGLOpenGLStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLOpenGLStyleLayer.h; sourceTree = "<group>"; }; + DA72620A1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLOpenGLStyleLayer.mm; sourceTree = "<group>"; }; DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLMapViewDelegate.h; sourceTree = "<group>"; }; DA821D041CCC6D59007508D4 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; }; DA821D051CCC6D59007508D4 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; }; @@ -696,7 +700,6 @@ DA8848351CBAFB8500AB86E3 /* MGLCalloutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCalloutView.h; sourceTree = "<group>"; }; DA8848361CBAFB8500AB86E3 /* MGLMapView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLMapView.h; sourceTree = "<group>"; }; DA8848371CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLMapView+IBAdditions.h"; sourceTree = "<group>"; }; - DA8848381CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLMapView+MGLCustomStyleLayerAdditions.h"; sourceTree = "<group>"; }; DA8848391CBAFB8500AB86E3 /* MGLUserLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLUserLocation.h; sourceTree = "<group>"; }; DA8848401CBAFB9800AB86E3 /* MGLAnnotationImage_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationImage_Private.h; sourceTree = "<group>"; }; DA8848411CBAFB9800AB86E3 /* MGLAnnotationImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLAnnotationImage.m; sourceTree = "<group>"; }; @@ -860,6 +863,8 @@ 3538AA1C1D542239008EC33D /* MGLForegroundStyleLayer.m */, 353933F71D3FB79F003F57D7 /* MGLLineStyleLayer.h */, 35136D3E1D42273000C20EFD /* MGLLineStyleLayer.mm */, + DA7262091DEEE3480043BB89 /* MGLOpenGLStyleLayer.h */, + DA72620A1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm */, 353933FA1D3FB7C0003F57D7 /* MGLRasterStyleLayer.h */, 35136D411D42274500C20EFD /* MGLRasterStyleLayer.mm */, 35D13AB51D3D15E300AFB4E0 /* MGLStyleLayer.h */, @@ -1126,7 +1131,6 @@ DA8848361CBAFB8500AB86E3 /* MGLMapView.h */, DA17BE2F1CC4BAC300402C41 /* MGLMapView_Private.h */, DA8848371CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h */, - DA8848381CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h */, DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */, DA88484A1CBAFB9800AB86E3 /* MGLMapView.mm */, DA88487F1CBB033F00AB86E3 /* Fabric */, @@ -1442,7 +1446,6 @@ 7E016D841D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */, 400533011DB0862B0069F638 /* NSArray+MGLAdditions.h in Headers */, 4049C29D1DB6CD6C00B3F799 /* MGLPointCollection.h in Headers */, - DA88483E1CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */, 40CF6DBB1DAC3C6600A4D18B /* MGLShape_Private.h in Headers */, 4018B1CA1CDC288E00F666AF /* MGLAnnotationView.h in Headers */, 35E79F201D41266300957B9E /* MGLStyleLayer_Private.h in Headers */, @@ -1497,6 +1500,7 @@ DA8848851CBB033F00AB86E3 /* FABKitProtocol.h in Headers */, DA88481B1CBAFA6200AB86E3 /* MGLGeometry_Private.h in Headers */, 3510FFF91D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */, + DA72620B1DEEE3480043BB89 /* MGLOpenGLStyleLayer.h in Headers */, 404C26E71D89C55D000AA13D /* MGLTileSet_Private.h in Headers */, DA88485C1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h in Headers */, DA8848871CBB033F00AB86E3 /* Fabric.h in Headers */, @@ -1531,7 +1535,6 @@ 4049C29E1DB6CD6C00B3F799 /* MGLPointCollection.h in Headers */, 3566C7671D4A77BA008152BC /* MGLGeoJSONSource.h in Headers */, DA35A29F1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */, - DABFB8711CBE9A0F00D62B32 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */, 404C26E31D89B877000AA13D /* MGLTileSet.h in Headers */, DABFB8611CBE99E500D62B32 /* MGLMultiPoint.h in Headers */, 3510FFF11D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h in Headers */, @@ -1553,6 +1556,7 @@ DABFB8701CBE9A0F00D62B32 /* MGLMapView+IBAdditions.h in Headers */, 353AFA151D65AB17005A69F4 /* NSDate+MGLAdditions.h in Headers */, 3510FFFA1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */, + DA72620C1DEEE3480043BB89 /* MGLOpenGLStyleLayer.h in Headers */, 35CE61831D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */, DABFB8671CBE99E500D62B32 /* MGLPolygon.h in Headers */, 404C26E81D89C55D000AA13D /* MGLTileSet_Private.h in Headers */, @@ -1985,6 +1989,7 @@ DA88482A1CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm in Sources */, 4049C29F1DB6CD6C00B3F799 /* MGLPointCollection.mm in Sources */, 35136D3F1D42273000C20EFD /* MGLLineStyleLayer.mm in Sources */, + DA72620D1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm in Sources */, DA88481A1CBAFA6200AB86E3 /* MGLAccountManager.m in Sources */, 3510FFFB1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm in Sources */, DA8848271CBAFA6200AB86E3 /* MGLPolyline.mm in Sources */, @@ -2058,6 +2063,7 @@ DAA4E4211CBB730400178DFB /* MGLOfflineStorage.mm in Sources */, 4049C2A01DB6CD6C00B3F799 /* MGLPointCollection.mm in Sources */, 35136D401D42273000C20EFD /* MGLLineStyleLayer.mm in Sources */, + DA72620E1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm in Sources */, DAA4E42F1CBB730400178DFB /* MGLCompactCalloutView.m in Sources */, 3510FFFC1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm in Sources */, DAA4E4271CBB730400178DFB /* MGLTilePyramidOfflineRegion.mm in Sources */, diff --git a/platform/ios/src/MGLMapView+MGLCustomStyleLayerAdditions.h b/platform/ios/src/MGLMapView+MGLCustomStyleLayerAdditions.h deleted file mode 100644 index de4dc01f99..0000000000 --- a/platform/ios/src/MGLMapView+MGLCustomStyleLayerAdditions.h +++ /dev/null @@ -1,26 +0,0 @@ -#import "MGLMapView.h" - -NS_ASSUME_NONNULL_BEGIN - -typedef void (^MGLCustomStyleLayerPreparationHandler)(void); - -typedef void (^MGLCustomStyleLayerDrawingHandler)(CGSize size, - CLLocationCoordinate2D centerCoordinate, - double zoomLevel, - CLLocationDirection direction, - CGFloat pitch, - CGFloat perspectiveSkew); - -typedef void (^MGLCustomStyleLayerCompletionHandler)(void); - -@interface MGLMapView (MGLCustomStyleLayerAdditions) - -- (void)insertCustomStyleLayerWithIdentifier:(NSString *)identifier preparationHandler:(MGLCustomStyleLayerPreparationHandler)preparation drawingHandler:(MGLCustomStyleLayerDrawingHandler)drawing completionHandler:(MGLCustomStyleLayerCompletionHandler)completion belowStyleLayerWithIdentifier:(nullable NSString *)otherIdentifier; - -- (void)removeCustomStyleLayerWithIdentifier:(NSString *)identifier; - -- (void)setCustomStyleLayersNeedDisplay; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index e6fed8639c..3ee03182a8 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -378,6 +378,11 @@ public: self.styleURL = styleURL; } +- (mbgl::Map *)mbglMap +{ + return _mbglMap; +} + - (void)commonInit { MGLinitializeRunLoop(); @@ -5336,80 +5341,3 @@ private: } @end - -#pragma mark - MGLCustomStyleLayerAdditions methods - -class MGLCustomStyleLayerHandlers -{ -public: - MGLCustomStyleLayerHandlers(MGLCustomStyleLayerPreparationHandler p, - MGLCustomStyleLayerDrawingHandler d, - MGLCustomStyleLayerCompletionHandler f) - : prepare(p), draw(d), finish(f) {} - - MGLCustomStyleLayerPreparationHandler prepare; - MGLCustomStyleLayerDrawingHandler draw; - MGLCustomStyleLayerCompletionHandler finish; -}; - -void MGLPrepareCustomStyleLayer(void *context) -{ - MGLCustomStyleLayerPreparationHandler prepare = reinterpret_cast<MGLCustomStyleLayerHandlers *>(context)->prepare; - if (prepare) - { - prepare(); - } -} - -void MGLDrawCustomStyleLayer(void *context, const mbgl::style::CustomLayerRenderParameters ¶ms) -{ - CGSize size = CGSizeMake(params.width, params.height); - CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(params.latitude, params.longitude); - double zoomLevel = params.zoom; - CLLocationDirection direction = mbgl::util::wrap(params.bearing, 0., 360.); - CGFloat pitch = params.pitch; - CGFloat perspectiveSkew = params.altitude; - MGLCustomStyleLayerDrawingHandler draw = reinterpret_cast<MGLCustomStyleLayerHandlers *>(context)->draw; - if (draw) - { - draw(size, centerCoordinate, zoomLevel, direction, pitch, perspectiveSkew); - } -} - -void MGLFinishCustomStyleLayer(void *context) -{ - MGLCustomStyleLayerHandlers *handlers = reinterpret_cast<MGLCustomStyleLayerHandlers *>(context); - MGLCustomStyleLayerCompletionHandler finish = handlers->finish; - if (finish) - { - finish(); - } - delete handlers; -} - -@implementation MGLMapView (MGLCustomStyleLayerAdditions) - -- (void)insertCustomStyleLayerWithIdentifier:(NSString *)identifier preparationHandler:(void (^)())preparation drawingHandler:(MGLCustomStyleLayerDrawingHandler)drawing completionHandler:(void (^)())completion belowStyleLayerWithIdentifier:(nullable NSString *)otherIdentifier -{ - NSAssert(identifier, @"Style layer needs an identifier"); - MGLCustomStyleLayerHandlers *context = new MGLCustomStyleLayerHandlers(preparation, drawing, completion); - _mbglMap->addLayer(std::make_unique<mbgl::style::CustomLayer>(identifier.UTF8String, MGLPrepareCustomStyleLayer, - MGLDrawCustomStyleLayer, MGLFinishCustomStyleLayer, context), - otherIdentifier ? mbgl::optional<std::string>(otherIdentifier.UTF8String) : mbgl::optional<std::string>()); -} - -- (void)removeCustomStyleLayerWithIdentifier:(NSString *)identifier -{ - _mbglMap->removeLayer(identifier.UTF8String); -} - -- (void)setCustomStyleLayersNeedDisplay -{ - [self setNeedsGLDisplay]; -} - -- (mbgl::Map *)mbglMap { - return _mbglMap; -} - -@end diff --git a/platform/ios/src/Mapbox.h b/platform/ios/src/Mapbox.h index 7664695315..64fc2be0d4 100644 --- a/platform/ios/src/Mapbox.h +++ b/platform/ios/src/Mapbox.h @@ -19,7 +19,6 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[]; #import "MGLMapCamera.h" #import "MGLMapView.h" #import "MGLMapView+IBAdditions.h" -#import "MGLMapView+MGLCustomStyleLayerAdditions.h" #import "MGLMapViewDelegate.h" #import "MGLMultiPoint.h" #import "MGLOfflinePack.h" @@ -42,6 +41,7 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[]; #import "MGLRasterStyleLayer.h" #import "MGLCircleStyleLayer.h" #import "MGLBackgroundStyleLayer.h" +#import "MGLOpenGLStyleLayer.h" #import "MGLSource.h" #import "MGLVectorSource.h" #import "MGLGeoJSONSource.h" diff --git a/platform/macos/app/Base.lproj/MainMenu.xib b/platform/macos/app/Base.lproj/MainMenu.xib index cb9905d4a1..9faf1ba04b 100644 --- a/platform/macos/app/Base.lproj/MainMenu.xib +++ b/platform/macos/app/Base.lproj/MainMenu.xib @@ -537,6 +537,12 @@ <action selector="drawAnimatedAnnotation:" target="-1" id="CYM-WB-s97"/> </connections> </menuItem> + <menuItem title="Add Lime Green Layer" id="UWY-vl-t2m"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="insertCustomStyleLayer:" target="-1" id="LE5-lz-kx3"/> + </connections> + </menuItem> <menuItem title="Show All Annnotations" keyEquivalent="A" id="yMj-uM-8SN"> <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/> <connections> diff --git a/platform/macos/app/LimeGreenStyleLayer.h b/platform/macos/app/LimeGreenStyleLayer.h new file mode 100644 index 0000000000..35480963a4 --- /dev/null +++ b/platform/macos/app/LimeGreenStyleLayer.h @@ -0,0 +1,5 @@ +#import <Mapbox/Mapbox.h> + +@interface LimeGreenStyleLayer : MGLOpenGLStyleLayer + +@end diff --git a/platform/macos/app/LimeGreenStyleLayer.m b/platform/macos/app/LimeGreenStyleLayer.m new file mode 100644 index 0000000000..0d2e642db9 --- /dev/null +++ b/platform/macos/app/LimeGreenStyleLayer.m @@ -0,0 +1,60 @@ +#import "LimeGreenStyleLayer.h" + +#include <OpenGL/gl.h> +#include <OpenGL/glext.h> + +@implementation LimeGreenStyleLayer { + GLuint _program; + GLuint _vertexShader; + GLuint _fragmentShader; + GLuint _buffer; + GLuint _aPos; +} + +- (void)didMoveToMapView:(MGLMapView *)mapView { + static const GLchar *vertexShaderSource = "attribute vec2 a_pos; void main() { gl_Position = vec4(a_pos, 0, 1); }"; + static const GLchar *fragmentShaderSource = "void main() { gl_FragColor = vec4(0, 1, 0, 1); }"; + + _program = glCreateProgram(); + _vertexShader = glCreateShader(GL_VERTEX_SHADER); + _fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + + glShaderSource(_vertexShader, 1, &vertexShaderSource, NULL); + glCompileShader(_vertexShader); + glAttachShader(_program, _vertexShader); + glShaderSource(_fragmentShader, 1, &fragmentShaderSource, NULL); + glCompileShader(_fragmentShader); + glAttachShader(_program, _fragmentShader); + glLinkProgram(_program); + _aPos = glGetAttribLocation(_program, "a_pos"); + + GLfloat background[] = { -1,-1, 1,-1, -1,1, 1,1 }; + glGenBuffers(1, &_buffer); + glBindBuffer(GL_ARRAY_BUFFER, _buffer); + glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), background, GL_STATIC_DRAW); +} + +- (void)drawInMapView:(MGLMapView *)mapView withContext:(MGLStyleLayerDrawingContext)context { + glUseProgram(_program); + glBindBuffer(GL_ARRAY_BUFFER, _buffer); + glEnableVertexAttribArray(_aPos); + glVertexAttribPointer(_aPos, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glDisable(GL_STENCIL_TEST); + glDisable(GL_DEPTH_TEST); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} + +- (void)willMoveFromMapView:(MGLMapView *)mapView { + if (!_program) { + return; + } + + glDeleteBuffers(1, &_buffer); + glDetachShader(_program, _vertexShader); + glDetachShader(_program, _fragmentShader); + glDeleteShader(_vertexShader); + glDeleteShader(_fragmentShader); + glDeleteProgram(_program); +} + +@end diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 901a5ebb7f..6c36d00d73 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -1,6 +1,7 @@ #import "MapDocument.h" #import "AppDelegate.h" +#import "LimeGreenStyleLayer.h" #import "DroppedPinAnnotation.h" #import <Mapbox/Mapbox.h> @@ -604,6 +605,37 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio cos(angle) * 20); } +- (IBAction)insertCustomStyleLayer:(id)sender { + [self.undoManager registerUndoWithTarget:self handler:^(id _Nonnull target) { + [self removeCustomStyleLayer:sender]; + }]; + + if (!self.undoManager.isUndoing) { + [self.undoManager setActionName:@"Add Lime Green Layer"]; + } + + LimeGreenStyleLayer *layer = [[LimeGreenStyleLayer alloc] initWithIdentifier:@"mbx-custom"]; + MGLStyleLayer *houseNumberLayer = [self.mapView.style layerWithIdentifier:@"housenum-label"]; + if (houseNumberLayer) { + [self.mapView.style insertLayer:layer belowLayer:houseNumberLayer]; + } else { + [self.mapView.style addLayer:layer]; + } +} + +- (IBAction)removeCustomStyleLayer:(id)sender { + [self.undoManager registerUndoWithTarget:self handler:^(id _Nonnull target) { + [self insertCustomStyleLayer:sender]; + }]; + + if (!self.undoManager.isUndoing) { + [self.undoManager setActionName:@"Delete Lime Green Layer"]; + } + + MGLStyleLayer *layer = [self.mapView.style layerWithIdentifier:@"mbx-custom"]; + [self.mapView.style removeLayer:layer]; +} + #pragma mark Offline packs - (IBAction)addOfflinePack:(id)sender { @@ -892,6 +924,9 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio if (menuItem.action == @selector(drawAnimatedAnnotation:)) { return !_isShowingAnimatedAnnotation; } + if (menuItem.action == @selector(insertCustomStyleLayer:)) { + return ![self.mapView.style layerWithIdentifier:@"mbx-custom"]; + } if (menuItem.action == @selector(showAllAnnotations:) || menuItem.action == @selector(removeAllAnnotations:)) { return self.mapView.annotations.count > 0; } diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index bb81919292..20fa968a97 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -80,6 +80,8 @@ DA5589771D320C41006B7F64 /* wms.json in Resources */ = {isa = PBXBuildFile; fileRef = DA5589761D320C41006B7F64 /* wms.json */; }; DA6408D71DA4E5DA00908C90 /* MGLVectorStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6408D51DA4E5DA00908C90 /* MGLVectorStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA6408D81DA4E5DA00908C90 /* MGLVectorStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.m */; }; + DA7262071DEEDD460043BB89 /* MGLOpenGLStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA7262051DEEDD460043BB89 /* MGLOpenGLStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DA7262081DEEDD460043BB89 /* MGLOpenGLStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA7262061DEEDD460043BB89 /* MGLOpenGLStyleLayer.mm */; }; DA839E971CC2E3400062CAFB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E961CC2E3400062CAFB /* AppDelegate.m */; }; DA839E9A1CC2E3400062CAFB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E991CC2E3400062CAFB /* main.m */; }; DA839E9D1CC2E3400062CAFB /* MapDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E9C1CC2E3400062CAFB /* MapDocument.m */; }; @@ -117,6 +119,7 @@ DA8F25B21D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25A61D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h */; }; DA8F25B31D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25A71D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm */; }; DAA48EFD1D6A4731006A7E36 /* StyleLayerIconTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA48EFC1D6A4731006A7E36 /* StyleLayerIconTransformer.m */; }; + DAB2CCE51DF632ED001B2FE1 /* LimeGreenStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAB2CCE41DF632ED001B2FE1 /* LimeGreenStyleLayer.m */; }; DAC2ABC51CC6D343006D18C4 /* MGLAnnotationImage_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */; }; DACC22141CF3D3E200D220D9 /* MGLFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = DACC22121CF3D3E200D220D9 /* MGLFeature.h */; settings = {ATTRIBUTES = (Public, ); }; }; DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */ = {isa = PBXBuildFile; fileRef = DACC22131CF3D3E200D220D9 /* MGLFeature.mm */; }; @@ -316,6 +319,8 @@ DA5589761D320C41006B7F64 /* wms.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = wms.json; sourceTree = "<group>"; }; DA6408D51DA4E5DA00908C90 /* MGLVectorStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLVectorStyleLayer.h; sourceTree = "<group>"; }; DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLVectorStyleLayer.m; sourceTree = "<group>"; }; + DA7262051DEEDD460043BB89 /* MGLOpenGLStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLOpenGLStyleLayer.h; sourceTree = "<group>"; }; + DA7262061DEEDD460043BB89 /* MGLOpenGLStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLOpenGLStyleLayer.mm; sourceTree = "<group>"; }; DA839E921CC2E3400062CAFB /* Mapbox GL.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mapbox GL.app"; sourceTree = BUILT_PRODUCTS_DIR; }; DA839E951CC2E3400062CAFB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; DA839E961CC2E3400062CAFB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; @@ -361,6 +366,8 @@ DA8F25B71D51D2240010E6B5 /* MGLStyleLayer.mm.ejs */ = {isa = PBXFileReference; lastKnownFileType = text; path = MGLStyleLayer.mm.ejs; sourceTree = "<group>"; }; DAA48EFB1D6A4731006A7E36 /* StyleLayerIconTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleLayerIconTransformer.h; sourceTree = "<group>"; }; DAA48EFC1D6A4731006A7E36 /* StyleLayerIconTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StyleLayerIconTransformer.m; sourceTree = "<group>"; }; + DAB2CCE31DF632ED001B2FE1 /* LimeGreenStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LimeGreenStyleLayer.h; sourceTree = "<group>"; }; + DAB2CCE41DF632ED001B2FE1 /* LimeGreenStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LimeGreenStyleLayer.m; sourceTree = "<group>"; }; DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationImage_Private.h; sourceTree = "<group>"; }; DACC22121CF3D3E200D220D9 /* MGLFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature.h; sourceTree = "<group>"; }; DACC22131CF3D3E200D220D9 /* MGLFeature.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFeature.mm; sourceTree = "<group>"; }; @@ -500,6 +507,8 @@ 35602BFE1D3EA9B40050646F /* MGLForegroundStyleLayer.m */, DA8F25891D51CA540010E6B5 /* MGLLineStyleLayer.h */, DA8F258A1D51CA540010E6B5 /* MGLLineStyleLayer.mm */, + DA7262051DEEDD460043BB89 /* MGLOpenGLStyleLayer.h */, + DA7262061DEEDD460043BB89 /* MGLOpenGLStyleLayer.mm */, DA8F258D1D51CA600010E6B5 /* MGLRasterStyleLayer.h */, DA8F258E1D51CA600010E6B5 /* MGLRasterStyleLayer.mm */, 3538AA211D542685008EC33D /* MGLStyleLayer.h */, @@ -586,6 +595,8 @@ DA839E961CC2E3400062CAFB /* AppDelegate.m */, DAE6C2E31CC3050F00DB3429 /* DroppedPinAnnotation.h */, DAE6C2E41CC3050F00DB3429 /* DroppedPinAnnotation.m */, + DAB2CCE31DF632ED001B2FE1 /* LimeGreenStyleLayer.h */, + DAB2CCE41DF632ED001B2FE1 /* LimeGreenStyleLayer.m */, DAE6C2E51CC3050F00DB3429 /* LocationCoordinate2DTransformer.h */, DAE6C2E61CC3050F00DB3429 /* LocationCoordinate2DTransformer.m */, DA839E9B1CC2E3400062CAFB /* MapDocument.h */, @@ -952,6 +963,7 @@ 30E5781B1DAA857E0050F07E /* NSImage+MGLAdditions.h in Headers */, DAE6C3661CC31E0400DB3429 /* MGLShape.h in Headers */, DA551B831DB496AC0009AFAF /* MGLTileSet_Private.h in Headers */, + DA7262071DEEDD460043BB89 /* MGLOpenGLStyleLayer.h in Headers */, 352742811D4C243B00A1ECE6 /* MGLSource.h in Headers */, DAE6C3C21CC31F4500DB3429 /* Mapbox.h in Headers */, DAE6C3641CC31E0400DB3429 /* MGLPolygon.h in Headers */, @@ -1169,6 +1181,7 @@ DA839E9D1CC2E3400062CAFB /* MapDocument.m in Sources */, DAE6C2ED1CC3050F00DB3429 /* DroppedPinAnnotation.m in Sources */, DAE6C2EE1CC3050F00DB3429 /* LocationCoordinate2DTransformer.m in Sources */, + DAB2CCE51DF632ED001B2FE1 /* LimeGreenStyleLayer.m in Sources */, DAE6C2F11CC3050F00DB3429 /* TimeIntervalTransformer.m in Sources */, DA839E9A1CC2E3400062CAFB /* main.m in Sources */, DA839E971CC2E3400062CAFB /* AppDelegate.m in Sources */, @@ -1191,6 +1204,7 @@ DAE6C3B11CC31EF300DB3429 /* MGLAnnotationImage.m in Sources */, 3508EC651D749D39009B0EE4 /* NSExpression+MGLAdditions.mm in Sources */, DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */, + DA7262081DEEDD460043BB89 /* MGLOpenGLStyleLayer.mm in Sources */, 355BA4EE1D41633E00CCC6D5 /* NSColor+MGLAdditions.mm in Sources */, DAE6C3B31CC31EF300DB3429 /* MGLAttributionButton.m in Sources */, 35602BFB1D3EA99F0050646F /* MGLFillStyleLayer.mm in Sources */, diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 204efd4987..a2fe7acbda 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -796,7 +796,7 @@ public: _mbglMap->setSourceTileCacheSize(cacheSize); } -- (void)invalidate { +- (void)setNeedsGLDisplay { MGLAssertIsMainThread(); [self.layer setNeedsDisplay]; @@ -931,7 +931,7 @@ public: - (void)print:(__unused id)sender { _isPrinting = YES; - [self invalidate]; + [self setNeedsGLDisplay]; } - (void)printWithImage:(NSImage *)image { @@ -2623,7 +2623,7 @@ public: } void invalidate() override { - [nativeView invalidate]; + [nativeView setNeedsGLDisplay]; } void activate() override { diff --git a/platform/macos/src/MGLMapView_Private.h b/platform/macos/src/MGLMapView_Private.h index 2d9fc52a62..f0a61773a9 100644 --- a/platform/macos/src/MGLMapView_Private.h +++ b/platform/macos/src/MGLMapView_Private.h @@ -19,6 +19,9 @@ /// Center longitude set independently of the center latitude in an inspectable. @property (nonatomic) CLLocationDegrees pendingLongitude; +/// Asynchronously render a frame of the map. +- (void)setNeedsGLDisplay; + /// Synchronously render a frame of the map. - (void)renderSync; diff --git a/platform/macos/src/Mapbox.h b/platform/macos/src/Mapbox.h index 73b8624be0..df3f0b27a3 100644 --- a/platform/macos/src/Mapbox.h +++ b/platform/macos/src/Mapbox.h @@ -39,6 +39,7 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[]; #import "MGLRasterStyleLayer.h" #import "MGLCircleStyleLayer.h" #import "MGLBackgroundStyleLayer.h" +#import "MGLOpenGLStyleLayer.h" #import "MGLSource.h" #import "MGLVectorSource.h" #import "MGLGeoJSONSource.h" |