diff --git a/CMakeLists.txt b/CMakeLists.txt index f99fb436d2d..944ea282370 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1000,6 +1000,8 @@ if(MLN_WITH_OPENGL) INCLUDE_FILES ${PROJECT_SOURCE_DIR}/include/mbgl/gfx/backend.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/layers/custom_layer.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/style/layers/custom_layer_render_parameters.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/style/layers/mtl/custom_layer_render_parameters.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/custom_layer_factory.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/gl/renderable_resource.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/gl/renderer_backend.hpp @@ -1072,6 +1074,7 @@ if(MLN_WITH_OPENGL) ${PROJECT_SOURCE_DIR}/src/mbgl/gl/fence.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/gl/fence.hpp ${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/custom_layer.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/custom_layer_render_parameters.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/layermanager/custom_layer_factory.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/custom_layer_impl.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/custom_layer_impl.hpp diff --git a/bazel/core.bzl b/bazel/core.bzl index 34e514003c9..9a756fa84ff 100644 --- a/bazel/core.bzl +++ b/bazel/core.bzl @@ -449,6 +449,7 @@ MLN_CORE_SOURCE = [ "src/mbgl/style/layers/circle_layer_impl.cpp", "src/mbgl/style/layers/circle_layer_impl.hpp", "src/mbgl/style/layers/custom_layer.cpp", + "src/mbgl/style/layers/custom_layer_render_parameters.cpp", "src/mbgl/style/layers/custom_layer_impl.cpp", "src/mbgl/style/layers/custom_layer_impl.hpp", "src/mbgl/style/layers/fill_extrusion_layer_impl.cpp", @@ -774,6 +775,7 @@ MLN_CORE_HEADERS = [ "include/mbgl/style/layer.hpp", "include/mbgl/style/layer_properties.hpp", "include/mbgl/style/layers/custom_layer.hpp", + "include/mbgl/style/layers/custom_layer_render_parameters.hpp", "include/mbgl/style/position.hpp", "include/mbgl/style/property_expression.hpp", "include/mbgl/style/property_value.hpp", @@ -1066,6 +1068,7 @@ MLN_DRAWABLES_MTL_SOURCE = [ "src/mbgl/shaders/mtl/symbol_icon.cpp", "src/mbgl/shaders/mtl/symbol_sdf.cpp", "src/mbgl/shaders/mtl/symbol_text_and_icon.cpp", + "src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp", ] MLN_DRAWABLES_MTL_HEADERS = [ @@ -1111,4 +1114,5 @@ MLN_DRAWABLES_MTL_HEADERS = [ "include/mbgl/shaders/mtl/symbol_icon.hpp", "include/mbgl/shaders/mtl/symbol_sdf.hpp", "include/mbgl/shaders/mtl/symbol_text_and_icon.hpp", + "include/mbgl/style/layers/mtl/custom_layer_render_parameters.hpp", ] diff --git a/include/mbgl/gfx/drawable_atlases_tweaker.hpp b/include/mbgl/gfx/drawable_atlases_tweaker.hpp index f13a30470c5..63e123845ba 100644 --- a/include/mbgl/gfx/drawable_atlases_tweaker.hpp +++ b/include/mbgl/gfx/drawable_atlases_tweaker.hpp @@ -13,8 +13,9 @@ namespace mbgl { class TileAtlasTextures; using TileAtlasTexturesPtr = std::shared_ptr; -namespace gfx { +class PaintParameters; +namespace gfx { class Drawable; /** diff --git a/include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp b/include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp index 1a6ca0bdd93..0e6341e4460 100644 --- a/include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp +++ b/include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp @@ -8,6 +8,8 @@ namespace mbgl { +class PaintParameters; + namespace gfx { class Drawable; diff --git a/include/mbgl/gl/drawable_gl.hpp b/include/mbgl/gl/drawable_gl.hpp index f7184a88b25..7da9372ba8a 100644 --- a/include/mbgl/gl/drawable_gl.hpp +++ b/include/mbgl/gl/drawable_gl.hpp @@ -13,6 +13,7 @@ namespace mbgl { template class Segment; +class PaintParameters; namespace gfx { diff --git a/include/mbgl/gl/layer_group_gl.hpp b/include/mbgl/gl/layer_group_gl.hpp index 6b3a83fa616..dc8173f193a 100644 --- a/include/mbgl/gl/layer_group_gl.hpp +++ b/include/mbgl/gl/layer_group_gl.hpp @@ -3,6 +3,9 @@ #include namespace mbgl { + +class PaintParameters; + namespace gl { /** diff --git a/include/mbgl/mtl/drawable.hpp b/include/mbgl/mtl/drawable.hpp index c4bb7251934..ddeaccb1486 100644 --- a/include/mbgl/mtl/drawable.hpp +++ b/include/mbgl/mtl/drawable.hpp @@ -11,6 +11,7 @@ namespace mbgl { template class Segment; +class PaintParameters; namespace gfx { diff --git a/include/mbgl/mtl/layer_group.hpp b/include/mbgl/mtl/layer_group.hpp index 586b8096f18..aba0a0d4293 100644 --- a/include/mbgl/mtl/layer_group.hpp +++ b/include/mbgl/mtl/layer_group.hpp @@ -3,6 +3,9 @@ #include namespace mbgl { + +class PaintParameters; + namespace mtl { /** diff --git a/include/mbgl/mtl/tile_layer_group.hpp b/include/mbgl/mtl/tile_layer_group.hpp index 58b15d4e3f1..069906168c0 100644 --- a/include/mbgl/mtl/tile_layer_group.hpp +++ b/include/mbgl/mtl/tile_layer_group.hpp @@ -8,6 +8,9 @@ #include namespace mbgl { + +class PaintParameters; + namespace mtl { /** diff --git a/include/mbgl/style/layers/custom_layer.hpp b/include/mbgl/style/layers/custom_layer.hpp index c957b6dc5d5..2ef7aa39c9c 100644 --- a/include/mbgl/style/layers/custom_layer.hpp +++ b/include/mbgl/style/layers/custom_layer.hpp @@ -1,33 +1,20 @@ #pragma once #include +#include #include +#include namespace mbgl { -namespace style { -/** - * Parameters that define the current camera position for a - * `CustomLayerHost::render()` function. - */ -struct CustomLayerRenderParameters { - double width; - double height; - double latitude; - double longitude; - double zoom; - double bearing; - double pitch; - double fieldOfView; - std::array projectionMatrix; -}; +namespace style { class CustomLayerHost { public: virtual ~CustomLayerHost() = default; /** - * Initialize any GL state needed by the custom layer. This method is called + * Initialize any GL/Metal state needed by the custom layer. This method is called * once, from the main thread, at a point when the GL context is active but * before rendering for the first time. * @@ -38,7 +25,7 @@ class CustomLayerHost { /** * Render the layer. This method is called once per frame. The - * implementation should not make any assumptions about the GL state (other + * implementation should not make any assumptions about the GL/Metal state (other * than that the correct context is active). It may make changes to the * state, and is not required to reset values such as the depth mask, * stencil mask, and corresponding test flags to their original values. Make @@ -46,10 +33,10 @@ class CustomLayerHost { * advantage of the opaque fragment culling in case there are opaque layers * above your custom layer. */ - virtual void render(const CustomLayerRenderParameters&) = 0; + virtual void render(const mbgl::style::CustomLayerRenderParameters&) = 0; /** - * Called when the system has destroyed the underlying GL context. The + * Called when the system has destroyed the underlying GL/Metal context. The * `deinitialize` function will not be called in this case, however * `initialize` will be called instead to prepare for a new render. * @@ -57,9 +44,9 @@ class CustomLayerHost { virtual void contextLost() = 0; /** - * Destroy any GL state needed by the custom layer, and deallocate context, + * Destroy any GL/Metal state needed by the custom layer, and deallocate context, * if necessary. This method is called once, from the main thread, at a - * point when the GL context is active. + * point when the GL/Metal context is active. * * Note that it may be called even when the `initialize` function has not * been called. diff --git a/include/mbgl/style/layers/custom_layer_render_parameters.hpp b/include/mbgl/style/layers/custom_layer_render_parameters.hpp new file mode 100644 index 00000000000..54eb7d90d41 --- /dev/null +++ b/include/mbgl/style/layers/custom_layer_render_parameters.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +namespace mbgl { + +class PaintParameters; + +namespace style { + +/** + * Parameters that define the current camera position for a + * `CustomLayerHost::render()` function. + */ +struct CustomLayerRenderParameters { + double width; + double height; + double latitude; + double longitude; + double zoom; + double bearing; + double pitch; + double fieldOfView; + std::array projectionMatrix; + + CustomLayerRenderParameters(const PaintParameters&); +}; + +} // namespace style +} // namespace mbgl diff --git a/include/mbgl/style/layers/mtl/custom_layer_render_parameters.hpp b/include/mbgl/style/layers/mtl/custom_layer_render_parameters.hpp new file mode 100644 index 00000000000..1b6e094b7d1 --- /dev/null +++ b/include/mbgl/style/layers/mtl/custom_layer_render_parameters.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include +#include +#include + +#include + +namespace mbgl { + +class PaintParameters; + +namespace style { + +namespace mtl { + +/** + * Metal subclass of CustomLayerRenderParameters + */ +struct CustomLayerRenderParameters : mbgl::style::CustomLayerRenderParameters { + mbgl::mtl::MTLRenderCommandEncoderPtr encoder; + + CustomLayerRenderParameters(const PaintParameters&); +}; + +} // namespace mtl +} // namespace style +} // namespace mbgl diff --git a/platform/BUILD.bazel b/platform/BUILD.bazel index 4052b441e27..b381a1f62a4 100644 --- a/platform/BUILD.bazel +++ b/platform/BUILD.bazel @@ -12,11 +12,6 @@ objc_library( "//platform/ios:ios_public_hdrs", "//platform/ios:ios_sdk_hdrs", ] + select({ - "//:metal_renderer": [], - "//conditions:default": [ - "//platform/darwin:darwin_objcpp_opengl_srcs", - ], - }) + select({ "//:legacy_renderer": [], "//conditions:default": [ "//platform/darwin:darwin_objcpp_custom_drawable_srcs", @@ -193,13 +188,9 @@ objc_library( name = "iosapp", srcs = [ "//platform/ios:ios_app_srcs", - ] + select({ - "//:metal_renderer": [], - "//conditions:default": [ - "//platform/darwin:app/LimeGreenStyleLayer.h", - "//platform/darwin:app/LimeGreenStyleLayer.m", - ], - }), + "//platform/darwin:app/CustomStyleLayerExample.h", + "//platform/darwin:app/CustomStyleLayerExample.m", + ], defines = ["GLES_SILENCE_DEPRECATION"], includes = [ "darwin/app", @@ -211,7 +202,7 @@ objc_library( "MetalKit", ], "//conditions:default": [ - "GLKit", # needed for LimeGreenStyleLayer + "GLKit", # needed for CustomStyleLayerExample ], }), visibility = ["//visibility:public"], diff --git a/platform/android/src/example_custom_layer.cpp b/platform/android/src/example_custom_layer.cpp index caa44c9831b..535c7c39b87 100644 --- a/platform/android/src/example_custom_layer.cpp +++ b/platform/android/src/example_custom_layer.cpp @@ -3,6 +3,7 @@ #include #include #include +#include // DEBUGGING diff --git a/platform/darwin/BUILD.bazel b/platform/darwin/BUILD.bazel index 5fa5997bf65..331fa679133 100644 --- a/platform/darwin/BUILD.bazel +++ b/platform/darwin/BUILD.bazel @@ -10,7 +10,6 @@ load( "MLN_DARWIN_OBJC_HEADERS", "MLN_DARWIN_PRIVATE_HEADERS", "MLN_DARWIN_PUBLIC_OBJCPP_CUSTOM_DRAWABLE_SOURCE", - "MLN_DARWIN_PUBLIC_OBJCPP_OPENGL_SOURCE", "MLN_DARWIN_PUBLIC_OBJCPP_SOURCE", "MLN_DARWIN_PUBLIC_OBJC_SOURCE", "MLN_GENERATED_DARWIN_STYLE_HEADERS", @@ -33,10 +32,7 @@ filegroup( filegroup( name = "darwin_objcpp_hdrs", - srcs = MLN_DARWIN_OBJCPP_HEADERS + select({ - "//:metal_renderer": [], - "//conditions:default": ["src/MLNOpenGLStyleLayer.h"], - }), + srcs = MLN_DARWIN_OBJCPP_HEADERS, visibility = ["//visibility:public"], ) @@ -46,12 +42,6 @@ filegroup( visibility = ["//visibility:public"], ) -filegroup( - name = "darwin_objcpp_opengl_srcs", - srcs = MLN_DARWIN_PUBLIC_OBJCPP_OPENGL_SOURCE, - visibility = ["//visibility:public"], -) - filegroup( name = "darwin_objcpp_custom_drawable_srcs", srcs = MLN_DARWIN_PUBLIC_OBJCPP_CUSTOM_DRAWABLE_SOURCE, @@ -319,14 +309,13 @@ exports_files( [ "test/amsterdam.geojson", "test/MLNSDKTestHelpers.swift", - "app/LimeGreenStyleLayer.h", - "app/LimeGreenStyleLayer.m", + "app/CustomStyleLayerExample.h", + "app/CustomStyleLayerExample.m", "app/ExampleCustomDrawableStyleLayer.h", "app/ExampleCustomDrawableStyleLayer.mm", "include/mbgl/util/image+MLNAdditions.hpp", ] + MLN_DARWIN_PUBLIC_OBJC_SOURCE + MLN_DARWIN_PUBLIC_OBJCPP_SOURCE + - MLN_DARWIN_PUBLIC_OBJCPP_OPENGL_SOURCE + MLN_DARWIN_PUBLIC_OBJCPP_CUSTOM_DRAWABLE_SOURCE + MLN_DARWIN_PRIVATE_HEADERS + MLN_DARWIN_OBJC_HEADERS + @@ -359,11 +348,6 @@ js_library( ":generated_style_hdrs", ":generated_style_srcs", ] + select({ - "//:metal_renderer": [], - "//conditions:default": [ - ":darwin_objcpp_opengl_srcs", - ], - }) + select({ "//:legacy_renderer": [], "//conditions:default": [ ":darwin_objcpp_custom_drawable_srcs", diff --git a/platform/darwin/app/CustomStyleLayerExample.h b/platform/darwin/app/CustomStyleLayerExample.h new file mode 100644 index 00000000000..69736db6533 --- /dev/null +++ b/platform/darwin/app/CustomStyleLayerExample.h @@ -0,0 +1,5 @@ +#import "Mapbox.h" + +@interface CustomStyleLayerExample : MLNCustomStyleLayer + +@end diff --git a/platform/darwin/app/CustomStyleLayerExample.m b/platform/darwin/app/CustomStyleLayerExample.m new file mode 100644 index 00000000000..c2f69589d92 --- /dev/null +++ b/platform/darwin/app/CustomStyleLayerExample.m @@ -0,0 +1,188 @@ +#if !MLN_RENDER_BACKEND_METAL + +/* OPENGL Custom Layer example implementation */ +#import "CustomStyleLayerExample.h" +#import + +@implementation CustomStyleLayerExample { + GLuint _program; + GLuint _vertexShader; + GLuint _fragmentShader; + GLuint _buffer; + GLuint _aPos; +} + +- (void)didMoveToMapView:(MLNMapView *)mapView { + static const GLchar *vertexShaderSource = "#version 300 es\nlayout (location = 0) in vec2 a_pos; void main() { gl_Position = vec4(a_pos, 1, 1); }"; + static const GLchar *fragmentShaderSource = "#version 300 es\nout highp vec4 fragColor; void main() { fragColor = vec4(0, 0.5, 0, 0.5); }"; + + _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 triangle[] = { 0, 0.5, 0.5, -0.5, -0.5, -0.5 }; + glGenBuffers(1, &_buffer); + glBindBuffer(GL_ARRAY_BUFFER, _buffer); + glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), triangle, GL_STATIC_DRAW); +} + +- (void)drawInMapView:(MLNMapView *)mapView withContext:(MLNStyleLayerDrawingContext)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, 3); +} + +- (void)willMoveFromMapView:(MLNMapView *)mapView { + if (!_program) { + return; + } + + glDeleteBuffers(1, &_buffer); + glDetachShader(_program, _vertexShader); + glDetachShader(_program, _fragmentShader); + glDeleteShader(_vertexShader); + glDeleteShader(_fragmentShader); + glDeleteProgram(_program); +} + +@end + +#else // MLN_RENDER_BACKEND_METAL: + +/* Metal Custom Layer example implementation */ +#import "CustomStyleLayerExample.h" + +@implementation CustomStyleLayerExample { + // The render pipeline state + id _pipelineState; + id _depthStencilStateWithoutStencil; +} + +- (void)didMoveToMapView:(MLNMapView *)mapView { + MLNBackendResource resource = [mapView backendResource]; + + NSString *shaderSource = @ +" #include \n" +" using namespace metal;\n" +" typedef struct\n" +" {\n" +" vector_float2 position;\n" +" vector_float4 color;\n" +" } Vertex;\n" +" struct RasterizerData\n" +" {\n" +" float4 position [[position]];\n" +" float4 color;\n" +" };\n" +" vertex RasterizerData\n" +" vertexShader(uint vertexID [[vertex_id]],\n" +" constant Vertex *vertices [[buffer(0)]],\n" +" constant vector_uint2 *viewportSizePointer [[buffer(1)]])\n" +" {\n" +" RasterizerData out;\n" +" float2 pixelSpacePosition = vertices[vertexID].position.xy;\n" +" vector_float2 viewportSize = vector_float2(*viewportSizePointer);\n" +" out.position = vector_float4(0.0, 0.0, 0.0, 1.0);\n" +" out.position.xy = pixelSpacePosition / (viewportSize / 2.0);\n" +" out.color = vertices[vertexID].color;\n" +" return out;\n" +" }\n" +" fragment float4 fragmentShader(RasterizerData in [[stage_in]])\n" +" {\n" +" return in.color;\n" +" }\n"; + + + NSError *error = nil; + id _device = resource.device; + id library = [_device newLibraryWithSource:shaderSource options:nil error:&error]; + NSAssert(library, @"Error compiling shaders: %@", error); + id vertexFunction = [library newFunctionWithName:@"vertexShader"]; + id fragmentFunction = [library newFunctionWithName:@"fragmentShader"]; + + // Configure a pipeline descriptor that is used to create a pipeline state. + MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; + pipelineStateDescriptor.label = @"Simple Pipeline"; + pipelineStateDescriptor.vertexFunction = vertexFunction; + pipelineStateDescriptor.fragmentFunction = fragmentFunction; + pipelineStateDescriptor.colorAttachments[0].pixelFormat = resource.mtkView.colorPixelFormat; + pipelineStateDescriptor.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float_Stencil8; + pipelineStateDescriptor.stencilAttachmentPixelFormat = MTLPixelFormatDepth32Float_Stencil8; + + _pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor + error:&error]; + NSAssert(_pipelineState, @"Failed to create pipeline state: %@", error); + + // Notice that we don't configure the stencilTest property, leaving stencil testing disabled + MTLDepthStencilDescriptor *depthStencilDescriptor = [[MTLDepthStencilDescriptor alloc] init]; + depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways; // Or another value as needed + depthStencilDescriptor.depthWriteEnabled = NO; + + _depthStencilStateWithoutStencil = [_device newDepthStencilStateWithDescriptor:depthStencilDescriptor]; + +} + +- (void)drawInMapView:(MLNMapView *)mapView withContext:(MLNStyleLayerDrawingContext)context { + // Use the supplied render command encoder to encode commands + id renderEncoder = self.renderEncoder; + if(renderEncoder != nil) + { + MLNBackendResource resource = [mapView backendResource]; + + vector_uint2 _viewportSize; + _viewportSize.x = resource.mtkView.drawableSize.width; + _viewportSize.y = resource.mtkView.drawableSize.height; + + typedef struct + { + vector_float2 position; + vector_float4 color; + } Vertex; + + static const Vertex triangleVertices[] = + { + // 2D positions, RGBA colors + { { 250, -250 }, { 1, 0, 0, 1 } }, + { { -250, -250 }, { 0, 1, 0, 1 } }, + { { 0, 250 }, { 0, 0, 1, 1 } }, + }; + + [renderEncoder setRenderPipelineState:_pipelineState]; + [renderEncoder setDepthStencilState:_depthStencilStateWithoutStencil]; + + // Pass in the parameter data. + [renderEncoder setVertexBytes:triangleVertices + length:sizeof(triangleVertices) + atIndex:0]; + + [renderEncoder setVertexBytes:&_viewportSize + length:sizeof(_viewportSize) + atIndex:1]; + + // Draw the triangle. + [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle + vertexStart:0 + vertexCount:3]; + } +} + +- (void)willMoveFromMapView:(MLNMapView *)mapView { + // Clean up +} + +@end + +#endif diff --git a/platform/darwin/app/LimeGreenStyleLayer.h b/platform/darwin/app/LimeGreenStyleLayer.h deleted file mode 100644 index 10d359422d7..00000000000 --- a/platform/darwin/app/LimeGreenStyleLayer.h +++ /dev/null @@ -1,5 +0,0 @@ -#import "Mapbox.h" - -@interface LimeGreenStyleLayer : MLNOpenGLStyleLayer - -@end diff --git a/platform/darwin/app/LimeGreenStyleLayer.m b/platform/darwin/app/LimeGreenStyleLayer.m deleted file mode 100644 index c920a736f92..00000000000 --- a/platform/darwin/app/LimeGreenStyleLayer.m +++ /dev/null @@ -1,58 +0,0 @@ -#import "LimeGreenStyleLayer.h" -#import - -@implementation LimeGreenStyleLayer { - GLuint _program; - GLuint _vertexShader; - GLuint _fragmentShader; - GLuint _buffer; - GLuint _aPos; -} - -- (void)didMoveToMapView:(MLNMapView *)mapView { - static const GLchar *vertexShaderSource = "#version 300 es\nlayout (location = 0) in vec2 a_pos; void main() { gl_Position = vec4(a_pos, 1, 1); }"; - static const GLchar *fragmentShaderSource = "#version 300 es\nout highp vec4 fragColor; void main() { fragColor = vec4(0, 0.5, 0, 0.5); }"; - - _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 triangle[] = { 0, 0.5, 0.5, -0.5, -0.5, -0.5 }; - glGenBuffers(1, &_buffer); - glBindBuffer(GL_ARRAY_BUFFER, _buffer); - glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), triangle, GL_STATIC_DRAW); -} - -- (void)drawInMapView:(MLNMapView *)mapView withContext:(MLNStyleLayerDrawingContext)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, 3); -} - -- (void)willMoveFromMapView:(MLNMapView *)mapView { - if (!_program) { - return; - } - - glDeleteBuffers(1, &_buffer); - glDetachShader(_program, _vertexShader); - glDetachShader(_program, _fragmentShader); - glDeleteShader(_vertexShader); - glDeleteShader(_fragmentShader); - glDeleteProgram(_program); -} - -@end diff --git a/platform/darwin/bazel/files.bzl b/platform/darwin/bazel/files.bzl index a7cee65be70..fd344cb28af 100644 --- a/platform/darwin/bazel/files.bzl +++ b/platform/darwin/bazel/files.bzl @@ -53,11 +53,13 @@ MLN_DARWIN_OBJC_HEADERS = [ "src/MLNAnnotation.h", "src/MLNAttributedExpression.h", "src/MLNAttributionInfo.h", + "src/MLNBackendResource.h", "src/MLNClockDirectionFormatter.h", "src/MLNCluster.h", "src/MLNCompassDirectionFormatter.h", "src/MLNComputedShapeSource.h", "src/MLNCoordinateFormatter.h", + "src/MLNCustomStyleLayer.h", "src/MLNCustomDrawableStyleLayer.h", "src/MLNDefaultStyle.h", "src/MLNDistanceFormatter.h", @@ -75,7 +77,6 @@ MLN_DARWIN_OBJC_HEADERS = [ "src/MLNOfflinePack.h", "src/MLNOfflineRegion.h", "src/MLNOfflineStorage.h", - "src/MLNOpenGLStyleLayer.h", "src/MLNOverlay.h", "src/MLNPointAnnotation.h", "src/MLNPointCollection.h", @@ -126,6 +127,7 @@ MLN_DARWIN_OBJCPP_HEADERS = [ MLN_DARWIN_PRIVATE_HEADERS = [ "src/MLNAttributionInfo_Private.h", "src/MLNComputedShapeSource_Private.h", + "src/MLNCustomStyleLayer_Private.h", "src/MLNFeature_Private.h", "src/MLNFoundation_Private.h", "src/MLNGeometry_Private.h", @@ -160,6 +162,7 @@ MLN_DARWIN_PRIVATE_HEADERS = [ MLN_DARWIN_PUBLIC_OBJCPP_SOURCE = [ "src/MLNAttributionInfo.mm", "src/MLNComputedShapeSource.mm", + "src/MLNCustomStyleLayer.mm", "src/MLNDefaultStyle.mm", "src/MLNFeature.mm", "src/MLNForegroundStyleLayer.mm", @@ -205,11 +208,6 @@ MLN_DARWIN_PUBLIC_OBJCPP_SOURCE = [ "src/NSPredicate+MLNAdditions.mm", "src/NSValue+MLNStyleAttributeAdditions.mm", ] -MLN_DARWIN_PUBLIC_OBJCPP_OPENGL_SOURCE = [ - "src/MLNOpenGLStyleLayer_Private.h", - "src/MLNOpenGLStyleLayer.h", - "src/MLNOpenGLStyleLayer.mm", -] MLN_DARWIN_PUBLIC_OBJCPP_CUSTOM_DRAWABLE_SOURCE = [ "src/MLNCustomDrawableStyleLayer_Private.h", "src/MLNCustomDrawableStyleLayer.mm", diff --git a/platform/darwin/src/MLNBackendResource.h b/platform/darwin/src/MLNBackendResource.h new file mode 100644 index 00000000000..97f9c9f630f --- /dev/null +++ b/platform/darwin/src/MLNBackendResource.h @@ -0,0 +1,19 @@ +#if MLN_RENDER_BACKEND_METAL + +#import + +typedef struct +{ + MTKView *mtkView; + id device; + MTLRenderPassDescriptor *renderPassDescriptor; + id commandBuffer; +} MLNBackendResource; + +#else + +typedef struct +{ +} MLNBackendResource; + +#endif diff --git a/platform/darwin/src/MLNOpenGLStyleLayer.h b/platform/darwin/src/MLNCustomStyleLayer.h similarity index 84% rename from platform/darwin/src/MLNOpenGLStyleLayer.h rename to platform/darwin/src/MLNCustomStyleLayer.h index 8231f763efa..135f3923dff 100644 --- a/platform/darwin/src/MLNOpenGLStyleLayer.h +++ b/platform/darwin/src/MLNCustomStyleLayer.h @@ -7,6 +7,10 @@ #import "MLNStyleLayer.h" #import "MLNGeometry.h" +#if MLN_RENDER_BACKEND_METAL +#import +#endif + NS_ASSUME_NONNULL_BEGIN @class MLNMapView; @@ -23,7 +27,7 @@ typedef struct MLNStyleLayerDrawingContext { } MLNStyleLayerDrawingContext; MLN_EXPORT -@interface MLNOpenGLStyleLayer : MLNStyleLayer +@interface MLNCustomStyleLayer : MLNStyleLayer @property (nonatomic, weak, readonly) MLNStyle *style; @@ -36,6 +40,10 @@ MLN_EXPORT #endif #pragma clang diagnostic pop +#if MLN_RENDER_BACKEND_METAL +@property (nonatomic, weak) id renderEncoder; +#endif + - (instancetype)initWithIdentifier:(NSString *)identifier; - (void)didMoveToMapView:(MLNMapView *)mapView; diff --git a/platform/darwin/src/MLNOpenGLStyleLayer.mm b/platform/darwin/src/MLNCustomStyleLayer.mm similarity index 73% rename from platform/darwin/src/MLNOpenGLStyleLayer.mm rename to platform/darwin/src/MLNCustomStyleLayer.mm index dc868979553..7bcb69dab93 100644 --- a/platform/darwin/src/MLNOpenGLStyleLayer.mm +++ b/platform/darwin/src/MLNCustomStyleLayer.mm @@ -1,35 +1,43 @@ -#import "MLNOpenGLStyleLayer.h" -#import "MLNOpenGLStyleLayer_Private.h" +#import "MLNCustomStyleLayer.h" +#import "MLNCustomStyleLayer_Private.h" #import "MLNMapView_Private.h" #import "MLNStyle_Private.h" #import "MLNStyleLayer_Private.h" #import "MLNGeometry_Private.h" +#if MLN_RENDER_BACKEND_METAL +#import +#endif + #include #include -class MLNOpenGLLayerHost; +#if MLN_RENDER_BACKEND_METAL +#include +#endif + +class MLNCustomLayerHost; /** - An `MLNOpenGLStyleLayer` is a style layer that is rendered by OpenGL code that + An `MLNCustomStyleLayer` is a style layer that is rendered by OpenGL / Metal code that you provide. By default, this class does nothing. You can subclass this class to provide - custom OpenGL drawing code that is run on each frame of the map. Your subclass + custom OpenGL or Metal drawing code that is run on each frame of the map. Your subclass should override the `-didMoveToMapView:`, `-willMoveFromMapView:`, and `-drawInMapView:withContext:` methods. - You can access an existing OpenGL style layer using the + You can access an existing MLNCustomStyleLayer using the `-[MLNStyle layerWithIdentifier:]` method if you know its identifier; otherwise, find it using the `MLNStyle.layers` property. You can also create a - new OpenGL style layer and add it to the style using a method such as + new MLNCustomStyleLayer and add it to the style using a method such as `-[MLNStyle addLayer:]`. @warning This API is undocumented and therefore unsupported. It may change at any time without notice. */ -@interface MLNOpenGLStyleLayer () +@interface MLNCustomStyleLayer () @property (nonatomic, readonly) mbgl::style::CustomLayer *rawLayer; @@ -45,10 +53,10 @@ @interface MLNOpenGLStyleLayer () @end -@implementation MLNOpenGLStyleLayer +@implementation MLNCustomStyleLayer /** - Returns an OpenGL style layer object initialized with the given identifier. + Returns an MLNCustomStyleLayer 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 `-[MLNStyle addLayer:]` or @@ -60,7 +68,7 @@ @implementation MLNOpenGLStyleLayer */ - (instancetype)initWithIdentifier:(NSString *)identifier { auto layer = std::make_unique(identifier.UTF8String, - std::make_unique(self)); + std::make_unique(self)); return self = [super initWithPendingLayer:std::move(layer)]; } @@ -88,13 +96,13 @@ - (CGLContextObj)context { // MARK: - Adding to and removing from a map view - (void)addToStyle:(MLNStyle *)style belowLayer:(MLNStyleLayer *)otherLayer { self.style = style; - self.style.openGLLayers[self.identifier] = self; + self.style.customLayers[self.identifier] = self; [super addToStyle:style belowLayer:otherLayer]; } - (void)removeFromStyle:(MLNStyle *)style { [super removeFromStyle:style]; - self.style.openGLLayers[self.identifier] = nil; + self.style.customLayers[self.identifier] = nil; self.style = nil; } @@ -164,9 +172,9 @@ - (void)setNeedsDisplay { @end -class MLNOpenGLLayerHost : public mbgl::style::CustomLayerHost { +class MLNCustomLayerHost : public mbgl::style::CustomLayerHost { public: - MLNOpenGLLayerHost(MLNOpenGLStyleLayer *styleLayer) { + MLNCustomLayerHost(MLNCustomStyleLayer *styleLayer) { layerRef = styleLayer; layer = nil; } @@ -180,17 +188,23 @@ void initialize() { } } - void render(const mbgl::style::CustomLayerRenderParameters ¶ms) { + void render(const mbgl::style::CustomLayerRenderParameters& parameters) { if(!layer) return; +#if MLN_RENDER_BACKEND_METAL + MTL::RenderCommandEncoder* ptr = static_cast(parameters).encoder.get(); + id encoder = (__bridge id)ptr; + layer.renderEncoder = encoder; +#endif + MLNStyleLayerDrawingContext 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 = static_cast(params.pitch), - .fieldOfView = static_cast(params.fieldOfView), - .projectionMatrix = MLNMatrix4Make(params.projectionMatrix) + .size = CGSizeMake(parameters.width, parameters.height), + .centerCoordinate = CLLocationCoordinate2DMake(parameters.latitude, parameters.longitude), + .zoomLevel = parameters.zoom, + .direction = mbgl::util::wrap(parameters.bearing, 0., 360.), + .pitch = static_cast(parameters.pitch), + .fieldOfView = static_cast(parameters.fieldOfView), + .projectionMatrix = MLNMatrix4Make(parameters.projectionMatrix) }; if (layer.mapView) { [layer drawInMapView:layer.mapView withContext:drawingContext]; @@ -209,14 +223,14 @@ void deinitialize() { layer = nil; } private: - __weak MLNOpenGLStyleLayer * layerRef; - MLNOpenGLStyleLayer * layer = nil; + __weak MLNCustomStyleLayer * layerRef; + MLNCustomStyleLayer * layer = nil; }; namespace mbgl { -MLNStyleLayer* OpenGLStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MLNOpenGLStyleLayer alloc] initWithRawLayer:rawLayer]; +MLNStyleLayer* CustomStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { + return [[MLNCustomStyleLayer alloc] initWithRawLayer:rawLayer]; } } // namespace mbgl diff --git a/platform/darwin/src/MLNOpenGLStyleLayer_Private.h b/platform/darwin/src/MLNCustomStyleLayer_Private.h similarity index 84% rename from platform/darwin/src/MLNOpenGLStyleLayer_Private.h rename to platform/darwin/src/MLNCustomStyleLayer_Private.h index 07f59d7bfaa..39ce4d33988 100644 --- a/platform/darwin/src/MLNOpenGLStyleLayer_Private.h +++ b/platform/darwin/src/MLNCustomStyleLayer_Private.h @@ -6,7 +6,7 @@ namespace mbgl { -class OpenGLStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::CustomLayerFactory { +class CustomStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::CustomLayerFactory { // LayerPeerFactory overrides. LayerFactory* getCoreLayerFactory() final { return this; } virtual MLNStyleLayer* createPeer(style::Layer*) final; diff --git a/platform/darwin/src/MLNStyle.mm b/platform/darwin/src/MLNStyle.mm index 7b885c6af8a..d8101b56113 100644 --- a/platform/darwin/src/MLNStyle.mm +++ b/platform/darwin/src/MLNStyle.mm @@ -39,9 +39,7 @@ #import "NSDate+MLNAdditions.h" -#if !MLN_RENDER_BACKEND_METAL - #import "MLNOpenGLStyleLayer.h" -#endif +#import "MLNCustomStyleLayer.h" #if TARGET_OS_IPHONE #import "UIImage+MLNAdditions.h" @@ -82,7 +80,7 @@ @interface MLNStyle() @property (nonatomic, readonly, weak) id stylable; @property (nonatomic, readonly) mbgl::style::Style *rawStyle; @property (readonly, copy, nullable) NSURL *URL; -@property (nonatomic, readwrite, strong) NSMutableDictionary *openGLLayers; +@property (nonatomic, readwrite, strong) NSMutableDictionary *customLayers; @property (nonatomic) NSMutableDictionary *> *localizedLayersByIdentifier; @end @@ -125,7 +123,7 @@ - (instancetype)initWithRawStyle:(mbgl::style::Style *)rawStyle stylable:(id ()); -#elif !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL) && !MLN_RENDER_BACKEND_METAL - addLayerType(std::make_unique()); +#elif !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL) + addLayerType(std::make_unique()); #endif #if MLN_DRAWABLE_RENDERER diff --git a/platform/darwin/src/MLNStyle_Private.h b/platform/darwin/src/MLNStyle_Private.h index def44f5c3c8..8300081bf7d 100644 --- a/platform/darwin/src/MLNStyle_Private.h +++ b/platform/darwin/src/MLNStyle_Private.h @@ -13,7 +13,7 @@ namespace mbgl { @class MLNAttributionInfo; @class MLNMapView; -@class MLNOpenGLStyleLayer; +@class MLNCustomStyleLayer; @class MLNVectorTileSource; @class MLNVectorStyleLayer; @@ -25,7 +25,7 @@ namespace mbgl { @property (nonatomic, readonly) mbgl::style::Style *rawStyle; - (nullable NSArray *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MLNColor *)linkColor; -@property (nonatomic, readonly, strong) NSMutableDictionary *openGLLayers; +@property (nonatomic, readonly, strong) NSMutableDictionary *customLayers; - (void)setStyleClasses:(NSArray *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration; @end diff --git a/platform/darwin/test/MLNStyleTests.mm b/platform/darwin/test/MLNStyleTests.mm index 101c38ab3cd..4c93719979e 100644 --- a/platform/darwin/test/MLNStyleTests.mm +++ b/platform/darwin/test/MLNStyleTests.mm @@ -232,9 +232,7 @@ - (void)testAddingLayersWithDuplicateIdentifiers { XCTAssertThrowsSpecificNamed([self.style insertLayer:[[MLNFillStyleLayer alloc] initWithIdentifier:@"my-layer" source:source] belowLayer:initial],NSException, @"MLNRedundantLayerIdentifierException"); XCTAssertThrowsSpecificNamed([self.style insertLayer:[[MLNFillStyleLayer alloc] initWithIdentifier:@"my-layer" source:source] aboveLayer:initial], NSException, @"MLNRedundantLayerIdentifierException"); XCTAssertThrowsSpecificNamed([self.style insertLayer:[[MLNFillStyleLayer alloc] initWithIdentifier:@"my-layer" source:source] atIndex:0], NSException, @"MLNRedundantLayerIdentifierException"); -#if !MLN_RENDER_BACKEND_METAL - XCTAssertThrowsSpecificNamed([self.style insertLayer:[[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"my-layer"] atIndex:0], NSException, @"MLNRedundantLayerIdentifierException"); -#endif + XCTAssertThrowsSpecificNamed([self.style insertLayer:[[MLNCustomStyleLayer alloc] initWithIdentifier:@"my-layer"] atIndex:0], NSException, @"MLNRedundantLayerIdentifierException"); } - (void)testRemovingLayerBeforeAddingSameLayer { diff --git a/platform/ios/Integration_Tests/MBGLIntegrationTests.mm b/platform/ios/Integration_Tests/MBGLIntegrationTests.mm index 4c57907a980..846103a1953 100644 --- a/platform/ios/Integration_Tests/MBGLIntegrationTests.mm +++ b/platform/ios/Integration_Tests/MBGLIntegrationTests.mm @@ -17,7 +17,7 @@ - (void)waitForMapViewToBeRendered { // This test does not strictly need to be in this test file/target. Including here for convenience. - (void)testOpenGLLayerDoesNotLeakWhenCreatedAndDestroyedWithoutAddingToStyle { - MLNOpenGLStyleLayer *layer = [[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"gl-layer"]; + MLNCustomStyleLayer *layer = [[MLNCustomStyleLayer alloc] initWithIdentifier:@"gl-layer"]; __weak id weakLayer = layer; layer = nil; @@ -31,7 +31,7 @@ - (void)testAddingRemovingOpenGLLayerWithoutRendering { __weak id weakLayer = nil; @autoreleasepool { - MLNOpenGLStyleLayer *layer = [[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"gl-layer"]; + MLNCustomStyleLayer *layer = [[MLNCustomStyleLayer alloc] initWithIdentifier:@"gl-layer"]; [self.style insertLayer:layer atIndex:0]; weakLayer = layer; @@ -49,15 +49,15 @@ - (void)testAddingRemovingOpenGLLayerWithoutRendering { } - (void)testReusingOpenGLLayerIdentifier { - __weak MLNOpenGLStyleLayer *weakLayer2; + __weak MLNCustomStyleLayer *weakLayer2; @autoreleasepool { - MLNOpenGLStyleLayer *layer1 = [[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"gl-layer"]; + MLNCustomStyleLayer *layer1 = [[MLNCustomStyleLayer alloc] initWithIdentifier:@"gl-layer"]; [self.style insertLayer:layer1 atIndex:0]; [self waitForMapViewToBeRendered]; [self.style removeLayer:layer1]; - MLNOpenGLStyleLayer *layer2 = [[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"gl-layer"]; + MLNCustomStyleLayer *layer2 = [[MLNCustomStyleLayer alloc] initWithIdentifier:@"gl-layer"]; weakLayer2 = layer2; XCTAssertNotNil(layer2); @@ -88,7 +88,7 @@ - (void)testAddingRemovingOpenGLLayer { __weak id retrievedLayer = nil; @autoreleasepool { - MLNOpenGLStyleLayer *layer = [[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"gl-layer"]; + MLNCustomStyleLayer *layer = [[MLNCustomStyleLayer alloc] initWithIdentifier:@"gl-layer"]; [self.style insertLayer:layer atIndex:0]; layer = nil; @@ -110,7 +110,7 @@ - (void)testAddingRemovingOpenGLLayer { } - (void)testReusingOpenGLLayer { - MLNOpenGLStyleLayer *layer = [[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"gl-layer"]; + MLNCustomStyleLayer *layer = [[MLNCustomStyleLayer alloc] initWithIdentifier:@"gl-layer"]; [self.style insertLayer:layer atIndex:0]; [self waitForMapViewToBeRendered]; @@ -127,7 +127,7 @@ - (void)testReusingOpenGLLayer { - (void)testOpenGLLayerDoesNotLeakWhenRemovedFromStyle { __weak id weakLayer; @autoreleasepool { - MLNOpenGLStyleLayer *layer = [[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"gl-layer"]; + MLNCustomStyleLayer *layer = [[MLNCustomStyleLayer alloc] initWithIdentifier:@"gl-layer"]; weakLayer = layer; [self.style insertLayer:layer atIndex:0]; layer = nil; @@ -146,11 +146,11 @@ - (void)testOpenGLLayerDoesNotLeakWhenRemovedFromStyle { } - (void)testOpenGLLayerDoesNotLeakWhenStyleChanged { - __weak MLNOpenGLStyleLayer *weakLayer; + __weak MLNCustomStyleLayer *weakLayer; @autoreleasepool { { - MLNOpenGLStyleLayer *layer = [[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"gl-layer"]; + MLNCustomStyleLayer *layer = [[MLNCustomStyleLayer alloc] initWithIdentifier:@"gl-layer"]; weakLayer = layer; [self.style insertLayer:layer atIndex:0]; layer = nil; @@ -192,7 +192,7 @@ - (void)testOpenGLLayerDoesNotLeakWhenMapViewDeallocs { self.styleLoadingExpectation = [self expectationWithDescription:@"Map view should finish loading style."]; [self waitForExpectationsWithTimeout:10 handler:nil]; - MLNOpenGLStyleLayer *layer = [[MLNOpenGLStyleLayer alloc] initWithIdentifier:@"gl-layer"]; + MLNCustomStyleLayer *layer = [[MLNCustomStyleLayer alloc] initWithIdentifier:@"gl-layer"]; weakLayer = layer; [mapView2.style insertLayer:layer atIndex:0]; layer = nil; diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index fa94621cc7a..d724e248d33 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -13,9 +13,7 @@ #import "MBXState.h" #import "MLNSettings.h" -#if !MLN_RENDER_BACKEND_METAL -#import "LimeGreenStyleLayer.h" -#endif +#import "CustomStyleLayerExample.h" #if MLN_DRAWABLE_RENDERER #import "ExampleCustomDrawableStyleLayer.h" @@ -101,9 +99,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) { MBXSettingsRuntimeStylingRasterTileSource, MBXSettingsRuntimeStylingImageSource, MBXSettingsRuntimeStylingRouteLine, -#if !MLN_RENDER_BACKEND_METAL - MBXSettingsRuntimeStylingAddLimeGreenTriangleLayer, -#endif + MBXSettingsRuntimeStylingAddCustomTriangleLayer, MBXSettingsRuntimeStylingDDSPolygon, MBXSettingsRuntimeStylingCustomLatLonGrid, MBXSettingsRuntimeStylingLineGradient, @@ -435,8 +431,10 @@ - (void)dismissSettings:(__unused id)sender @"Style Raster Tile Source", @"Style Image Source", @"Add Route Line", -#if !MLN_RENDER_BACKEND_METAL - @"Add Lime Green Triangle Layer", +#if MLN_RENDER_BACKEND_METAL + @"Add Custom Triangle Layer (Metal)", +#else + @"Add Custom Triangle Layer (OpenGL)", #endif @"Dynamically Style Polygon", @"Add Custom Lat/Lon Grid", @@ -654,11 +652,9 @@ - (void)performActionForSettingAtIndexPath:(NSIndexPath *)indexPath case MBXSettingsRuntimeStylingRouteLine: [self styleRouteLine]; break; -#if !MLN_RENDER_BACKEND_METAL - case MBXSettingsRuntimeStylingAddLimeGreenTriangleLayer: - [self styleAddLimeGreenTriangleLayer]; + case MBXSettingsRuntimeStylingAddCustomTriangleLayer: + [self styleAddCustomTriangleLayer]; break; -#endif case MBXSettingsRuntimeStylingDDSPolygon: [self stylePolygonWithDDS]; break; @@ -1604,13 +1600,11 @@ - (void)styleRouteLine [self.mapView.style addLayer:routeLayer]; } -#if !MLN_RENDER_BACKEND_METAL -- (void)styleAddLimeGreenTriangleLayer +- (void)styleAddCustomTriangleLayer { - LimeGreenStyleLayer *layer = [[LimeGreenStyleLayer alloc] initWithIdentifier:@"mbx-custom"]; + CustomStyleLayerExample *layer = [[CustomStyleLayerExample alloc] initWithIdentifier:@"mbx-custom"]; [self.mapView.style addLayer:layer]; } -#endif - (void)stylePolygonWithDDS { CLLocationCoordinate2D leftCoords[] = { diff --git a/platform/ios/scripts/bazel-package.sh b/platform/ios/scripts/bazel-package.sh old mode 100644 new mode 100755 diff --git a/platform/ios/sdk-files.json b/platform/ios/sdk-files.json index 5874ee4cdf8..bdf4b9c32dc 100644 --- a/platform/ios/sdk-files.json +++ b/platform/ios/sdk-files.json @@ -113,7 +113,7 @@ "platform/darwin/src/MLNPointCollection.mm", "platform/darwin/src/MLNLineStyleLayer.mm", "platform/ios/src/MLNMapAccessibilityElement.mm", - "platform/darwin/src/MLNOpenGLStyleLayer.mm", + "platform/darwin/src/MLNCustomStyleLayer.mm", "platform/darwin/src/MLNSettings.mm", "platform/darwin/src/NSCompoundPredicate+MLNAdditions.mm", "platform/ios/src/MLNTelemetryConfig.m", @@ -185,7 +185,7 @@ "MLNOfflineRegion.h": "platform/darwin/src/MLNOfflineRegion.h", "MLNMapViewDelegate.h": "platform/ios/src/MLNMapViewDelegate.h", "MLNDistanceFormatter.h": "platform/darwin/src/MLNDistanceFormatter.h", - "MLNOpenGLStyleLayer.h": "platform/darwin/src/MLNOpenGLStyleLayer.h", + "MLNCustomStyleLayer.h": "platform/darwin/src/MLNCustomStyleLayer.h", "MLNTileSource.h": "platform/darwin/src/MLNTileSource.h", "MLNTilePyramidOfflineRegion.h": "platform/darwin/src/MLNTilePyramidOfflineRegion.h", "MLNVectorTileSource.h": "platform/darwin/src/MLNVectorTileSource.h", @@ -277,7 +277,7 @@ "MLNGeometry_Private.h": "platform/darwin/src/MLNGeometry_Private.h", "NSCompoundPredicate+MLNAdditions.h": "platform/darwin/src/NSCompoundPredicate+MLNAdditions.h", "NSExpression+MLNPrivateAdditions.h": "platform/darwin/src/NSExpression+MLNPrivateAdditions.h", - "MLNOpenGLStyleLayer_Private.h": "platform/darwin/src/MLNOpenGLStyleLayer_Private.h", + "MLNCustomStyleLayer_Private.h": "platform/darwin/src/MLNCustomStyleLayer_Private.h", "MLNTileSource_Private.h": "platform/darwin/src/MLNTileSource_Private.h", "MLNFaux3DUserLocationAnnotationView.h": "platform/ios/src/MLNFaux3DUserLocationAnnotationView.h", "MLNUserLocationAnnotationView_Private.h": "platform/ios/src/MLNUserLocationAnnotationView_Private.h", diff --git a/platform/ios/src/MLNMapView+Impl.h b/platform/ios/src/MLNMapView+Impl.h index 73d6e45361b..04a9919773f 100644 --- a/platform/ios/src/MLNMapView+Impl.h +++ b/platform/ios/src/MLNMapView+Impl.h @@ -2,6 +2,8 @@ #import #import +#import "MLNBackendResource.h" + #import #import #import @@ -54,6 +56,8 @@ class MLNMapViewImpl : public mbgl::MapObserver { // Called by the view delegate when it's time to render. void render(); + virtual MLNBackendResource getObject() = 0; + // mbgl::MapObserver implementation void onCameraWillChange(mbgl::MapObserver::CameraChangeMode) override; void onCameraIsChanging() override; diff --git a/platform/ios/src/MLNMapView+Metal.h b/platform/ios/src/MLNMapView+Metal.h index e78e833730f..17b26146ca3 100644 --- a/platform/ios/src/MLNMapView+Metal.h +++ b/platform/ios/src/MLNMapView+Metal.h @@ -47,6 +47,7 @@ class MLNMapViewMetalImpl final : public MLNMapViewImpl, void deleteView() override; UIImage* snapshot() override; void layoutChanged() override; + MLNBackendResource getObject() override; // End implementation of MLNMapViewImpl private: diff --git a/platform/ios/src/MLNMapView+Metal.mm b/platform/ios/src/MLNMapView+Metal.mm index c9635b6df00..eb9ff5b3893 100644 --- a/platform/ios/src/MLNMapView+Metal.mm +++ b/platform/ios/src/MLNMapView+Metal.mm @@ -52,8 +52,10 @@ void bind() override { commandQueue = [mtlView.device newCommandQueue]; } - commandBuffer = [commandQueue commandBuffer]; - commandBufferPtr = NS::RetainPtr((__bridge MTL::CommandBuffer*)commandBuffer); + if (!commandBuffer) { + commandBuffer = [commandQueue commandBuffer]; + commandBufferPtr = NS::RetainPtr((__bridge MTL::CommandBuffer*)commandBuffer); + } } const mbgl::mtl::RendererBackend& getBackend() const override { return backend; } @@ -219,3 +221,14 @@ void swap() override { size = { static_cast(mapView.bounds.size.width * scaleFactor), static_cast(mapView.bounds.size.height * scaleFactor) }; } + +MLNBackendResource MLNMapViewMetalImpl::getObject() { + auto& resource = getResource(); + auto renderPassDescriptor = resource.getRenderPassDescriptor().get(); + return { + resource.mtlView, + resource.mtlView.device, + [MTLRenderPassDescriptor renderPassDescriptor], + resource.commandBuffer + }; +} diff --git a/platform/ios/src/MLNMapView+OpenGL.h b/platform/ios/src/MLNMapView+OpenGL.h index 555393a8afe..3e455f87d7c 100644 --- a/platform/ios/src/MLNMapView+OpenGL.h +++ b/platform/ios/src/MLNMapView+OpenGL.h @@ -56,5 +56,6 @@ class MLNMapViewOpenGLImpl final : public MLNMapViewImpl, void deleteView() override; UIImage* snapshot() override; void layoutChanged() override; + MLNBackendResource getObject() override; // End implementation of MLNMapViewImpl }; diff --git a/platform/ios/src/MLNMapView+OpenGL.mm b/platform/ios/src/MLNMapView+OpenGL.mm index b8c4d008ec0..3e3cc000628 100644 --- a/platform/ios/src/MLNMapView+OpenGL.mm +++ b/platform/ios/src/MLNMapView+OpenGL.mm @@ -252,3 +252,7 @@ void bind() override { auto& resource = getResource(); return resource.context; } + +MLNBackendResource MLNMapViewOpenGLImpl::getObject() { + return MLNBackendResource(); +} diff --git a/platform/ios/src/MLNMapView.h b/platform/ios/src/MLNMapView.h index 292cc6e2edc..6ac72f50c97 100644 --- a/platform/ios/src/MLNMapView.h +++ b/platform/ios/src/MLNMapView.h @@ -6,6 +6,7 @@ #import "MLNMapCamera.h" #import "MLNTypes.h" #import "MLNStyle.h" +#import "MLNBackendResource.h" NS_ASSUME_NONNULL_BEGIN @@ -2000,6 +2001,8 @@ MLN_EXPORT */ @property (nonatomic) MLNMapDebugMaskOptions debugMask; + +- (MLNBackendResource)backendResource; @end NS_ASSUME_NONNULL_END diff --git a/platform/ios/src/MLNMapView.mm b/platform/ios/src/MLNMapView.mm index 196284ad7d6..4f0657bd61a 100644 --- a/platform/ios/src/MLNMapView.mm +++ b/platform/ios/src/MLNMapView.mm @@ -7327,6 +7327,10 @@ - (void)prepareForInterfaceBuilder return _annotationViewReuseQueueByIdentifier[identifier]; } +- (MLNBackendResource)backendResource { + return _mbglView->getObject(); +} + @end // MARK: - IBAdditions methods diff --git a/platform/ios/src/Mapbox.h b/platform/ios/src/Mapbox.h index 076b7f6f95d..a926ad438dd 100644 --- a/platform/ios/src/Mapbox.h +++ b/platform/ios/src/Mapbox.h @@ -46,6 +46,7 @@ FOUNDATION_EXPORT MLN_EXPORT const unsigned char MapboxVersionString[]; #import "MLNOfflinePack.h" #import "MLNOfflineRegion.h" #import "MLNOfflineStorage.h" +#import "MLNCustomStyleLayer.h" #import "MLNOverlay.h" #import "MLNPointAnnotation.h" #import "MLNPointCollection.h" diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index e543287f6b2..4cafdc46e17 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -1,7 +1,7 @@ #import "MapDocument.h" #import "AppDelegate.h" -#import "LimeGreenStyleLayer.h" +#import "CustomStyleLayerExample.h" #import "DroppedPinAnnotation.h" #import "MLNMapsnapshotter.h" @@ -787,7 +787,7 @@ - (IBAction)insertCustomStyleLayer:(id)sender { [self.undoManager setActionName:@"Add Lime Green Layer"]; } - LimeGreenStyleLayer *layer = [[LimeGreenStyleLayer alloc] initWithIdentifier:@"mbx-custom"]; + CustomStyleLayerExample *layer = [[CustomStyleLayerExample alloc] initWithIdentifier:@"mbx-custom"]; MLNStyleLayer *houseNumberLayer = [self.mapView.style layerWithIdentifier:@"housenum-label"]; if (houseNumberLayer) { [self.mapView.style insertLayer:layer belowLayer:houseNumberLayer]; diff --git a/platform/macos/sdk-files.json b/platform/macos/sdk-files.json index 609902500f6..91329e6ddf0 100644 --- a/platform/macos/sdk-files.json +++ b/platform/macos/sdk-files.json @@ -19,7 +19,7 @@ "platform/macos/src/MLNAnnotationImage.m", "platform/darwin/src/NSExpression+MLNAdditions.mm", "platform/darwin/src/MLNFeature.mm", - "platform/darwin/src/MLNOpenGLStyleLayer.mm", + "platform/darwin/src/MLNCustomStyleLayer.mm", "platform/macos/src/NSColor+MLNAdditions.mm", "platform/macos/src/MLNAttributionButton.mm", "platform/darwin/src/MLNFillStyleLayer.mm", @@ -108,7 +108,7 @@ "MLNBackgroundStyleLayer.h": "platform/darwin/src/MLNBackgroundStyleLayer.h", "MLNPointCollection.h": "platform/darwin/src/MLNPointCollection.h", "MLNShape.h": "platform/darwin/src/MLNShape.h", - "MLNOpenGLStyleLayer.h": "platform/darwin/src/MLNOpenGLStyleLayer.h", + "MLNCustomStyleLayer.h": "platform/darwin/src/MLNCustomStyleLayer.h", "MLNSource.h": "platform/darwin/src/MLNSource.h", "MLNPolygon.h": "platform/darwin/src/MLNPolygon.h", "MLNClockDirectionFormatter.h": "platform/darwin/src/MLNClockDirectionFormatter.h", @@ -202,7 +202,7 @@ "NSDate+MLNAdditions.h": "platform/darwin/src/NSDate+MLNAdditions.h", "NSColor+MLNAdditions.h": "platform/macos/src/NSColor+MLNAdditions.h", "MLNMultiPoint_Private.h": "platform/darwin/src/MLNMultiPoint_Private.h", - "MLNOpenGLStyleLayer_Private.h": "platform/darwin/src/MLNOpenGLStyleLayer_Private.h", + "MLNCustomStyleLayer_Private.h": "platform/darwin/src/MLNCustomStyleLayer_Private.h", "MLNPolygon_Private.h": "platform/darwin/src/MLNPolygon_Private.h", "MLNShape_Private.h": "platform/darwin/src/MLNShape_Private.h", "MLNTilePyramidOfflineRegion_Private.h": "platform/darwin/src/MLNTilePyramidOfflineRegion_Private.h", diff --git a/platform/macos/src/Mapbox.h b/platform/macos/src/Mapbox.h index 0ae1f1de2fc..d8aeab39129 100644 --- a/platform/macos/src/Mapbox.h +++ b/platform/macos/src/Mapbox.h @@ -47,7 +47,7 @@ FOUNDATION_EXPORT MLN_EXPORT const unsigned char MapboxVersionString[]; #import "MLNBackgroundStyleLayer.h" #import "MLNHeatmapStyleLayer.h" #import "MLNHillshadeStyleLayer.h" -#import "MLNOpenGLStyleLayer.h" +#import "MLNCustomStyleLayer.h" #import "MLNSource.h" #import "MLNTileSource.h" #import "MLNVectorTileSource.h" diff --git a/src/mbgl/gfx/drawable_custom_layer_host_tweaker.cpp b/src/mbgl/gfx/drawable_custom_layer_host_tweaker.cpp index 6a19ac676f0..6bf00fb45ae 100644 --- a/src/mbgl/gfx/drawable_custom_layer_host_tweaker.cpp +++ b/src/mbgl/gfx/drawable_custom_layer_host_tweaker.cpp @@ -6,30 +6,27 @@ #include #include +#if MLN_RENDER_BACKEND_METAL +#include +#endif + +#include + namespace mbgl { namespace gfx { void DrawableCustomLayerHostTweaker::execute([[maybe_unused]] gfx::Drawable& drawable, - const PaintParameters& paintParameters) { + const mbgl::PaintParameters& paintParameters) { // custom drawing auto& context = paintParameters.context; - const TransformState& state = paintParameters.state; context.resetState(paintParameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly), paintParameters.colorModeForRenderPass()); - style::CustomLayerRenderParameters parameters; - - parameters.width = state.getSize().width; - parameters.height = state.getSize().height; - parameters.latitude = state.getLatLng().latitude(); - parameters.longitude = state.getLatLng().longitude(); - parameters.zoom = state.getZoom(); - parameters.bearing = util::rad2deg(-state.getBearing()); - parameters.pitch = state.getPitch(); - parameters.fieldOfView = state.getFieldOfView(); - mat4 projMatrix; - state.getProjMatrix(projMatrix); - parameters.projectionMatrix = projMatrix; +#if MLN_RENDER_BACKEND_METAL + style::mtl::CustomLayerRenderParameters parameters(paintParameters); +#else + style::CustomLayerRenderParameters parameters(paintParameters); +#endif host->render(parameters); diff --git a/src/mbgl/gl/drawable_gl.cpp b/src/mbgl/gl/drawable_gl.cpp index 4560f46651c..33499312cab 100644 --- a/src/mbgl/gl/drawable_gl.cpp +++ b/src/mbgl/gl/drawable_gl.cpp @@ -145,7 +145,12 @@ struct IndexBufferGL : public gfx::IndexBufferBase { }; void DrawableGL::upload(gfx::UploadPass& uploadPass) { + if (isCustom) { + return; + } if (!shader) { + Log::Warning(Event::General, "Missing shader for drawable " + util::toString(getID()) + "/" + getName()); + assert(false); return; } diff --git a/src/mbgl/mtl/drawable.cpp b/src/mbgl/mtl/drawable.cpp index d0883842c11..865a22b893b 100644 --- a/src/mbgl/mtl/drawable.cpp +++ b/src/mbgl/mtl/drawable.cpp @@ -479,6 +479,9 @@ MTL::VertexFormat mtlVertexTypeOf(gfx::AttributeDataType type) noexcept { } // namespace void Drawable::upload(gfx::UploadPass& uploadPass_) { + if (isCustom) { + return; + } if (!shader) { Log::Warning(Event::General, "Missing shader for drawable " + util::toString(getID()) + "/" + getName()); assert(false); diff --git a/src/mbgl/mtl/render_pass.cpp b/src/mbgl/mtl/render_pass.cpp index f09feb4654e..0841768a2cf 100644 --- a/src/mbgl/mtl/render_pass.cpp +++ b/src/mbgl/mtl/render_pass.cpp @@ -15,9 +15,7 @@ RenderPass::RenderPass(CommandEncoder& commandEncoder_, const char* name, const commandEncoder(commandEncoder_) { auto& resource = descriptor.renderable.getResource(); - if (!resource.getCommandBuffer()) { - resource.bind(); - } + resource.bind(); if (const auto& buffer = resource.getCommandBuffer()) { if (auto rpd = resource.getRenderPassDescriptor()) { diff --git a/src/mbgl/mtl/upload_pass.cpp b/src/mbgl/mtl/upload_pass.cpp index cf1ef9cf604..b8e6ab7cab2 100644 --- a/src/mbgl/mtl/upload_pass.cpp +++ b/src/mbgl/mtl/upload_pass.cpp @@ -19,9 +19,7 @@ UploadPass::UploadPass(gfx::Renderable& renderable, CommandEncoder& commandEncod : commandEncoder(commandEncoder_) { auto& resource = renderable.getResource(); - if (!resource.getCommandBuffer()) { - resource.bind(); - } + resource.bind(); if (const auto& buffer_ = resource.getCommandBuffer()) { buffer = buffer_; diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp index 39647a08ff7..86168a1c562 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_layer.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #endif #if MLN_DRAWABLE_RENDERER @@ -86,7 +87,6 @@ void RenderCustomLayer::render(PaintParameters& paintParameters) { // TODO: remove cast auto& glContext = static_cast(paintParameters.context); - const TransformState& state = paintParameters.state; // Reset GL state to a known state so the CustomLayer always has a clean slate. glContext.bindVertexArray = 0; @@ -95,21 +95,7 @@ void RenderCustomLayer::render(PaintParameters& paintParameters) { glContext.setColorMode(paintParameters.colorModeForRenderPass()); glContext.setCullFaceMode(gfx::CullFaceMode::disabled()); - CustomLayerRenderParameters parameters; - - parameters.width = state.getSize().width; - parameters.height = state.getSize().height; - parameters.latitude = state.getLatLng().latitude(); - parameters.longitude = state.getLatLng().longitude(); - parameters.zoom = state.getZoom(); - parameters.bearing = util::rad2deg(-state.getBearing()); - parameters.pitch = state.getPitch(); - parameters.fieldOfView = state.getFieldOfView(); - mat4 projMatrix; - state.getProjMatrix(projMatrix); - parameters.projectionMatrix = projMatrix; - - MBGL_CHECK_ERROR(host->render(parameters)); + MBGL_CHECK_ERROR(host->render(CustomLayerRenderParameters(paintParameters))); // Reset the view back to our original one, just in case the CustomLayer // changed the viewport or Framebuffer. diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index 315f3ac401b..3e115f6ccea 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -350,7 +350,7 @@ class OutlineDrawableTweaker : public gfx::DrawableTweaker { void init(gfx::Drawable&) override{}; - void execute(gfx::Drawable& drawable, const PaintParameters& parameters) override { + virtual void execute(gfx::Drawable& drawable, const PaintParameters& parameters) override { if (!drawable.getTileID().has_value()) { return; } diff --git a/src/mbgl/renderer/render_tree.hpp b/src/mbgl/renderer/render_tree.hpp index f6bf888dbb5..bf106e5e72e 100644 --- a/src/mbgl/renderer/render_tree.hpp +++ b/src/mbgl/renderer/render_tree.hpp @@ -13,8 +13,8 @@ namespace mbgl { -class PaintParameters; class PatternAtlas; +class PaintParameters; namespace gfx { class UploadPass; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 0546d96afad..56dc856e1e3 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/src/mbgl/style/layers/custom_drawable_layer.cpp b/src/mbgl/style/layers/custom_drawable_layer.cpp index d7ee3b3e2fe..9b8525ec075 100644 --- a/src/mbgl/style/layers/custom_drawable_layer.cpp +++ b/src/mbgl/style/layers/custom_drawable_layer.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/src/mbgl/style/layers/custom_layer_render_parameters.cpp b/src/mbgl/style/layers/custom_layer_render_parameters.cpp new file mode 100644 index 00000000000..24a869657c3 --- /dev/null +++ b/src/mbgl/style/layers/custom_layer_render_parameters.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +namespace mbgl { +namespace style { + +CustomLayerRenderParameters::CustomLayerRenderParameters(const mbgl::PaintParameters& paintParameters) { + const TransformState& state = paintParameters.state; + width = state.getSize().width; + height = state.getSize().height; + latitude = state.getLatLng().latitude(); + longitude = state.getLatLng().longitude(); + zoom = state.getZoom(); + bearing = util::rad2deg(-state.getBearing()); + pitch = state.getPitch(); + fieldOfView = state.getFieldOfView(); + mat4 projMatrix; + state.getProjMatrix(projMatrix); + projectionMatrix = projMatrix; +} + +} // namespace style +} // namespace mbgl \ No newline at end of file diff --git a/src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp b/src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp new file mode 100644 index 00000000000..660234e6459 --- /dev/null +++ b/src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +#include +#include + +namespace mbgl { +namespace style { +namespace mtl { + +CustomLayerRenderParameters::CustomLayerRenderParameters(const mbgl::PaintParameters& paintParameters) + : mbgl::style::CustomLayerRenderParameters(paintParameters) { + const mbgl::mtl::RenderPass& renderPass = static_cast(*paintParameters.renderPass); + encoder = renderPass.getMetalEncoder(); +} + +} // namespace mtl +} // namespace style +} // namespace mbgl diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp index 885d8c2cc59..20cdf3a2bc1 100644 --- a/test/api/custom_layer.test.cpp +++ b/test/api/custom_layer.test.cpp @@ -15,6 +15,8 @@ #include #include +#include + using namespace mbgl; using namespace mbgl::style; using namespace mbgl::platform;