Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Migrate MGLCustomStyleLayerAdditions to style layer API #7250

Merged
merged 5 commits into from
Dec 7, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions include/mbgl/style/layers/custom_layer.hpp
Original file line number Diff line number Diff line change
@@ -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.
*/
7 changes: 1 addition & 6 deletions platform/darwin/src/MGLBackgroundStyleLayer.mm
Original file line number Diff line number Diff line change
@@ -33,19 +33,14 @@ - (instancetype)initWithIdentifier:(NSString *)identifier

#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"
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
"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);
7 changes: 1 addition & 6 deletions platform/darwin/src/MGLCircleStyleLayer.mm
Original file line number Diff line number Diff line change
@@ -73,19 +73,14 @@ - (NSPredicate *)predicate
}
#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"
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
"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);
7 changes: 1 addition & 6 deletions platform/darwin/src/MGLFillStyleLayer.mm
Original file line number Diff line number Diff line change
@@ -68,19 +68,14 @@ - (NSPredicate *)predicate
}
#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"
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
"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);
7 changes: 1 addition & 6 deletions platform/darwin/src/MGLLineStyleLayer.mm
Original file line number Diff line number Diff line change
@@ -80,19 +80,14 @@ - (NSPredicate *)predicate
}
#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"
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
"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);
34 changes: 34 additions & 0 deletions platform/darwin/src/MGLOpenGLStyleLayer.h
Original file line number Diff line number Diff line change
@@ -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
200 changes: 200 additions & 0 deletions platform/darwin/src/MGLOpenGLStyleLayer.mm
Original file line number Diff line number Diff line change
@@ -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 &params) {
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.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

causing its drawing handler to be run

This is a holdover from the former block-based API. I reworded this sentence in 1781302.

*/
- (void)setNeedsDisplay {
[self.mapView setNeedsGLDisplay];
}

@end
7 changes: 1 addition & 6 deletions platform/darwin/src/MGLRasterStyleLayer.mm
Original file line number Diff line number Diff line change
@@ -32,19 +32,14 @@ - (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)so
}
#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"
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
"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);
Loading