Metal setup merge (#1616)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Alex Cristici <alex.cristici@gmail.com>
Co-authored-by: mwilsnd <mwilsnd@gmail.com>
Co-authored-by: Stefan Karschti <stefan.karschti@gmail.com>
Co-authored-by: Bart Louwers <bart@emeel.net>
Co-authored-by: Alex Cristici <alex@skoon.energy>
Co-authored-by: Bart Louwers <bart.louwers@gmail.com>
Co-authored-by: Wei Chen <alanchenboy@gmail.com>
Co-authored-by: Siarhei Fedartsou <siarhei.fedartsou@gmail.com>
Co-authored-by: tdcosta100 <tdcosta100@gmail.com>
This commit is contained in:
Tim Sylvester
2023-09-13 11:35:20 -07:00
committed by GitHub
parent 085b0ced6d
commit 82ec59a2b0
284 changed files with 32357 additions and 1155 deletions

View File

@@ -199,4 +199,4 @@ jobs:
steps:
- name: Mark result as failed
if: needs.ios-build.result != 'success'
run: exit 1
run: exit 1

View File

@@ -5,7 +5,12 @@ load(
"MLN_CORE_SOURCE",
"MLN_DRAWABLES_HEADERS",
"MLN_DRAWABLES_SOURCE",
"MLN_DRAWABLES_GL_HEADERS",
"MLN_DRAWABLES_GL_SOURCE",
"MLN_DRAWABLES_MTL_HEADERS",
"MLN_DRAWABLES_MTL_SOURCE",
"MLN_GENERATED_SHADER_HEADERS",
"MLN_GENERATED_OPENGL_SHADER_HEADERS",
"MLN_GENERATED_STYLE_SOURCE",
"MLN_OPENGL_HEADERS",
"MLN_OPENGL_SOURCE",
@@ -44,7 +49,8 @@ filegroup(
genrule(
name = "generated_shaders",
srcs = ["shader_data"],
outs = MLN_GENERATED_SHADER_HEADERS,
outs = MLN_GENERATED_SHADER_HEADERS +
MLN_GENERATED_OPENGL_SHADER_HEADERS,
cmd = "node $(execpath shaders/generate_shader_code.js) --root $(RULEDIR)",
tools = ["shaders/generate_shader_code.js"],
)
@@ -55,7 +61,11 @@ cc_library(
name = "mbgl-core-generated-public-artifacts",
srcs = [],
hdrs = MLN_PUBLIC_GENERATED_STYLE_HEADERS +
MLN_GENERATED_SHADER_HEADERS,
MLN_GENERATED_SHADER_HEADERS +
select({
"//:metal_renderer": [],
"//conditions:default": MLN_GENERATED_OPENGL_SHADER_HEADERS,
}),
visibility = ["//visibility:public"],
deps = [
":generated_shaders",
@@ -79,23 +89,32 @@ cc_library(
cc_library(
name = "mbgl-core",
srcs = MLN_CORE_SOURCE +
MLN_GENERATED_STYLE_SOURCE +
MLN_OPENGL_SOURCE + select({
":drawable_renderer": MLN_DRAWABLES_SOURCE,
"//conditions:default": [],
}),
hdrs = MLN_CORE_HEADERS +
MLN_OPENGL_HEADERS + select({
":drawable_renderer": MLN_DRAWABLES_HEADERS,
"//conditions:default": [],
}),
MLN_GENERATED_STYLE_SOURCE + select({
":drawable_renderer": MLN_OPENGL_SOURCE + MLN_DRAWABLES_SOURCE + MLN_DRAWABLES_GL_SOURCE,
":legacy_renderer": MLN_OPENGL_SOURCE,
":metal_renderer": MLN_DRAWABLES_SOURCE + MLN_DRAWABLES_MTL_SOURCE,
"//conditions:default": [],
}),
hdrs = MLN_CORE_HEADERS + select({
":drawable_renderer": MLN_OPENGL_HEADERS + MLN_DRAWABLES_HEADERS + MLN_DRAWABLES_GL_HEADERS,
":legacy_renderer": MLN_OPENGL_HEADERS,
":metal_renderer": MLN_DRAWABLES_HEADERS + MLN_DRAWABLES_MTL_HEADERS,
"//conditions:default": [],
}),
copts = CPP_FLAGS + MAPLIBRE_FLAGS,
defines = select({
":legacy_renderer": [
"MLN_RENDER_BACKEND_OPENGL=1",
"MLN_LEGACY_RENDERER=1",
"MLN_DRAWABLE_RENDERER=0",
],
":drawable_renderer": [
"MLN_RENDER_BACKEND_OPENGL=1",
"MLN_LEGACY_RENDERER=0",
"MLN_DRAWABLE_RENDERER=1",
],
":metal_renderer": [
"MLN_RENDER_BACKEND_METAL=1",
"MLN_LEGACY_RENDERER=0",
"MLN_DRAWABLE_RENDERER=1",
],
@@ -106,7 +125,12 @@ cc_library(
includes = [
"include",
"src",
],
] + select({
":metal_renderer": [
"vendor/metal-cpp",
],
"//conditions:default": [],
}),
local_defines = [
r"MLN_VERSION_REV=\"standalone\"",
],
@@ -130,6 +154,11 @@ cc_library(
"//vendor:icu",
],
"//conditions:default": [],
}) + select({
":metal_renderer": [
"//vendor:metal-cpp",
],
"//conditions:default": [],
}),
)
@@ -180,10 +209,11 @@ config_setting(
string_flag(
name = "renderer",
build_setting_default = "legacy",
values = [
values=[
"legacy",
"drawable",
],
"metal"
]
)
config_setting(
@@ -200,6 +230,13 @@ config_setting(
},
)
config_setting(
name = "metal_renderer",
flag_values = {
":renderer": "metal"
}
)
exports_files(
[
"LICENSE.md",

View File

@@ -152,7 +152,6 @@ if(MLN_DRAWABLE_RENDERER)
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/layer_tweaker.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/render_target.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/shader_program_base.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_program_mtl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/util/identity.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/util/suppress_copies.hpp
@@ -174,7 +173,7 @@ if(MLN_DRAWABLE_RENDERER)
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_custom_layer_host_tweaker.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/hillshade_prepare_drawable_data.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/image_drawable_data.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/line_drawable_data.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/line_drawable_data.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/symbol_drawable_data.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/collision_drawable_data.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/uniform_block.cpp
@@ -211,7 +210,6 @@ if(MLN_DRAWABLE_RENDERER)
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/collision_layer_tweaker.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/collision_layer_tweaker.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/shader_program_base.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/shader_program_mtl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/util/identity.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/shader_program_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl.cpp
@@ -979,10 +977,10 @@ if(MLN_WITH_OPENGL)
target_compile_definitions(
mbgl-core
PRIVATE
MBGL_RENDER_BACKEND_OPENGL=1
PRIVATE MLN_RENDER_BACKEND_OPENGL=1
PUBLIC
"MLN_LEGACY_RENDERER=$<BOOL:${MLN_LEGACY_RENDERER}>"
"MLN_DRAWABLE_RENDERER=$<BOOL:${MLN_DRAWABLE_RENDERER}>"
"MLN_DRAWABLE_RENDERER=$<BOOL:${MLN_DRAWABLE_RENDERER}>"
)
list(APPEND
INCLUDE_FILES
@@ -1109,6 +1107,38 @@ if(MLN_WITH_OPENGL)
${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/location_indicator_layer_properties.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/location_indicator_layer_properties.hpp
)
if(MLN_DRAWABLE_RENDERER)
list(APPEND INCLUDE_FILES
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/background_layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/circle_layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/fill_layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/line_layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/raster_layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/shader_program_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl_builder.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/layer_group_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/render_target_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/uniform_block_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/uniform_buffer_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/vertex_attribute_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/texture2d.hpp
)
list(APPEND SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/gl/render_target_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/shader_program_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_builder.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_impl.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/layer_group_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/texture2d.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform_block_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform_buffer_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_attribute_gl.cpp
)
endif()
endif()
if(MBGL_WITH_METAL)
@@ -1119,15 +1149,54 @@ if(MBGL_WITH_METAL)
)
list(APPEND
INCLUDE_FILES
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable_mtl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable_mtl_builder.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable_mtl_tweaker.hpp
)
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/buffer_resource.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/command_encoder.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/context.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/layer_group.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable_builder.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable_tweaker.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/index_buffer_resource.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/mtl_fwd.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/texture2d.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/tile_layer_group.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/uniform_block.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/uniform_buffer.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/upload_pass.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/vertex_attribute.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/vertex_buffer_resource.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_program.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/background.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/background_pattern.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/circle.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/common.hpp
)
list(APPEND
SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_mtl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_mtl_builder.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_mtl_tweaker.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/buffer_resource.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/command_encoder.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/context.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_impl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_builder.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_tweaker.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/layer_group.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/mtl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/texture2d.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/tile_layer_group.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/uniform_block.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/uniform_buffer.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/upload_pass.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/vertex_attribute.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/shader_program.cpp
)
endif()
if(MBGL_WITH_METAL)
message(STATUS "Configuring Metal renderer backend")
target_compile_definitions(
mbgl-core
PRIVATE MBGL_RENDER_BACKEND_METAL=1
)
endif()

View File

@@ -52,6 +52,9 @@ MLN_GENERATED_STYLE_SOURCE = [
MLN_GENERATED_SHADER_HEADERS = [
"include/mbgl/shaders/shader_source.hpp",
"include/mbgl/shaders/shader_manifest.hpp",
]
MLN_GENERATED_OPENGL_SHADER_HEADERS = [
"include/mbgl/shaders/gl/background.hpp",
"include/mbgl/shaders/gl/background_pattern.hpp",
"include/mbgl/shaders/gl/circle.hpp",
@@ -137,6 +140,7 @@ MLN_CORE_SOURCE = [
"src/mbgl/geometry/line_atlas.hpp",
"src/mbgl/gfx/attribute.cpp",
"src/mbgl/gfx/attribute.hpp",
"include/mbgl/gfx/backend.hpp",
"src/mbgl/gfx/color_mode.hpp",
"src/mbgl/gfx/command_encoder.hpp",
"src/mbgl/gfx/context.hpp",
@@ -163,6 +167,7 @@ MLN_CORE_SOURCE = [
"src/mbgl/gfx/vertex_vector.hpp",
"src/mbgl/layermanager/background_layer_factory.cpp",
"src/mbgl/layermanager/circle_layer_factory.cpp",
"src/mbgl/layermanager/custom_layer_factory.cpp",
"src/mbgl/layermanager/fill_extrusion_layer_factory.cpp",
"src/mbgl/layermanager/fill_layer_factory.cpp",
"src/mbgl/layermanager/heatmap_layer_factory.cpp",
@@ -284,6 +289,8 @@ MLN_CORE_SOURCE = [
"src/mbgl/renderer/layers/render_background_layer.hpp",
"src/mbgl/renderer/layers/render_circle_layer.cpp",
"src/mbgl/renderer/layers/render_circle_layer.hpp",
"src/mbgl/renderer/layers/render_custom_layer.cpp",
"src/mbgl/renderer/layers/render_custom_layer.hpp",
"src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp",
"src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp",
"src/mbgl/renderer/layers/render_fill_layer.cpp",
@@ -441,6 +448,9 @@ MLN_CORE_SOURCE = [
"src/mbgl/style/layers/background_layer_impl.hpp",
"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_impl.cpp",
"src/mbgl/style/layers/custom_layer_impl.hpp",
"src/mbgl/style/layers/fill_extrusion_layer_impl.cpp",
"src/mbgl/style/layers/fill_extrusion_layer_impl.hpp",
"src/mbgl/style/layers/fill_layer_impl.cpp",
@@ -451,6 +461,8 @@ MLN_CORE_SOURCE = [
"src/mbgl/style/layers/hillshade_layer_impl.hpp",
"src/mbgl/style/layers/line_layer_impl.cpp",
"src/mbgl/style/layers/line_layer_impl.hpp",
"src/mbgl/style/layers/location_indicator_layer_impl.cpp",
"src/mbgl/style/layers/location_indicator_layer_impl.hpp",
"src/mbgl/style/layers/raster_layer_impl.cpp",
"src/mbgl/style/layers/raster_layer_impl.hpp",
"src/mbgl/style/layers/symbol_layer_impl.cpp",
@@ -653,6 +665,7 @@ MLN_CORE_HEADERS = [
"include/mbgl/i18n/number_format.hpp",
"include/mbgl/layermanager/background_layer_factory.hpp",
"include/mbgl/layermanager/circle_layer_factory.hpp",
"include/mbgl/layermanager/custom_layer_factory.hpp",
"include/mbgl/layermanager/fill_extrusion_layer_factory.hpp",
"include/mbgl/layermanager/fill_layer_factory.hpp",
"include/mbgl/layermanager/heatmap_layer_factory.hpp",
@@ -757,6 +770,7 @@ MLN_CORE_HEADERS = [
"include/mbgl/style/image.hpp",
"include/mbgl/style/layer.hpp",
"include/mbgl/style/layer_properties.hpp",
"include/mbgl/style/layers/custom_layer.hpp",
"include/mbgl/style/position.hpp",
"include/mbgl/style/property_expression.hpp",
"include/mbgl/style/property_value.hpp",
@@ -832,10 +846,6 @@ MLN_OPENGL_SOURCE = [
"src/mbgl/gl/command_encoder.hpp",
"src/mbgl/gl/context.cpp",
"src/mbgl/gl/context.hpp",
"src/mbgl/style/layers/custom_layer.cpp",
"src/mbgl/layermanager/custom_layer_factory.cpp",
"src/mbgl/style/layers/custom_layer_impl.cpp",
"src/mbgl/style/layers/custom_layer_impl.hpp",
"src/mbgl/gl/debugging_extension.cpp",
"src/mbgl/gl/debugging_extension.hpp",
"src/mbgl/gl/defines.hpp",
@@ -851,8 +861,6 @@ MLN_OPENGL_SOURCE = [
"src/mbgl/gl/offscreen_texture.cpp",
"src/mbgl/gl/offscreen_texture.hpp",
"src/mbgl/gl/program.hpp",
"src/mbgl/renderer/layers/render_custom_layer.cpp",
"src/mbgl/renderer/layers/render_custom_layer.hpp",
"src/mbgl/gl/render_pass.cpp",
"src/mbgl/gl/render_pass.hpp",
"src/mbgl/gl/renderbuffer_resource.hpp",
@@ -877,14 +885,10 @@ MLN_OPENGL_SOURCE = [
"src/mbgl/platform/gl_functions.cpp",
"src/mbgl/renderer/layers/render_location_indicator_layer.cpp",
"src/mbgl/renderer/layers/render_location_indicator_layer.hpp",
"src/mbgl/style/layers/location_indicator_layer_impl.cpp",
"src/mbgl/style/layers/location_indicator_layer_impl.hpp",
]
MLN_OPENGL_HEADERS = [
"include/mbgl/gfx/backend.hpp",
"include/mbgl/style/layers/custom_layer.hpp",
"include/mbgl/layermanager/custom_layer_factory.hpp",
"include/mbgl/gl/renderable_resource.hpp",
"include/mbgl/gl/renderer_backend.hpp",
"include/mbgl/layermanager/location_indicator_layer_factory.hpp",
@@ -935,18 +939,7 @@ MLN_DRAWABLES_SOURCE = [
"src/mbgl/renderer/layers/collision_layer_tweaker.cpp",
"src/mbgl/renderer/layers/collision_layer_tweaker.hpp",
"src/mbgl/shaders/shader_program_base.cpp",
"src/mbgl/shaders/mtl/shader_program_mtl.cpp",
"src/mbgl/shaders/gl/shader_program_gl.cpp",
"src/mbgl/util/identity.cpp",
"src/mbgl/gl/drawable_gl.cpp",
"src/mbgl/gl/drawable_gl_builder.cpp",
"src/mbgl/gl/drawable_gl_impl.hpp",
"src/mbgl/gl/layer_group_gl.cpp",
"src/mbgl/gl/render_target_gl.cpp",
"src/mbgl/gl/texture2d.cpp",
"src/mbgl/gl/uniform_block_gl.cpp",
"src/mbgl/gl/uniform_buffer_gl.cpp",
"src/mbgl/gl/vertex_attribute_gl.cpp"
]
MLN_DRAWABLES_HEADERS = [
@@ -965,12 +958,30 @@ MLN_DRAWABLES_HEADERS = [
"include/mbgl/renderer/layer_group.hpp",
"include/mbgl/renderer/layer_tweaker.hpp",
"include/mbgl/renderer/render_target.hpp",
"include/mbgl/shaders/background_layer_ubo.hpp",
"include/mbgl/shaders/circle_layer_ubo.hpp",
"include/mbgl/shaders/fill_layer_ubo.hpp",
"include/mbgl/shaders/layer_ubo.hpp",
"include/mbgl/shaders/line_layer_ubo.hpp",
"include/mbgl/shaders/raster_layer_ubo.hpp",
"include/mbgl/shaders/shader_program_base.hpp",
"include/mbgl/shaders/mtl/shader_program_mtl.hpp",
"include/mbgl/util/identity.hpp",
"include/mbgl/util/suppress_copies.hpp",
"include/mbgl/shaders/gl/shader_program_gl.hpp",
"include/mbgl/shaders/gl/shader_group_gl.hpp",
]
MLN_DRAWABLES_GL_SOURCE = [
"src/mbgl/gl/drawable_gl.cpp",
"src/mbgl/gl/drawable_gl_builder.cpp",
"src/mbgl/gl/drawable_gl_impl.hpp",
"src/mbgl/gl/layer_group_gl.cpp",
"src/mbgl/gl/render_target_gl.cpp",
"src/mbgl/gl/texture2d.cpp",
"src/mbgl/gl/uniform_block_gl.cpp",
"src/mbgl/gl/uniform_buffer_gl.cpp",
"src/mbgl/gl/vertex_attribute_gl.cpp",
"src/mbgl/shaders/gl/shader_program_gl.cpp",
]
MLN_DRAWABLES_GL_HEADERS = [
"include/mbgl/gl/drawable_gl.hpp",
"include/mbgl/gl/drawable_gl_builder.hpp",
"include/mbgl/gl/layer_group_gl.hpp",
@@ -978,5 +989,58 @@ MLN_DRAWABLES_HEADERS = [
"include/mbgl/gl/uniform_block_gl.hpp",
"include/mbgl/gl/uniform_buffer_gl.hpp",
"include/mbgl/gl/vertex_attribute_gl.hpp",
"include/mbgl/gl/texture2d.hpp"
"include/mbgl/gl/texture2d.hpp",
"include/mbgl/shaders/gl/shader_program_gl.hpp",
"include/mbgl/shaders/gl/shader_group_gl.hpp"
]
MLN_DRAWABLES_MTL_SOURCE = [
"src/mbgl/mtl/buffer_resource.cpp",
"src/mbgl/mtl/command_encoder.cpp",
"src/mbgl/mtl/context.cpp",
"src/mbgl/mtl/drawable.cpp",
"src/mbgl/mtl/drawable_impl.hpp",
"src/mbgl/mtl/drawable_builder.cpp",
"src/mbgl/mtl/layer_group.cpp",
"src/mbgl/mtl/mtl.cpp",
"src/mbgl/mtl/renderer_backend.cpp",
"src/mbgl/mtl/texture2d.cpp",
"src/mbgl/mtl/render_pass.cpp",
"src/mbgl/mtl/tile_layer_group.cpp",
"src/mbgl/mtl/uniform_block.cpp",
"src/mbgl/mtl/uniform_buffer.cpp",
"src/mbgl/mtl/upload_pass.cpp",
"src/mbgl/mtl/vertex_attribute.cpp",
"src/mbgl/shaders/mtl/shader_program.cpp",
]
MLN_DRAWABLES_MTL_HEADERS = [
"include/mbgl/mtl/buffer_resource.hpp",
"include/mbgl/mtl/command_encoder.hpp",
"include/mbgl/mtl/context.hpp",
"include/mbgl/mtl/drawable.hpp",
"include/mbgl/mtl/drawable_builder.hpp",
"include/mbgl/mtl/index_buffer_resource.hpp",
"include/mbgl/mtl/layer_group.hpp",
"include/mbgl/mtl/mtl_fwd.hpp",
"include/mbgl/mtl/render_pass.hpp",
"include/mbgl/mtl/renderer_backend.hpp",
"include/mbgl/mtl/renderable_resource.hpp",
"include/mbgl/mtl/texture2d.hpp",
"include/mbgl/mtl/tile_layer_group.hpp",
"include/mbgl/mtl/uniform_block.hpp",
"include/mbgl/mtl/uniform_buffer.hpp",
"include/mbgl/mtl/upload_pass.hpp",
"include/mbgl/mtl/vertex_attribute.hpp",
"include/mbgl/mtl/vertex_buffer_resource.hpp",
"include/mbgl/shaders/mtl/background.hpp",
"include/mbgl/shaders/mtl/background_pattern.hpp",
"include/mbgl/shaders/mtl/circle.hpp",
"include/mbgl/shaders/mtl/common.hpp",
"include/mbgl/shaders/mtl/line.hpp",
"include/mbgl/shaders/mtl/fill.hpp",
"include/mbgl/shaders/mtl/line_gradient.hpp",
"include/mbgl/shaders/mtl/raster.hpp",
"include/mbgl/shaders/mtl/shader_group.hpp",
"include/mbgl/shaders/mtl/shader_program.hpp",
]

View File

@@ -61,3 +61,7 @@ target_link_libraries(
)
set_property(TARGET mbgl-benchmark PROPERTY FOLDER Core)
if(MLN_WITH_OPENGL)
target_compile_definitions(mbgl-benchmark PRIVATE "MLN_RENDER_BACKEND_OPENGL=1")
endif()

View File

@@ -56,3 +56,7 @@ install(TARGETS mbgl-offline mbgl-render RUNTIME DESTINATION bin)
# ${PROJECT_SOURCE_DIR} )
#
# add_test(NAME mbgl-render-tool-test COMMAND mbgl-render WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} )
if(MLN_WITH_OPENGL)
target_compile_definitions(mbgl-render PRIVATE "MLN_RENDER_BACKEND_OPENGL=1")
endif()

View File

@@ -12,11 +12,16 @@ public:
/// @brief The active graphics API/backend type.
enum class Type : uint8_t {
OpenGL, ///< The OpenGL API backend
Metal, ///< The Metal API backend
TYPE_MAX, ///< Not a valid backend type, used to determine the number
///< of available backends (ie for array allocation).
};
#if MLN_RENDER_BACKEND_METAL
static constexpr Type DefaultType = Type::Metal;
#else // assume MLN_RENDER_BACKEND_METAL
static constexpr Type DefaultType = Type::OpenGL;
#endif
static void SetType(const Type value) {
if (Value(value) != value) {

View File

@@ -1,12 +1,12 @@
#pragma once
#include <mbgl/gfx/drawable_data.hpp>
#include <mbgl/gfx/texture2d.hpp>
#include <mbgl/gfx/uniform_buffer.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/util/color.hpp>
#include <mbgl/util/identity.hpp>
#include <mbgl/util/traits.hpp>
#include <mbgl/gfx/texture2d.hpp>
#include <mbgl/gfx/drawable_data.hpp>
#include <cstdint>
#include <cstddef>

View File

@@ -9,6 +9,11 @@ namespace mbgl {
namespace gfx {
class Context;
class UniformBuffer;
class UniformBufferArray;
using UniqueUniformBuffer = std::unique_ptr<UniformBuffer>;
using UniqueUniformBufferArray = std::unique_ptr<UniformBufferArray>;
class UniformBuffer {
// Can only be created by platform specific implementations
@@ -74,7 +79,7 @@ public:
protected:
const std::shared_ptr<UniformBuffer>& add(const std::string_view name, std::shared_ptr<UniformBuffer>&&);
virtual std::unique_ptr<UniformBuffer> copy(const UniformBuffer& uniformBuffer) = 0;
virtual std::unique_ptr<UniformBuffer> copy(const UniformBuffer&) = 0;
protected:
UniformBufferMap uniformBufferMap;

View File

@@ -27,8 +27,13 @@ using mat4 = std::array<double, 4 * 4>;
namespace gfx {
class ShaderProgramBase;
class VertexAttribute;
class VertexAttributeArray;
class VertexVectorBase;
using UniqueVertexAttribute = std::unique_ptr<VertexAttribute>;
using UniqueVertexAttributeArray = std::unique_ptr<VertexAttributeArray>;
class VertexAttribute {
public:
/// type for vector of 2 floats
@@ -71,11 +76,12 @@ public:
/// @param stride_ the vertex attribute stride
VertexAttribute(int index_, AttributeDataType dataType_, std::size_t count_, std::size_t stride_)
: index(index_),
stride((int)stride_),
stride(stride_),
dataType(dataType_),
items(count_) {}
VertexAttribute(const VertexAttribute& other)
: index(other.index),
stride(other.stride),
dataType(other.dataType),
items(other.items),
sharedRawData(other.sharedRawData),
@@ -85,6 +91,7 @@ public:
sharedStride(other.sharedStride) {}
VertexAttribute(VertexAttribute&& other)
: index(other.index),
stride(other.stride),
dataType(other.dataType),
items(std::move(other.items)),
sharedRawData(std::move(other.sharedRawData)),
@@ -104,6 +111,7 @@ public:
/// @brief Get the stride of the vertex attribute
std::size_t getStride() const { return stride; }
void setStride(std::size_t value) { stride = value; }
/// @brief Get the count of vertex attribute items
std::size_t getCount() const;
@@ -188,6 +196,7 @@ public:
/// Get the vertex attribute's raw data
std::vector<std::uint8_t>& getRawData() { return rawData; }
const std::vector<std::uint8_t>& getRawData() const { return rawData; }
void setRawData(std::vector<std::uint8_t> value) { rawData = std::move(value); }
/// Get the vertex attribute's shared raw data
const std::shared_ptr<VertexVectorBase>& getSharedRawData() const { return sharedRawData; }
@@ -225,8 +234,11 @@ public:
/// @brief Clears the shared data
void resetSharedRawData() { sharedRawData.reset(); }
const gfx::UniqueVertexBufferResource& getBuffer() const { return buffer; }
void setBuffer(gfx::UniqueVertexBufferResource&& value) { buffer = std::move(value); }
protected:
VertexAttribute& operator=(const VertexAttribute&) = default;
VertexAttribute& operator=(const VertexAttribute&) = delete;
VertexAttribute& operator=(VertexAttribute&& other) {
index = other.index;
dataType = other.dataType;
@@ -236,7 +248,7 @@ protected:
protected:
int index;
int stride;
std::size_t stride;
/// indicates that a value has changed and any cached result should be discarded
mutable bool dirty = true;
@@ -252,6 +264,8 @@ protected:
uint32_t sharedOffset = 0;
uint32_t sharedVertexOffset = 0;
uint32_t sharedStride = 0;
gfx::UniqueVertexBufferResource buffer;
};
/// Stores a collection of vertex attributes by name
@@ -276,15 +290,15 @@ public:
/// Add a new attribute element.
/// Returns a pointer to the new element on success, or null if the attribute already exists.
/// The result is valid only until the next non-const method call on this class.
const std::unique_ptr<VertexAttribute>& get(const std::string& name) const;
const UniqueVertexAttribute& get(const std::string& name) const;
/// Add a new attribute element.
/// Returns a pointer to the new element on success, or null if the attribute already exists.
/// The result is valid only until the next non-const method call on this class.
const std::unique_ptr<VertexAttribute>& add(std::string name,
int index = -1,
AttributeDataType = AttributeDataType::Invalid,
std::size_t count = 1);
const UniqueVertexAttribute& add(std::string name,
int index = -1,
AttributeDataType = AttributeDataType::Invalid,
std::size_t count = 1);
/// Add a new attribute element if it doesn't already exist.
/// Returns a pointer to the new element on success, or null if the type or count conflict with an existing entry.
@@ -292,10 +306,10 @@ public:
/// @param index index to match, or -1 for any
/// @param type type to match, or `Invalid` for any
/// @param count type to match, or 0 for any
const std::unique_ptr<VertexAttribute>& getOrAdd(std::string name,
int index = -1,
AttributeDataType type = AttributeDataType::Invalid,
std::size_t count = 0);
const UniqueVertexAttribute& getOrAdd(std::string name,
int index = -1,
AttributeDataType type = AttributeDataType::Invalid,
std::size_t count = 0);
// Set a value if the element is present
template <typename T>
@@ -333,8 +347,7 @@ public:
});
}
using ResolveDelegate =
std::function<void(const std::string&, VertexAttribute&, const std::unique_ptr<VertexAttribute>&)>;
using ResolveDelegate = std::function<void(const std::string&, VertexAttribute&, const UniqueVertexAttribute&)>;
/// Call the provided delegate with each value, providing the override if one exists.
void resolve(const VertexAttributeArray& overrides, ResolveDelegate) const;
@@ -342,7 +355,7 @@ public:
VertexAttributeArray& operator=(const VertexAttributeArray&);
/// Clone the collection
virtual std::unique_ptr<VertexAttributeArray> clone() const {
virtual UniqueVertexAttributeArray clone() const {
auto newAttrs = std::make_unique<VertexAttributeArray>();
newAttrs->copy(*this);
return newAttrs;
@@ -403,21 +416,13 @@ public:
}
protected:
const std::unique_ptr<VertexAttribute>& add(std::string name, std::unique_ptr<VertexAttribute>&& attr) {
const auto result = attrs.insert(std::make_pair(std::move(name), std::unique_ptr<VertexAttribute>()));
if (result.second) {
result.first->second = std::move(attr);
return result.first->second;
} else {
return nullref;
}
}
const UniqueVertexAttribute& add(std::string name, std::unique_ptr<VertexAttribute>&&);
virtual std::unique_ptr<VertexAttribute> create(int index, AttributeDataType dataType, std::size_t count) const {
virtual UniqueVertexAttribute create(int index, AttributeDataType dataType, std::size_t count) const {
return std::make_unique<VertexAttribute>(index, dataType, count, count);
}
virtual std::unique_ptr<VertexAttribute> copy(const gfx::VertexAttribute& attr) const {
virtual UniqueVertexAttribute copy(const gfx::VertexAttribute& attr) const {
return std::make_unique<VertexAttribute>(attr);
}

View File

@@ -0,0 +1,42 @@
#pragma once
#include <mbgl/gfx/vertex_buffer.hpp>
#include <mbgl/mtl/mtl_fwd.hpp>
#include <Foundation/NSSharedPtr.hpp>
#include <Metal/MTLBuffer.hpp>
#include <Metal/MTLDevice.hpp>
namespace mbgl {
namespace mtl {
class BufferResource {
public:
BufferResource() = default;
/** @brief Create a new Metal buffer
@param device The Metal device on which to create the buffer.
@param raw Data to use for the contents of the new buffer. May be null.
@param size The minimum size of the new buffer. Must be non-zero.
@param usage A `MTL::ResourceOptions` value. Currently, only `ResourceStorageModeShared` is supported.
*/
BufferResource(MTLDevicePtr device, const void* raw, std::size_t size, MTL::ResourceOptions usage);
BufferResource(const BufferResource&);
BufferResource(BufferResource&&);
void update(const void* data, std::size_t size, std::size_t offset);
std::size_t getSizeInBytes() const { return buffer ? buffer->length() : 0; }
void* contents() const { return buffer ? buffer->contents() : nullptr; }
const MTLBufferPtr& getMetalBuffer() const { return buffer; }
operator bool() const { return buffer.operator bool(); }
protected:
MTLDevicePtr device;
MTLBufferPtr buffer;
NS::UInteger usage;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,73 @@
#pragma once
#include <mbgl/gfx/command_encoder.hpp>
#include <mbgl/mtl/mtl_fwd.hpp>
#include <functional>
#include <memory>
#include <string>
#include <unordered_set>
#include <vector>
namespace mbgl {
namespace gfx {
class Renderable;
} // namespace gfx
namespace mtl {
class Context;
class RenderPass;
class UploadPass;
class CommandEncoder final : public gfx::CommandEncoder {
public:
explicit CommandEncoder(Context& context_);
~CommandEncoder() override;
std::unique_ptr<gfx::UploadPass> createUploadPass(const char* name, gfx::Renderable&) override;
std::unique_ptr<gfx::RenderPass> createRenderPass(const char* name, const gfx::RenderPassDescriptor&) override;
void present(gfx::Renderable&) override;
template <typename TFunc>
void visitDebugGroups(TFunc f) {
for (const auto& item : debugGroupNames) {
f(item.name);
}
}
private:
friend class RenderPass;
friend class UploadPass;
// Track a RenderPass, propagating debug groups to it
void trackRenderPass(RenderPass*);
// Stop tracking a RenderPass
void forgetRenderPass(RenderPass*);
// Track an UploadPass, propagating debug groups to it
void trackUploadPass(UploadPass*);
// Stop tracking a RenderPass
void forgetUploadPass(UploadPass*);
void pushDebugGroup(const char* name) override;
void popDebugGroup() override;
protected:
struct GroupEntry {
std::string name;
std::size_t renderGroups;
std::size_t uploadGroups;
};
protected:
mtl::Context& context;
std::vector<GroupEntry> debugGroupNames;
std::vector<gfx::DebugGroup<gfx::RenderPass>> renderDebugGroups;
std::vector<gfx::DebugGroup<gfx::UploadPass>> uploadDebugGroups;
std::unordered_set<RenderPass*> renderPasses;
std::unordered_set<UploadPass*> uploadPasses;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,124 @@
#pragma once
#include <mbgl/gfx/texture.hpp>
#include <mbgl/gfx/draw_mode.hpp>
#include <mbgl/gfx/depth_mode.hpp>
#include <mbgl/gfx/stencil_mode.hpp>
#include <mbgl/gfx/color_mode.hpp>
#include <mbgl/gfx/texture2d.hpp>
#include <mbgl/gfx/context.hpp>
#include <mbgl/mtl/buffer_resource.hpp>
#include <mbgl/mtl/mtl_fwd.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <memory>
#include <unordered_map>
namespace mbgl {
class ProgramParameters;
namespace mtl {
class RendererBackend;
class ShaderProgram;
using UniqueShaderProgram = std::unique_ptr<ShaderProgram>;
class Context final : public gfx::Context {
public:
Context(RendererBackend&);
~Context() noexcept override;
Context(const Context&) = delete;
Context& operator=(const Context& other) = delete;
std::unique_ptr<gfx::CommandEncoder> createCommandEncoder() override;
gfx::RenderingStats& renderingStats() { return stats; }
const gfx::RenderingStats& renderingStats() const override { return stats; }
BufferResource createBuffer(const void* data, std::size_t size, gfx::BufferUsageType) const;
UniqueShaderProgram createProgram(std::string name,
std::string_view source,
std::string_view vertexName,
std::string_view fragmentName,
const ProgramParameters& programParameters,
const std::unordered_map<std::string, std::string>& additionalDefines);
MTLTexturePtr createMetalTexture(MTLTextureDescriptorPtr textureDescriptor) const;
MTLSamplerStatePtr createMetalSamplerState(MTLSamplerDescriptorPtr samplerDescriptor) const;
/*
Framebuffer createFramebuffer(const gfx::Renderbuffer<gfx::RenderbufferPixelType::RGBA>&,
const gfx::Renderbuffer<gfx::RenderbufferPixelType::DepthStencil>&);
Framebuffer createFramebuffer(const gfx::Renderbuffer<gfx::RenderbufferPixelType::RGBA>&);
Framebuffer createFramebuffer(const gfx::Texture&,
const gfx::Renderbuffer<gfx::RenderbufferPixelType::DepthStencil>&);
Framebuffer createFramebuffer(const gfx::Texture&);
Framebuffer createFramebuffer(const gfx::Texture&, const gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&);
template <typename Image,
gfx::TexturePixelType format = Image::channels == 4 ? gfx::TexturePixelType::RGBA
: gfx::TexturePixelType::Alpha>
Image readFramebuffer(const Size size, bool flip = true) {
static_assert(Image::channels == (format == gfx::TexturePixelType::RGBA ? 4 : 1), "image format mismatch");
return {size, readFramebuffer(size, format, flip)};
}
*/
// Actually remove the objects we marked as abandoned with the above methods.
void performCleanup() override {}
void reduceMemoryUsage() override {}
gfx::UniqueDrawableBuilder createDrawableBuilder(std::string name) override;
gfx::UniformBufferPtr createUniformBuffer(const void* data, std::size_t size) override;
gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) override;
TileLayerGroupPtr createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) override;
LayerGroupPtr createLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) override;
gfx::Texture2DPtr createTexture2D() override;
RenderTargetPtr createRenderTarget(const Size size, const gfx::TextureChannelDataType type) override;
// UniqueFramebuffer createFramebuffer(const gfx::Texture2D& color);
void resetState(gfx::DepthMode depthMode, gfx::ColorMode colorMode) override;
void setDirtyState() override;
std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(Size, gfx::TextureChannelDataType) override;
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,
gfx::TexturePixelType,
gfx::TextureChannelDataType) override;
std::unique_ptr<gfx::RenderbufferResource> createRenderbufferResource(gfx::RenderbufferPixelType,
Size size) override;
std::unique_ptr<gfx::DrawScopeResource> createDrawScopeResource() override;
/*
UniqueFramebuffer createFramebuffer();
std::unique_ptr<uint8_t[]> readFramebuffer(Size, gfx::TexturePixelType, bool flip);
*/
#if !defined(NDEBUG)
void visualizeStencilBuffer() override;
void visualizeDepthBuffer(float depthRangeSize) override;
#endif
void clearStencilBuffer(int32_t) override;
private:
RendererBackend& backend;
bool cleanupOnDestruction = true;
gfx::RenderingStats stats;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,78 @@
#pragma once
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/gfx/draw_mode.hpp>
#include <mbgl/mtl/upload_pass.hpp>
#include <mbgl/programs/segment.hpp>
#include <memory>
namespace mbgl {
template <class AttributeList>
class Segment;
namespace gfx {
class IndexBuffer;
class UploadPass;
class VertexBufferResource;
using UniqueVertexBufferResource = std::unique_ptr<VertexBufferResource>;
} // namespace gfx
namespace mtl {
class RenderPass;
class Texture2D;
class VertexArray;
class Drawable : public gfx::Drawable {
public:
Drawable(std::string name);
~Drawable() override;
void draw(PaintParameters&) const override;
struct DrawSegment;
void setIndexData(gfx::IndexVectorBasePtr, std::vector<UniqueDrawSegment> segments) override;
void setVertices(std::vector<uint8_t>&&, std::size_t, gfx::AttributeDataType) override;
const gfx::VertexAttributeArray& getVertexAttributes() const override;
void setVertexAttributes(const gfx::VertexAttributeArray& value) override;
void setVertexAttributes(gfx::VertexAttributeArray&& value) override;
gfx::VertexAttributeArray& mutableVertexAttributes() override;
const gfx::UniformBufferArray& getUniformBuffers() const override;
gfx::UniformBufferArray& mutableUniformBuffers() override;
void setVertexAttrName(std::string);
void upload(gfx::UploadPass&);
protected:
// For testing only.
Drawable(std::unique_ptr<Impl>);
void bindAttributes(const RenderPass& renderPass) const;
void unbindAttributes(const RenderPass& renderPass) const;
void bindUniformBuffers(const RenderPass& renderPass) const;
void unbindUniformBuffers(const RenderPass& renderPass) const;
void bindTextures(const RenderPass& renderPass) const;
void unbindTextures(const RenderPass& renderPass) const;
void uploadTextures() const;
class Impl;
const std::unique_ptr<Impl> impl;
gfx::AttributeBindingArray attributeBindings;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,28 @@
#pragma once
#include <mbgl/gfx/drawable_builder.hpp>
namespace mbgl {
namespace mtl {
/**
Base class for Metal-specific drawable builders.
*/
class DrawableBuilder final : public gfx::DrawableBuilder {
public:
DrawableBuilder(std::string name_)
: gfx::DrawableBuilder(std::move(name_)) {}
~DrawableBuilder() override = default;
using DrawSegment = gfx::Drawable::DrawSegment;
std::unique_ptr<DrawSegment> createSegment(gfx::DrawMode, SegmentBase&&) override;
protected:
gfx::UniqueDrawable createDrawable() const override;
/// Setup the SDK-specific aspects after all the values are present
void init() override;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,27 @@
#pragma once
#include <mbgl/mtl/buffer_resource.hpp>
namespace mbgl {
namespace mtl {
class IndexBufferResource : public gfx::IndexBufferResource {
public:
IndexBufferResource() = default;
IndexBufferResource(BufferResource&& ptr)
: buffer(std::move(ptr)) {}
IndexBufferResource(IndexBufferResource&& other)
: buffer(std::move(other.buffer)) {}
std::size_t getSizeInBytes() const { return buffer.getSizeInBytes(); }
void* contents() const { return buffer.contents(); }
BufferResource& get() { return buffer; }
const BufferResource& get() const { return buffer; }
protected:
BufferResource buffer;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,23 @@
#pragma once
#include <mbgl/renderer/layer_group.hpp>
namespace mbgl {
namespace mtl {
/**
A layer group for non-tile-based drawables
*/
class LayerGroup : public mbgl::LayerGroup {
public:
LayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name);
~LayerGroup() override {}
void upload(gfx::UploadPass&) override;
void render(RenderOrchestrator&, PaintParameters&) override;
protected:
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,60 @@
#pragma once
// Forward-declarations for metal-cpp types, allowing
// references without including any third-party headers
#include <memory>
namespace CA {
class MetalDrawable;
} // namespace CA
namespace NS {
template <class T>
class SharedPtr;
using UInteger = std::uintptr_t;
} // namespace NS
namespace MTL {
class BlitCommandEncoder;
class BlitPassDescriptor;
class Buffer;
class CommandBuffer;
class CommandQueue;
class Device;
class Function;
class RenderCommandEncoder;
class RenderPipelineState;
class RenderPassDescriptor;
class Texture;
class TextureDescriptor;
class SamplerState;
class SamplerDescriptor;
class VertexAttributeDescriptor;
class VertexBufferLayoutDescriptor;
class VertexDescriptor;
} // namespace MTL
namespace mbgl {
namespace mtl {
using CAMetalDrawablePtr = NS::SharedPtr<CA::MetalDrawable>;
using MTLBlitCommandEncoderPtr = NS::SharedPtr<MTL::BlitCommandEncoder>;
using MTLBlitPassDescriptorPtr = NS::SharedPtr<MTL::BlitPassDescriptor>;
using MTLBufferPtr = NS::SharedPtr<MTL::Buffer>;
using MTLCommandBufferPtr = NS::SharedPtr<MTL::CommandBuffer>;
using MTLCommandQueuePtr = NS::SharedPtr<MTL::CommandQueue>;
using MTLDevicePtr = NS::SharedPtr<MTL::Device>;
using MTLFunctionPtr = NS::SharedPtr<MTL::Function>;
using MTLRenderCommandEncoderPtr = NS::SharedPtr<MTL::RenderCommandEncoder>;
using MTLRenderPassDescriptorPtr = NS::SharedPtr<MTL::RenderPassDescriptor>;
using MTLRenderPipelineStatePtr = NS::SharedPtr<MTL::RenderPipelineState>;
using MTLTexturePtr = NS::SharedPtr<MTL::Texture>;
using MTLTextureDescriptorPtr = NS::SharedPtr<MTL::TextureDescriptor>;
using MTLSamplerStatePtr = NS::SharedPtr<MTL::SamplerState>;
using MTLSamplerDescriptorPtr = NS::SharedPtr<MTL::SamplerDescriptor>;
using MTLVertexAttributeDescriptorPtr = NS::SharedPtr<MTL::VertexAttributeDescriptor>;
using MTLVertexBufferLayoutDescriptorPtr = NS::SharedPtr<MTL::VertexBufferLayoutDescriptor>;
using MTLVertexDescriptorPtr = NS::SharedPtr<MTL::VertexDescriptor>;
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,42 @@
#pragma once
#include <mbgl/gfx/render_pass.hpp>
#include <mbgl/mtl/mtl_fwd.hpp>
#include <Foundation/NSSharedPtr.hpp>
#include <Metal/MTLCommandEncoder.hpp>
#include <memory>
#include <optional>
namespace mbgl {
namespace mtl {
class CommandEncoder;
class Context;
class RenderPass final : public gfx::RenderPass {
public:
RenderPass(CommandEncoder&, const char* name, const gfx::RenderPassDescriptor&);
~RenderPass() override;
const MTLRenderCommandEncoderPtr& getMetalEncoder() const { return encoder; }
const gfx::RenderPassDescriptor& getDescriptor() const { return descriptor; }
void endEncoding();
void addDebugSignpost(const char* name) override;
private:
void pushDebugGroup(const char* name) override;
void popDebugGroup() override;
private:
gfx::RenderPassDescriptor descriptor;
mtl::CommandEncoder& commandEncoder;
MTLRenderCommandEncoderPtr encoder;
std::vector<gfx::DebugGroup<gfx::RenderPass>> debugGroups;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,30 @@
#pragma once
#include <mbgl/gfx/renderable.hpp>
#include <mbgl/mtl/mtl_fwd.hpp>
#include <cstdlib>
namespace mbgl {
namespace mtl {
class RendererBackend;
class RenderableResource : public gfx::RenderableResource {
protected:
explicit RenderableResource() = default;
public:
virtual void swap() {
// Renderable resources that require a swap function to be called
// explicitly can override this method.
}
virtual const mbgl::mtl::RendererBackend& getBackend() const = 0;
virtual const mbgl::mtl::MTLCommandBufferPtr& getCommandBuffer() const = 0;
virtual mbgl::mtl::MTLBlitPassDescriptorPtr getUploadPassDescriptor() const = 0;
virtual mbgl::mtl::MTLRenderPassDescriptorPtr getRenderPassDescriptor() const = 0;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,67 @@
#pragma once
#include <mbgl/gfx/renderer_backend.hpp>
#include <mbgl/mtl/mtl_fwd.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/size.hpp>
#include <mbgl/util/util.hpp>
#include <Foundation/NSSharedPtr.hpp>
#include <Metal/MTLDevice.hpp>
#include <Metal/MTLCommandQueue.hpp>
namespace mbgl {
class ProgramParameters;
namespace mtl {
using ProcAddress = void (*)();
using FramebufferID = uint32_t;
class RendererBackend : public gfx::RendererBackend {
public:
RendererBackend(gfx::ContextMode);
~RendererBackend() override;
/// Called prior to rendering to update the internally assumed MetalMetal state.
virtual void updateAssumedState() = 0;
/// One-time shader initialization
void initShaders(gfx::ShaderRegistry&, const ProgramParameters& programParameters) override;
const MTLDevicePtr& getDevice() const { return device; }
const MTLCommandQueuePtr& getCommandQueue() const { return commandQueue; }
protected:
std::unique_ptr<gfx::Context> createContext() override;
/// Reads the color pixel data from the currently bound framebuffer.
PremultipliedImage readFramebuffer(const Size&);
/// A constant to signal that a framebuffer is bound, but with an unknown ID.
static constexpr const FramebufferID ImplicitFramebufferBinding = std::numeric_limits<FramebufferID>::max();
/// Tells the renderer that the Metal state has already been set by the windowing toolkit.
/// It sets the internal assumed state to the supplied values.
void assumeFramebufferBinding(FramebufferID fbo);
void assumeViewport(int32_t x, int32_t y, const Size&);
void assumeScissorTest(bool);
/// Returns true when assumed framebuffer binding hasn't changed from the implicit binding.
bool implicitFramebufferBound();
public:
/// Triggers a Metal state update if the internal assumed state doesn't
/// match the supplied values.
void setFramebufferBinding(FramebufferID fbo);
void setViewport(int32_t x, int32_t y, const Size&);
void setScissorTest(bool);
protected:
MTLDevicePtr device;
MTLCommandQueuePtr commandQueue;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,78 @@
#pragma once
#include <mbgl/gfx/texture2d.hpp>
#include <mbgl/mtl/mtl_fwd.hpp>
#include <mbgl/util/image.hpp>
#include <Foundation/NSSharedPtr.hpp>
#include <Metal/MTLPixelFormat.hpp>
#include <memory>
namespace mbgl {
namespace mtl {
class Context;
class RenderPass;
class Texture2D : public gfx::Texture2D {
public:
Texture2D(Context& context_);
~Texture2D() override;
gfx::Texture2D& setSamplerConfiguration(const SamplerState&) noexcept override;
gfx::Texture2D& setFormat(gfx::TexturePixelType, gfx::TextureChannelDataType) noexcept override;
gfx::Texture2D& setSize(Size size_) noexcept override;
gfx::Texture2D& setImage(std::shared_ptr<PremultipliedImage>) noexcept override;
Size getSize() const noexcept override { return size; }
size_t getDataSize() const noexcept override;
size_t getPixelStride() const noexcept override;
size_t numChannels() const noexcept override;
void create() noexcept override;
void upload(const void* pixelData, const Size& size_) noexcept override;
void uploadSubRegion(const void* pixelData, const Size& size, uint16_t xOffset, uint16_t yOffset) noexcept override;
void upload() noexcept override;
bool needsUpload() const noexcept override { return !!image; };
void updateSamplerConfiguration() noexcept;
/// @brief Bind this texture to the specified location
/// @param renderPass Render pass on which the texture will be assign
/// @param location Location index of texture sampler in a shader
void bind(const RenderPass& renderPass, int32_t location) noexcept;
/// @brief Unbind the texture, if it was bound
/// @param renderPass Render pass from which the texture will be removed
/// @param location Location index of texture sampler in a shader
void unbind(const RenderPass& renderPass, int32_t location) noexcept;
private:
MTL::PixelFormat getMetalPixelFormat() const noexcept;
void createMetalTexture() noexcept;
Context& context;
MTLTexturePtr metalTexture;
MTLSamplerStatePtr metalSamplerState;
Size size{0, 0};
gfx::TexturePixelType pixelFormat{gfx::TexturePixelType::RGBA};
gfx::TextureChannelDataType channelType{gfx::TextureChannelDataType::UnsignedByte};
SamplerState samplerState{};
std::shared_ptr<PremultipliedImage> image{nullptr};
bool textureDirty{true};
bool samplerStateDirty{true};
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,23 @@
#pragma once
#include <mbgl/renderer/layer_group.hpp>
namespace mbgl {
namespace mtl {
/**
A layer group for tile-based drawables
*/
class TileLayerGroup : public mbgl::TileLayerGroup {
public:
TileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name);
~TileLayerGroup() override {}
void upload(gfx::UploadPass&) override;
void render(RenderOrchestrator&, PaintParameters&) override;
protected:
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,66 @@
#pragma once
#include <mbgl/gfx/uniform_block.hpp>
#include <mbgl/gfx/uniform_buffer.hpp>
namespace mbgl {
namespace mtl {
class UniformBlockArray;
class UniformBlock final : public gfx::UniformBlock {
// Can only be created by UniformBlockArray
private:
friend UniformBlockArray;
UniformBlock(int index_, std::size_t size_)
: gfx::UniformBlock(index_, size_) {}
UniformBlock(const UniformBlock& other)
: gfx::UniformBlock(other) {}
UniformBlock(UniformBlock&& other)
: gfx::UniformBlock(std::move(other)) {}
public:
void bindBuffer(const gfx::UniformBuffer& uniformBuffer) override;
void unbindBuffer() override;
bool getBindVertex() const { return bindVertex; }
void setBindVertex(bool value) { bindVertex = value; }
bool getBindFragment() const { return bindFragment; }
void setBindFragment(bool value) { bindFragment = value; }
protected:
bool bindVertex = false;
bool bindFragment = false;
};
/// Stores a collection of uniform blocks by name
class UniformBlockArray final : public gfx::UniformBlockArray {
public:
UniformBlockArray(int initCapacity = 10)
: gfx::UniformBlockArray(initCapacity) {}
UniformBlockArray(UniformBlockArray&& other)
: gfx::UniformBlockArray(std::move(other)) {}
UniformBlockArray(const UniformBlockArray&) = delete;
UniformBlockArray& operator=(UniformBlockArray&& other) {
gfx::UniformBlockArray::operator=(std::move(other));
return *this;
}
UniformBlockArray& operator=(const UniformBlockArray& other) {
gfx::UniformBlockArray::operator=(other);
return *this;
}
private:
std::unique_ptr<gfx::UniformBlock> create(int index, std::size_t size) override {
return std::unique_ptr<gfx::UniformBlock>(new UniformBlock(index, size));
}
std::unique_ptr<gfx::UniformBlock> copy(const gfx::UniformBlock& uniformBlocks) override {
return std::unique_ptr<gfx::UniformBlock>(new UniformBlock(static_cast<const UniformBlock&>(uniformBlocks)));
}
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,49 @@
#pragma once
#include <mbgl/gfx/uniform_buffer.hpp>
#include <mbgl/mtl/buffer_resource.hpp>
namespace mbgl {
namespace mtl {
class UniformBuffer final : public gfx::UniformBuffer {
public:
UniformBuffer(BufferResource&&);
UniformBuffer(const UniformBuffer&) = default;
UniformBuffer(UniformBuffer&&);
~UniformBuffer() override = default;
const BufferResource& getBufferResource() const { return buffer; }
void update(const void* data, std::size_t size_) override;
protected:
BufferResource buffer;
};
/// Stores a collection of uniform buffers by name
class UniformBufferArray final : public gfx::UniformBufferArray {
public:
UniformBufferArray(int initCapacity = 10)
: gfx::UniformBufferArray(initCapacity) {}
UniformBufferArray(UniformBufferArray&& other)
: gfx::UniformBufferArray(std::move(other)) {}
UniformBufferArray(const UniformBufferArray&) = delete;
UniformBufferArray& operator=(UniformBufferArray&& other) {
gfx::UniformBufferArray::operator=(std::move(other));
return *this;
}
UniformBufferArray& operator=(const UniformBufferArray& other) {
gfx::UniformBufferArray::operator=(other);
return *this;
}
private:
gfx::UniqueUniformBuffer copy(const gfx::UniformBuffer& buffer) override {
return std::make_unique<UniformBuffer>(static_cast<const UniformBuffer&>(buffer));
}
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,98 @@
#pragma once
#include <mbgl/gfx/index_buffer.hpp>
#include <mbgl/gfx/renderbuffer.hpp>
#include <mbgl/gfx/texture.hpp>
#include <mbgl/gfx/upload_pass.hpp>
#include <mbgl/gfx/vertex_buffer.hpp>
#include <mbgl/mtl/mtl_fwd.hpp>
#include <Foundation/NSSharedPtr.hpp>
#include <vector>
namespace mbgl {
namespace gfx {
class CommandEncoder;
class Renderable;
class VertexVectorBase;
using VertexVectorBasePtr = std::shared_ptr<VertexVectorBase>;
} // namespace gfx
namespace mtl {
class BufferResource;
class CommandEncoder;
class Context;
class VertexArray;
class Texture2D;
class RenderbufferResource : public gfx::RenderbufferResource {
public:
RenderbufferResource() = default;
};
class UploadPass final : public gfx::UploadPass {
public:
UploadPass(gfx::Renderable&, CommandEncoder&, const char* name);
~UploadPass() override;
gfx::Context& getContext() override;
const gfx::Context& getContext() const override;
std::unique_ptr<gfx::VertexBufferResource> createVertexBufferResource(const void* data,
std::size_t size,
gfx::BufferUsageType) override;
void updateVertexBufferResource(gfx::VertexBufferResource&, const void* data, std::size_t size) override;
std::unique_ptr<gfx::IndexBufferResource> createIndexBufferResource(const void* data,
std::size_t size,
gfx::BufferUsageType) override;
void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override;
void updateResource(BufferResource&, const void* data, std::size_t size);
const gfx::UniqueVertexBufferResource& getBuffer(const gfx::VertexVectorBasePtr&, gfx::BufferUsageType);
gfx::AttributeBindingArray buildAttributeBindings(
const std::size_t vertexCount,
const gfx::AttributeDataType vertexType,
const std::size_t vertexAttributeIndex,
const std::vector<std::uint8_t>& vertexData,
const gfx::VertexAttributeArray& defaults,
const gfx::VertexAttributeArray& overrides,
gfx::BufferUsageType,
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>& outBuffers) override;
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,
const void* data,
gfx::TexturePixelType,
gfx::TextureChannelDataType) override;
void updateTextureResource(
gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override;
void updateTextureResourceSub(gfx::TextureResource&,
uint16_t xOffset,
uint16_t yOffset,
Size,
const void* data,
gfx::TexturePixelType,
gfx::TextureChannelDataType) override;
private:
void pushDebugGroup(const char* name) override;
void popDebugGroup() override;
void endEncoding();
private:
CommandEncoder& commandEncoder;
MTLCommandBufferPtr buffer;
MTLBlitCommandEncoderPtr encoder;
std::vector<gfx::DebugGroup<gfx::UploadPass>> debugGroups;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,75 @@
#pragma once
#include <mbgl/gfx/types.hpp>
#include <mbgl/gfx/vertex_attribute.hpp>
namespace mbgl {
namespace gfx {
class VertexBufferResource;
} // namespace gfx
namespace mtl {
class VertexAttributeArray;
class UploadPass;
class VertexAttribute final : public gfx::VertexAttribute {
// Can only be created by VertexAttributeArray
private:
friend VertexAttributeArray;
VertexAttribute(int index_, gfx::AttributeDataType dataType_, std::size_t count_)
: gfx::VertexAttribute(index_, dataType_, count_, /*stride_=*/0) {}
VertexAttribute(const VertexAttribute& other)
: gfx::VertexAttribute(other) {}
VertexAttribute(VertexAttribute&& other)
: gfx::VertexAttribute(std::move(other)) {}
public:
~VertexAttribute() override = default;
/// Get the Metal buffer, creating it if necessary
// const gfx::UniqueVertexBufferResource& getBuffer(UploadPass&, const gfx::BufferUsageType);
static const gfx::UniqueVertexBufferResource& getBuffer(gfx::VertexAttribute&,
UploadPass&,
const gfx::BufferUsageType);
static std::size_t getStrideOf(gfx::AttributeDataType);
};
/// Stores a collection of vertex attributes by name
class VertexAttributeArray final : public gfx::VertexAttributeArray {
public:
VertexAttributeArray(int initCapacity = 10)
: gfx::VertexAttributeArray(initCapacity) {}
VertexAttributeArray(VertexAttributeArray&& other)
: gfx::VertexAttributeArray(std::move(other)) {}
VertexAttributeArray& operator=(VertexAttributeArray&& other) {
gfx::VertexAttributeArray::operator=(std::move(other));
return *this;
}
VertexAttributeArray& operator=(const VertexAttributeArray& other) {
gfx::VertexAttributeArray::operator=(other);
return *this;
}
gfx::UniqueVertexAttributeArray clone() const override {
auto newAttrs = std::make_unique<VertexAttributeArray>();
newAttrs->copy(*this);
return newAttrs;
}
private:
gfx::UniqueVertexAttribute create(int index, gfx::AttributeDataType dataType, std::size_t count) const override {
return gfx::UniqueVertexAttribute(new VertexAttribute(index, dataType, count));
}
using gfx::VertexAttributeArray::copy;
gfx::UniqueVertexAttribute copy(const gfx::VertexAttribute& attr) const override {
return gfx::UniqueVertexAttribute(new VertexAttribute(static_cast<const VertexAttribute&>(attr)));
}
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,27 @@
#pragma once
#include <mbgl/mtl/buffer_resource.hpp>
namespace mbgl {
namespace mtl {
class VertexBufferResource : public gfx::VertexBufferResource {
public:
VertexBufferResource() = default;
VertexBufferResource(BufferResource&& ptr)
: buffer(std::move(ptr)) {}
VertexBufferResource(VertexBufferResource&& other)
: buffer(std::move(other.buffer)) {}
std::size_t getSizeInBytes() const { return buffer.getSizeInBytes(); }
void* contents() const { return buffer.contents(); }
BufferResource& get() { return buffer; }
const BufferResource& get() const { return buffer; }
protected:
BufferResource buffer;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -4,12 +4,17 @@
#include <array>
#include <memory>
#include <string>
#include <vector>
namespace mbgl {
namespace gfx {
class UniformBuffer;
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
} // namespace gfx
namespace shaders {
struct ExpressionInputsUBO;
} // namespace shaders
namespace style {
class LayerProperties;
enum class TranslateAnchorType : bool;
@@ -27,12 +32,30 @@ using mat4 = std::array<double, 16>;
*/
class LayerTweaker {
protected:
LayerTweaker(Immutable<style::LayerProperties> properties);
LayerTweaker(std::string id, Immutable<style::LayerProperties> properties);
public:
LayerTweaker() = delete;
virtual ~LayerTweaker() = default;
const std::string& getID() const { return id; }
#if MLN_RENDER_BACKEND_METAL
/// Build the common expression inupts UBO
static shaders::ExpressionInputsUBO buildExpressionUBO(double zoom, uint64_t frameCount);
/// @brief Set the collection of attribute names which will be provided at uniform values rather than per-vertex
/// attributes.
/// @details These values should not have "a_" prefixes, as produced by `readDataDrivenPaintProperties`.
void setPropertiesAsUniforms(std::vector<std::string>);
/// @brief Check whether a property name exists within the previously set collection.
/// @details The string value provided is expected to have the "a_" prefix, as defined in the shader classes.
bool hasPropertyAsUniform(std::string_view) const;
#endif // MLN_RENDER_BACKEND_METAL
void enableOverdrawInspector(bool);
virtual void execute(LayerGroupBase&, const RenderTree&, const PaintParameters&) = 0;
protected:
@@ -49,7 +72,17 @@ protected:
bool aligned = false);
protected:
std::string id;
Immutable<style::LayerProperties> evaluatedProperties;
#if MLN_RENDER_BACKEND_METAL
// For Metal, whether a property is provided through attribtues or uniforms is specified in
// a uniform buffer rather than by a shader compiled with different preprocessor definitions.
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool propertiesChanged = true;
bool overdrawInspector = false;
};
} // namespace mbgl

View File

@@ -0,0 +1,44 @@
#pragma once
#include <mbgl/shaders/layer_ubo.hpp>
#include <memory>
namespace mbgl {
namespace shaders {
struct alignas(16) BackgroundDrawableUBO {
std::array<float, 4 * 4> matrix;
};
static_assert(sizeof(BackgroundDrawableUBO) % 16 == 0);
struct alignas(16) BackgroundLayerUBO {
/* 0 */ Color color;
/* 16 */ float opacity;
/* 20 */ float pad1, pad2, pad3;
/* 32 */
};
static_assert(sizeof(BackgroundLayerUBO) == 32);
struct alignas(16) BackgroundPatternLayerUBO {
/* 0 */ std::array<float, 2> pattern_tl_a;
/* 8 */ std::array<float, 2> pattern_br_a;
/* 16 */ std::array<float, 2> pattern_tl_b;
/* 24 */ std::array<float, 2> pattern_br_b;
/* 32 */ std::array<float, 2> texsize;
/* 40 */ std::array<float, 2> pattern_size_a;
/* 48 */ std::array<float, 2> pattern_size_b;
/* 56 */ std::array<float, 2> pixel_coord_upper;
/* 64 */ std::array<float, 2> pixel_coord_lower;
/* 72 */ float tile_units_to_pixels;
/* 76 */ float scale_a;
/* 80 */ float scale_b;
/* 84 */ float mix;
/* 88 */ float opacity;
/* 92 */ float pad;
/* 96 */
};
static_assert(sizeof(BackgroundPatternLayerUBO) == 96);
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,66 @@
#pragma once
#include <mbgl/shaders/layer_ubo.hpp>
namespace mbgl {
namespace shaders {
struct alignas(16) CircleDrawableUBO {
/* 0 */ std::array<float, 4 * 4> matrix; // composite model-view-projection matrix
/* 64 */ std::array<float, 2> extrude_scale;
/* 72 */ float pad;
/* 80 */
};
static_assert(sizeof(CircleDrawableUBO) == 5 * 16);
struct alignas(16) CirclePaintParamsUBO {
/* 0 */ float camera_to_center_distance;
/* 4 */ float device_pixel_ratio;
/* 8 */ float pad1, pad2;
/* 16 */
};
static_assert(sizeof(CirclePaintParamsUBO) == 1 * 16);
struct alignas(16) CircleEvaluatedPropsUBO {
Color color;
Color stroke_color;
float radius;
float blur;
float opacity;
float stroke_width;
float stroke_opacity;
int scale_with_map;
int pitch_with_map;
float padding;
};
static_assert(sizeof(CircleEvaluatedPropsUBO) % 16 == 0);
struct alignas(16) CircleInterpolateUBO {
float color_t;
float radius_t;
float blur_t;
float opacity_t;
float stroke_color_t;
float stroke_width_t;
float stroke_opacity_t;
float padding;
};
static_assert(sizeof(CircleInterpolateUBO) % 16 == 0);
struct alignas(16) CirclePermutationUBO {
/* 0 */ Attribute color;
/* 8 */ Attribute radius;
/* 16 */ Attribute blur;
/* 24 */ Attribute opacity;
/* 32 */ Attribute stroke_color;
/* 40 */ Attribute stroke_width;
/* 48 */ Attribute stroke_opacity;
/* 56 */ bool overdrawInspector;
/* 57 */ uint8_t pad1, pad2, pad3;
/* 60 */ float pad4;
/* 64 */
};
static_assert(sizeof(CirclePermutationUBO) == 4 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,166 @@
#pragma once
#include <mbgl/shaders/layer_ubo.hpp>
namespace mbgl {
namespace shaders {
//
// Fill
struct alignas(16) FillDrawableUBO {
/* 0 */ std::array<float, 4 * 4> matrix; // composite model-view-projection matrix
};
static_assert(sizeof(FillDrawableUBO) == 4 * 16);
struct alignas(16) FillEvaluatedPropsUBO {
Color color;
float opacity;
float pad1, pad2, pad3;
};
static_assert(sizeof(FillEvaluatedPropsUBO) == 2 * 16);
struct alignas(16) FillInterpolateUBO {
float color_t;
float opacity_t;
float pad1, pad2;
};
static_assert(sizeof(FillInterpolateUBO) % 16 == 0);
struct alignas(16) FillPermutationUBO {
/* 0 */ Attribute color;
/* 8 */ Attribute opacity;
/* 16 */ bool overdrawInspector;
/* 17 */ bool pad1, pad2, pad3;
/* 20 */ float pad4, pad5, pad6;
/* 32 */
};
static_assert(sizeof(FillPermutationUBO) == 2 * 16);
//
// Fill outline
struct alignas(16) FillOutlineDrawableUBO {
/* 0 */ std::array<float, 4 * 4> matrix; // composite model-view-projection matrix
/* 64 */ std::array<float, 2> world;
/* 80 */
};
static_assert(sizeof(FillOutlineDrawableUBO) == 5 * 16);
struct alignas(16) FillOutlineEvaluatedPropsUBO {
Color outline_color;
float opacity;
float pad1, pad2, pad3;
};
static_assert(sizeof(FillOutlineEvaluatedPropsUBO) == 2 * 16);
struct alignas(16) FillOutlineInterpolateUBO {
float outline_color_t;
float opacity_t;
float pad1, pad2;
};
static_assert(sizeof(FillOutlineInterpolateUBO) == 1 * 16);
struct alignas(16) FillOutlinePermutationUBO {
/* 0 */ Attribute outline_color;
/* 8 */ Attribute opacity;
/* 16 */ bool overdrawInspector;
/* 17 */ bool pad1, pad2, pad3;
/* 20 */ float pad4, pad5, pad6;
/* 32 */
};
static_assert(sizeof(FillOutlinePermutationUBO) == 2 * 16);
//
// Fill Pattern
struct alignas(16) FillPatternDrawableUBO {
/* 0 */ std::array<float, 4 * 4> matrix; // composite model-view-projection matrix
/* 64 */ std::array<float, 4> scale;
/* 80 */ std::array<float, 2> pixel_coord_upper;
/* 88 */ std::array<float, 2> pixel_coord_lower;
/* 96 */ std::array<float, 2> texsize;
/* 104 */ float pad1, pad2;
/* 112 */
};
static_assert(sizeof(FillPatternDrawableUBO) == 7 * 16);
struct alignas(16) FillPatternEvaluatedPropsUBO {
float opacity;
float fade;
float pad1, pad2;
};
static_assert(sizeof(FillPatternEvaluatedPropsUBO) == 1 * 16);
struct alignas(16) FillPatternTilePropsUBO {
std::array<float, 4> pattern_from;
std::array<float, 4> pattern_to;
};
static_assert(sizeof(FillPatternTilePropsUBO) == 2 * 16);
struct alignas(16) FillPatternInterpolateUBO {
float pattern_from_t;
float pattern_to_t;
float opacity_t;
float pad1;
};
static_assert(sizeof(FillPatternInterpolateUBO) == 1 * 16);
struct alignas(16) FillPatternPermutationUBO {
/* 0 */ Attribute pattern_from;
/* 8 */ Attribute pattern_to;
/* 16 */ Attribute opacity;
/* 24 */ bool overdrawInspector;
/* 25 */ bool pad1, pad2, pad3;
/* 28 */ float pad4;
/* 32 */
};
static_assert(sizeof(FillPatternPermutationUBO) == 2 * 16);
//
// Fill pattern outline
struct alignas(16) FillOutlinePatternDrawableUBO {
/* 0 */ std::array<float, 4 * 4> matrix; // composite model-view-projection matrix
/* 64 */ std::array<float, 4> scale;
/* 80 */ std::array<float, 2> world;
/* 88 */ std::array<float, 2> pixel_coord_upper;
/* 96 */ std::array<float, 2> pixel_coord_lower;
/* 104 */ std::array<float, 2> texsize;
};
static_assert(sizeof(FillOutlinePatternDrawableUBO) == 7 * 16);
struct alignas(16) FillOutlinePatternEvaluatedPropsUBO {
float opacity;
float fade;
float pad1, pad2;
};
static_assert(sizeof(FillOutlinePatternEvaluatedPropsUBO) == 16);
struct alignas(16) FillOutlinePatternTilePropsUBO {
std::array<float, 4> pattern_from;
std::array<float, 4> pattern_to;
};
static_assert(sizeof(FillOutlinePatternTilePropsUBO) == 2 * 16);
struct alignas(16) FillOutlinePatternInterpolateUBO {
float pattern_from_t;
float pattern_to_t;
float opacity_t;
float pad;
};
static_assert(sizeof(FillOutlinePatternInterpolateUBO) == 1 * 16);
struct alignas(16) FillOutlinePatternPermutationUBO {
/* 0 */ Attribute pattern_from;
/* 8 */ Attribute pattern_to;
/* 16 */ Attribute opacity;
/* 24 */ bool overdrawInspector;
/* 17 */ bool pad1, pad2, pad3;
/* 20 */ float pad4;
/* 32 */
};
static_assert(sizeof(FillOutlinePatternPermutationUBO) == 2 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -8,35 +8,20 @@ namespace shaders {
template <>
struct ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::OpenGL> {
static constexpr const char* name = "FillShader";
static constexpr const char* vertex = R"(layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
static constexpr const char* vertex = R"(layout (std140) uniform FillDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
layout (std140) uniform FillEvaluatedPropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
highp float u_opacity;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float pad_interp_1, pad_interp_2;
};
layout (location = 0) in vec2 a_pos;
@@ -65,35 +50,17 @@ lowp float opacity = u_opacity;
gl_Position = u_matrix * vec4(a_pos, 0, 1);
}
)";
static constexpr const char* fragment = R"(layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
static constexpr const char* fragment = R"(layout (std140) uniform FillEvaluatedPropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
highp float u_opacity;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float pad_interp_1, pad_interp_2;
};
#ifndef HAS_UNIFORM_u_color

View File

@@ -8,35 +8,22 @@ namespace shaders {
template <>
struct ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::OpenGL> {
static constexpr const char* name = "FillOutlineShader";
static constexpr const char* vertex = R"(layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
static constexpr const char* vertex = R"(layout (std140) uniform FillOutlineDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
layout (std140) uniform FillOutlineEvaluatedPropsUBO {
highp vec4 u_outline_color;
highp float u_opacity;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
layout (std140) uniform FillOutlineInterpolateUBO {
highp float u_outline_color_t;
highp float u_opacity_t;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (location = 0) in vec2 a_pos;
@@ -68,35 +55,18 @@ lowp float opacity = u_opacity;
v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;
}
)";
static constexpr const char* fragment = R"(layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
static constexpr const char* fragment = R"(layout (std140) uniform FillOutlineEvaluatedPropsUBO {
highp vec4 u_outline_color;
highp float u_opacity;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
layout (std140) uniform FillOutlineInterpolateUBO {
highp float u_outline_color_t;
highp float u_opacity_t;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
in vec2 v_pos;

View File

@@ -8,17 +8,7 @@ namespace shaders {
template <>
struct ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::OpenGL> {
static constexpr const char* name = "FillOutlinePatternShader";
static constexpr const char* vertex = R"(layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
static constexpr const char* vertex = R"(layout (std140) uniform FillOutlinePatternDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
@@ -26,15 +16,19 @@ layout (std140) uniform FillDrawableUBO {
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
layout (std140) uniform FillOutlinePatternEvaluatedPropsUBO {
highp float u_opacity;
highp float u_fade;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
layout (std140) uniform FillOutlinePatternInterpolateUBO {
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_opacity_t;
highp float pad1;
};
layout (std140) uniform FillOutlinePatternTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
};
@@ -96,17 +90,7 @@ mediump vec4 pattern_to = u_pattern_to;
v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;
}
)";
static constexpr const char* fragment = R"(layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
static constexpr const char* fragment = R"(layout (std140) uniform FillOutlinePatternDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
@@ -114,15 +98,19 @@ layout (std140) uniform FillDrawableUBO {
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
layout (std140) uniform FillOutlinePatternEvaluatedPropsUBO {
highp float u_opacity;
highp float u_fade;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
layout (std140) uniform FillOutlinePatternInterpolateUBO {
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_opacity_t;
highp float pad1;
};
layout (std140) uniform FillOutlinePatternTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
};

View File

@@ -8,33 +8,26 @@ namespace shaders {
template <>
struct ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::OpenGL> {
static constexpr const char* name = "FillPatternShader";
static constexpr const char* vertex = R"(layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
static constexpr const char* vertex = R"(layout (std140) uniform FillPatternDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
layout (std140) uniform FillPatternEvaluatedPropsUBO {
highp float u_opacity;
highp float u_fade;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
layout (std140) uniform FillPatternInterpolateUBO {
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_opacity_t;
highp float u_padding_interp1;
};
layout (std140) uniform FillPatternTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
};
@@ -92,33 +85,26 @@ mediump vec4 pattern_to = u_pattern_to;
v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, toScale * display_size_b, tileZoomRatio, a_pos);
}
)";
static constexpr const char* fragment = R"(layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
static constexpr const char* fragment = R"(layout (std140) uniform FillPatternDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
layout (std140) uniform FillPatternEvaluatedPropsUBO {
highp float u_opacity;
highp float u_fade;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
layout (std140) uniform FillPatternInterpolateUBO {
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_opacity_t;
highp float u_padding_interp1;
};
layout (std140) uniform FillPatternTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
};

View File

@@ -56,6 +56,7 @@ layout (std140) uniform LineSDFInterpolationUBO {
lowp float u_offset_t;
lowp float u_width_t;
lowp float u_floorwidth_t;
highp float pad2;
};
@@ -215,6 +216,7 @@ layout (std140) uniform LineSDFInterpolationUBO {
lowp float u_offset_t;
lowp float u_width_t;
lowp float u_floorwidth_t;
highp float pad2;
};

View File

@@ -29,8 +29,13 @@ layout (std140) uniform SymbolDrawableUBO {
highp float u_pitch;
bool u_rotate_symbol;
highp float u_aspect_ratio;
highp vec2 u_pad1;
};
layout (std140) uniform SymbolDynamicUBO {
highp float u_fade_change;
highp float u_pad2;
highp float u_pad7;
highp vec2 u_pad8;
};
layout (std140) uniform SymbolDrawablePaintUBO {

View File

@@ -37,8 +37,13 @@ layout (std140) uniform SymbolDrawableUBO {
highp float u_pitch;
bool u_rotate_symbol;
highp float u_aspect_ratio;
highp vec2 u_pad1;
};
layout (std140) uniform SymbolDynamicUBO {
highp float u_fade_change;
highp float u_pad2;
highp float u_pad7;
highp vec2 u_pad8;
};
layout (std140) uniform SymbolDrawablePaintUBO {
@@ -207,8 +212,13 @@ layout (std140) uniform SymbolDrawableUBO {
highp float u_pitch;
bool u_rotate_symbol;
highp float u_aspect_ratio;
highp vec2 u_pad1;
};
layout (std140) uniform SymbolDynamicUBO {
highp float u_fade_change;
highp float u_pad2;
highp float u_pad7;
highp vec2 u_pad8;
};
layout (std140) uniform SymbolDrawablePaintUBO {

View File

@@ -37,8 +37,13 @@ layout (std140) uniform SymbolDrawableUBO {
highp float u_pitch;
bool u_rotate_symbol;
highp float u_aspect_ratio;
highp vec2 u_pad1;
};
layout (std140) uniform SymbolDynamicUBO {
highp float u_fade_change;
highp float u_pad2;
highp float u_pad7;
highp vec2 u_pad8;
};
layout (std140) uniform SymbolDrawablePaintUBO {
@@ -207,8 +212,13 @@ layout (std140) uniform SymbolDrawableUBO {
highp float u_pitch;
bool u_rotate_symbol;
highp float u_aspect_ratio;
highp vec2 u_pad1;
};
layout (std140) uniform SymbolDynamicUBO {
highp float u_fade_change;
highp float u_pad2;
highp float u_pad7;
highp vec2 u_pad8;
};
layout (std140) uniform SymbolDrawablePaintUBO {

View File

@@ -36,8 +36,13 @@ layout (std140) uniform SymbolDrawableUBO {
highp float u_pitch;
bool u_rotate_symbol;
highp float u_aspect_ratio;
highp vec2 u_pad1;
};
layout (std140) uniform SymbolDynamicUBO {
highp float u_fade_change;
highp float u_pad2;
highp float u_pad7;
highp vec2 u_pad8;
};
layout (std140) uniform SymbolDrawablePaintUBO {
@@ -210,8 +215,13 @@ layout (std140) uniform SymbolDrawableUBO {
highp float u_pitch;
bool u_rotate_symbol;
highp float u_aspect_ratio;
highp vec2 u_pad1;
};
layout (std140) uniform SymbolDynamicUBO {
highp float u_fade_change;
highp float u_pad2;
highp float u_pad7;
highp vec2 u_pad8;
};
layout (std140) uniform SymbolDrawablePaintUBO {

View File

@@ -78,7 +78,7 @@ void main() {
// we want to vertically exaggerate the hillshading though, because otherwise
// it is barely noticeable at low zooms. to do this, we multiply this by some
// scale factor pow(2, (u_zoom - u_maxzoom) * a) where a is an arbitrary value
// Here we use a=0.3 which works out to the expression below. see
// Here we use a=0.3 which works out to the expression below. see
// nickidlugash's awesome breakdown for more info
// https://github.com/mapbox/mapbox-gl-js/pull/5286#discussion_r148419556
float exaggeration = u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;

View File

@@ -0,0 +1,52 @@
#pragma once
#include <mbgl/util/color.hpp>
#include <array>
#include <cstdint>
#define MLN_STRINGIZE(X) #X
namespace mbgl {
namespace shaders {
enum class AttributeSource : int32_t {
Constant,
PerVertex,
Computed,
};
enum class ExpressionFunction : int32_t {
Constant,
Linear,
Exponential,
};
struct Expression {
/* 0 */ ExpressionFunction function;
/* 4 */
};
static_assert(sizeof(Expression) == 4);
struct Attribute {
/* 0 */ AttributeSource source;
/* 4 */ Expression expression;
/* 8 */
};
static_assert(sizeof(Attribute) == 8);
struct alignas(16) ExpressionInputsUBO {
// These can use uint64_t in later versions of Metal
/* 0 */ uint32_t time_lo; /// Current scene time (nanoseconds)
/* 4 */ uint32_t time_hi;
/* 8 */ uint32_t frame_lo; /// Current frame count
/* 12 */ uint32_t frame_hi;
/* 16 */ float zoom; /// Current zoom level
/* 20 */ float zoom_frac; /// double precision zoom
/* 24 */ float pad1, pad2;
/* 32 */
};
static_assert(sizeof(ExpressionInputsUBO) == 2 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,158 @@
#pragma once
#include <mbgl/shaders/layer_ubo.hpp>
namespace mbgl {
namespace shaders {
struct alignas(16) LineUBO {
std::array<float, 4 * 4> matrix;
std::array<float, 2> units_to_pixels;
float ratio;
float device_pixel_ratio;
};
static_assert(sizeof(LineUBO) % 16 == 0);
using LineGradientUBO = LineUBO;
struct alignas(16) LinePropertiesUBO {
Color color;
float blur;
float opacity;
float gapwidth;
float offset;
float width;
float pad1, pad2, pad3;
};
static_assert(sizeof(LinePropertiesUBO) % 16 == 0);
struct alignas(16) LineGradientPropertiesUBO {
float blur;
float opacity;
float gapwidth;
float offset;
float width;
float pad1, pad2, pad3;
};
static_assert(sizeof(LineGradientPropertiesUBO) % 16 == 0);
struct alignas(16) LinePatternUBO {
std::array<float, 4 * 4> matrix;
std::array<float, 4> scale;
std::array<float, 2> texsize;
std::array<float, 2> units_to_pixels;
float ratio;
float device_pixel_ratio;
float fade;
float pad1;
};
static_assert(sizeof(LinePatternUBO) % 16 == 0);
struct alignas(16) LinePatternPropertiesUBO {
float blur;
float opacity;
float offset;
float gapwidth;
float width;
float pad1, pad2, pad3;
};
static_assert(sizeof(LinePatternPropertiesUBO) % 16 == 0);
struct alignas(16) LineSDFUBO {
std::array<float, 4 * 4> matrix;
std::array<float, 2> units_to_pixels;
std::array<float, 2> patternscale_a;
std::array<float, 2> patternscale_b;
float ratio;
float device_pixel_ratio;
float tex_y_a;
float tex_y_b;
float sdfgamma;
float mix;
};
static_assert(sizeof(LineSDFUBO) % 16 == 0);
struct alignas(16) LineSDFPropertiesUBO {
Color color;
float blur;
float opacity;
float gapwidth;
float offset;
float width;
float floorwidth;
float pad1, pad2;
};
static_assert(sizeof(LineSDFPropertiesUBO) % 16 == 0);
/// Property interpolation UBOs
struct alignas(16) LineInterpolationUBO {
float color_t;
float blur_t;
float opacity_t;
float gapwidth_t;
float offset_t;
float width_t;
float pad1, pad2;
};
static_assert(sizeof(LineInterpolationUBO) % 16 == 0);
struct alignas(16) LineGradientInterpolationUBO {
float blur_t;
float opacity_t;
float gapwidth_t;
float offset_t;
float width_t;
float pad1, pad2, pad3;
};
static_assert(sizeof(LineGradientInterpolationUBO) % 16 == 0);
struct alignas(16) LinePatternInterpolationUBO {
float blur_t;
float opacity_t;
float offset_t;
float gapwidth_t;
float width_t;
float pattern_from_t;
float pattern_to_t;
float pad1;
};
static_assert(sizeof(LinePatternInterpolationUBO) % 16 == 0);
struct alignas(16) LineSDFInterpolationUBO {
float color_t;
float blur_t;
float opacity_t;
float gapwidth_t;
float offset_t;
float width_t;
float floorwidth_t;
float pad1;
};
static_assert(sizeof(LineSDFInterpolationUBO) % 16 == 0);
/// Evaluated properties that depend on the tile
struct alignas(16) LinePatternTilePropertiesUBO {
std::array<float, 4> pattern_from;
std::array<float, 4> pattern_to;
};
static_assert(sizeof(LinePatternTilePropertiesUBO) % 16 == 0);
struct alignas(16) LinePermutationUBO {
/* 0 */ Attribute color;
/* 8 */ Attribute blur;
/* 16 */ Attribute opacity;
/* 24 */ Attribute gapwidth;
/* 32 */ Attribute offset;
/* 40 */ Attribute width;
/* 48 */ Attribute floorwidth;
/* 56 */ Attribute pattern_from;
/* 64 */ Attribute pattern_to;
/* 72 */ bool overdrawInspector;
/* 73 */ uint8_t pad1, pad2, pad3;
/* 76 */ float pad4;
/* 80 */
};
static_assert(sizeof(LinePermutationUBO) == 5 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,66 @@
#pragma once
#include <mbgl/shaders/shader_source.hpp>
#include <mbgl/shaders/background_layer_ubo.hpp>
#include <mbgl/shaders/mtl/common.hpp>
#include <mbgl/shaders/mtl/shader_program.hpp>
namespace mbgl {
namespace shaders {
template <>
struct ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "BackgroundShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr AttributeInfo attributes[] = {
{0, gfx::AttributeDataType::Float3, 1, "a_pos"},
};
static constexpr UniformBlockInfo uniforms[] = {
MLN_MTL_UNIFORM_BLOCK(1, true, true, BackgroundLayerUBO),
MLN_MTL_UNIFORM_BLOCK(2, true, false, BackgroundDrawableUBO),
};
static constexpr TextureInfo textures[] = {};
static constexpr auto source = R"(
#include <metal_stdlib>
using namespace metal;
struct VertexStage {
short2 position [[attribute(0)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
};
struct alignas(16) BackgroundDrawableUBO {
float4x4 matrix;
};
struct alignas(16) BackgroundLayerUBO {
float4 color;
float opacity, pad1, pad2, pad3;
};
FragmentStage vertex vertexMain(VertexStage in [[stage_in]],
device const BackgroundLayerUBO& layerUBO [[buffer(1)]],
device const BackgroundDrawableUBO& drawableUBO [[buffer(2)]]) {
return {
.position = drawableUBO.matrix * float4(float2(in.position.xy), 0, 1)
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const BackgroundLayerUBO& layerUBO [[buffer(1)]]) {
#ifdef OVERDRAW_INSPECTOR
return half4(1.0);
#else
return half4(float4(layerUBO.color.rgb, layerUBO.color.a * layerUBO.opacity));
#endif
}
)";
};
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,20 @@
#pragma once
#include <mbgl/shaders/mtl/background.hpp>
namespace mbgl {
namespace shaders {
template <>
struct ShaderSource<BuiltIn::BackgroundPatternShader, gfx::Backend::Type::Metal>
: public ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "BackgroundPatternShader";
static constexpr UniformBlockInfo uniforms[] = {
{1, sizeof(BackgroundLayerUBO), true, false, "BackgroundLayerUBO"},
{2, sizeof(BackgroundDrawableUBO), true, false, "BackgroundDrawableUBO"},
{3, sizeof(BackgroundPatternLayerUBO), true, false, "BackgroundPatternLayerUBO"},
};
};
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,193 @@
#pragma once
#include <mbgl/shaders/circle_layer_ubo.hpp>
#include <mbgl/shaders/shader_source.hpp>
#include <mbgl/shaders/mtl/common.hpp>
#include <mbgl/shaders/mtl/shader_program.hpp>
namespace mbgl {
namespace shaders {
template <>
struct ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "CircleShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr AttributeInfo attributes[] = {
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
{1, gfx::AttributeDataType::Float2, 1, "a_color"},
{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
{5, gfx::AttributeDataType::Float4, 1, "a_stroke_color"},
{6, gfx::AttributeDataType::Float2, 1, "a_stroke_width"},
{7, gfx::AttributeDataType::Float2, 1, "a_stroke_opacity"},
};
static constexpr UniformBlockInfo uniforms[] = {
MLN_MTL_UNIFORM_BLOCK(8, true, false, CircleDrawableUBO),
MLN_MTL_UNIFORM_BLOCK(9, true, true, CirclePaintParamsUBO),
MLN_MTL_UNIFORM_BLOCK(10, true, true, CircleEvaluatedPropsUBO),
MLN_MTL_UNIFORM_BLOCK(11, true, false, CircleInterpolateUBO),
MLN_MTL_UNIFORM_BLOCK(12, true, true, CirclePermutationUBO),
MLN_MTL_UNIFORM_BLOCK(13, true, false, ExpressionInputsUBO),
};
static constexpr TextureInfo textures[] = {};
static constexpr auto source = R"(
struct VertexStage {
short2 position [[attribute(0)]];
float2 color [[attribute(1)]];
float2 radius [[attribute(2)]];
float2 blur [[attribute(3)]];
float2 opacity [[attribute(4)]];
float4 stroke_color [[attribute(5)]];
float2 stroke_width [[attribute(6)]];
float2 stroke_opacity [[attribute(7)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
float4 color;
float radius;
half blur;
half opacity;
float4 stroke_color;
float stroke_width;
half stroke_opacity;
float2 extrude;
half antialiasblur;
};
struct alignas(16) CircleDrawableUBO {
float4x4 matrix;
float2 extrude_scale;
float2 padding;
};
struct alignas(16) CirclePaintParamsUBO {
float camera_to_center_distance;
float device_pixel_ratio;
float pad1,pad2;
};
struct alignas(16) CircleEvaluatedPropsUBO {
float4 color;
float4 stroke_color;
float radius;
float blur;
float opacity;
float stroke_width;
float stroke_opacity;
int scale_with_map;
int pitch_with_map;
float padding;
};
struct alignas(16) CircleInterpolateUBO {
float color_t;
float radius_t;
float blur_t;
float opacity_t;
float stroke_color_t;
float stroke_width_t;
float stroke_opacity_t;
float pad1_;
};
struct alignas(16) CirclePermutationUBO {
Attribute color;
Attribute radius;
Attribute blur;
Attribute opacity;
Attribute stroke_color;
Attribute stroke_width;
Attribute stroke_opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const CircleDrawableUBO& drawable [[buffer(8)]],
device const CirclePaintParamsUBO& params [[buffer(9)]],
device const CircleEvaluatedPropsUBO& props [[buffer(10)]],
device const CircleInterpolateUBO& interp [[buffer(11)]],
device const CirclePermutationUBO& permutation [[buffer(12)]],
device const ExpressionInputsUBO& expr [[buffer(13)]]) {
const auto color = colorFor(permutation.color, props.color, vertx.color, expr);
const auto radius = valueFor(permutation.radius, props.radius, vertx.radius, interp.radius_t, expr);
const auto blur = valueFor(permutation.blur, props.blur, vertx.blur, interp.blur_t, expr);
const auto opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr);
const auto stroke_color = colorFor(permutation.stroke_color, props.stroke_color, vertx.stroke_color, interp.stroke_color_t, expr);
const auto stroke_width = valueFor(permutation.stroke_width, props.stroke_width, vertx.stroke_width, interp.stroke_width_t, expr);
const auto stroke_opacity = valueFor(permutation.stroke_opacity, props.stroke_opacity, vertx.stroke_opacity, interp.stroke_opacity_t, expr);
// unencode the extrusion vector that we snuck into the a_pos vector
const float2 extrude = fmod(float2(vertx.position), 2.0) * 2.0 - 1.0;
const float2 scaled_extrude = extrude * drawable.extrude_scale;
// multiply a_pos by 0.5, since we had it * 2 in order to sneak in extrusion data
const float2 circle_center = floor(float2(vertx.position) * 0.5);
float4 position;
if (props.pitch_with_map) {
float2 corner_position = circle_center;
if (props.scale_with_map) {
corner_position += scaled_extrude * (radius + stroke_width);
} else {
// Pitching the circle with the map effectively scales it with the map
// To counteract the effect for pitch-scale: viewport, we rescale the
// whole circle based on the pitch scaling effect at its central point
float4 projected_center = drawable.matrix * float4(circle_center, 0, 1);
corner_position += scaled_extrude * (radius + stroke_width) *
(projected_center.w / params.camera_to_center_distance);
}
position = drawable.matrix * float4(corner_position, 0, 1);
} else {
position = drawable.matrix * float4(circle_center, 0, 1);
const float factor = props.scale_with_map ? params.camera_to_center_distance : position.w;
position.xy += scaled_extrude * (radius + stroke_width) * factor;
}
// This is a minimum blur distance that serves as a faux-antialiasing for
// the circle. since blur is a ratio of the circle's size and the intent is
// to keep the blur at roughly 1px, the two are inversely related.
const half antialiasblur = 1.0 / params.device_pixel_ratio / (radius + stroke_width);
return {
.position = position,
.color = color,
.radius = radius,
.blur = half(blur),
.opacity = half(opacity),
.stroke_color = stroke_color,
.stroke_width = stroke_width,
.stroke_opacity = half(stroke_opacity),
.extrude = extrude,
.antialiasblur = antialiasblur,
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const CirclePaintParamsUBO& params [[buffer(9)]],
device const CircleEvaluatedPropsUBO& props [[buffer(10)]],
device const CirclePermutationUBO& permutation [[buffer(12)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
const float extrude_length = length(in.extrude);
const float antialiased_blur = -max(in.blur, in.antialiasblur);
const float opacity_t = smoothstep(0.0, antialiased_blur, extrude_length - 1.0);
const float color_t = (in.stroke_width < 0.01) ? 0.0 :
smoothstep(antialiased_blur, 0.0, extrude_length - in.radius / (in.radius + in.stroke_width));
return half4(opacity_t * mix(in.color * in.opacity, in.stroke_color * in.stroke_opacity, color_t));
}
)";
};
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,207 @@
#pragma once
#define MLN_MTL_UNIFORM_BLOCK(idx, vert, frag, struc) \
{ idx, vert, frag, sizeof(struc), MLN_STRINGIZE(struc) }
namespace mbgl {
namespace shaders {
constexpr auto prelude = R"(
#include <metal_stdlib>
using namespace metal;
template <typename T1, typename T2>
inline auto mod(T1 x, T2 y) -> decltype(x - y * floor(x/y)) {
return x - y * metal::floor(x/y);
}
enum class AttributeSource : int32_t {
Constant,
PerVertex,
Computed,
};
struct Expression {};
struct Attribute {
AttributeSource source;
Expression expression;
};
struct alignas(16) ExpressionInputsUBO {
// These can use uint64_t in later versions of Metal
/* 0 */ uint32_t time_lo; // Current scene time (nanoseconds)
/* 4 */ uint32_t time_hi;
/* 8 */ uint32_t frame_lo; // Current frame count
/* 12 */ uint32_t frame_hi;
/* 16 */ float zoom; // Current zoom level
/* 20 */ float pad1, pad2, pad3;
/* 32 */
};
// Unpack a pair of values that have been packed into a single float.
// The packed values are assumed to be 8-bit unsigned integers, and are
// packed like so: packedValue = floor(input[0]) * 256 + input[1],
float2 unpack_float(const float packedValue) {
const int packedIntValue = int(packedValue);
const int v0 = packedIntValue / 256;
return float2(v0, packedIntValue - v0 * 256);
}
float2 unpack_opacity(const float packedOpacity) {
return float2(float(int(packedOpacity) / 2) / 127.0, fmod(packedOpacity, 2.0));
}
// To minimize the number of attributes needed, we encode a 4-component
// color into a pair of floats (i.e. a vec2) as follows:
// [ floor(color.r * 255) * 256 + color.g * 255, floor(color.b * 255) * 256 + color.g * 255 ]
float4 decode_color(const float2 encoded) {
return float4(unpack_float(encoded[0]) / 255, unpack_float(encoded[1]) / 255);
}
// Unpack a pair of paint values and interpolate between them.
float unpack_mix_float(const float2 packedValue, const float t) {
return mix(packedValue[0], packedValue[1], t);
}
// Unpack a pair of paint values and interpolate between them.
float4 unpack_mix_color(const float4 packedColors, const float t) {
return mix(decode_color(float2(packedColors[0], packedColors[1])),
decode_color(float2(packedColors[2], packedColors[3])), t);
}
float valueFor(device const Attribute& attrib,
device const float& constValue,
thread const float2& vertexValue,
device const float& t,
device const ExpressionInputsUBO&) {
switch (attrib.source) {
case AttributeSource::PerVertex: return unpack_mix_float(vertexValue, t);
case AttributeSource::Computed: // TODO
default:
case AttributeSource::Constant: return constValue;
}
}
// single packed color
float4 colorFor(device const Attribute& attrib,
device const float4& constValue,
thread const float2& vertexValue,
device const ExpressionInputsUBO&) {
switch (attrib.source) {
case AttributeSource::PerVertex: return decode_color(float2(vertexValue[0], vertexValue[1]));
case AttributeSource::Computed: // TODO
default:
case AttributeSource::Constant: return constValue;
}
}
// interpolated packed colors
float4 colorFor(device const Attribute& attrib,
device const float4& constValue,
thread const float4& vertexValue,
device const float& t,
device const ExpressionInputsUBO&) {
switch (attrib.source) {
case AttributeSource::PerVertex: return unpack_mix_color(vertexValue, t);
case AttributeSource::Computed: // TODO
default:
case AttributeSource::Constant: return constValue;
}
}
// The maximum allowed miter limit is 2.0 at the moment. the extrude normal is stored
// in a byte (-128..127). We scale regular normals up to length 63, but there are also
// "special" normals that have a bigger length (of up to 126 in this case).
constant float LINE_NORMAL_SCALE = 1.0 / (127 / 2);
// The attribute conveying progress along a line is scaled to [0, 2^15).
constant float MAX_LINE_DISTANCE = 32767.0;
struct alignas(16) LineUBO {
float4x4 matrix;
float2 units_to_pixels;
float ratio;
float device_pixel_ratio;
};
struct alignas(16) LineGradientUBO {
float4x4 matrix;
float2 units_to_pixels;
float ratio;
float device_pixel_ratio;
};
struct alignas(16) LinePropertiesUBO {
float4 color;
float blur;
float opacity;
float gapwidth;
float offset;
float width;
float pad1, pad2, pad3;
};
struct alignas(16) LineGradientPropertiesUBO {
float blur;
float opacity;
float gapwidth;
float offset;
float width;
float pad1, pad2, pad3;
};
struct alignas(16) LinePermutationUBO {
Attribute color;
Attribute blur;
Attribute opacity;
Attribute gapwidth;
Attribute offset;
Attribute width;
Attribute floorwidth;
Attribute pattern_from;
Attribute pattern_to;
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4;
};
struct alignas(16) LineInterpolationUBO {
float color_t;
float blur_t;
float opacity_t;
float gapwidth_t;
float offset_t;
float width_t;
float pad1, pad2;
};
struct alignas(16) LineGradientInterpolationUBO {
float blur_t;
float opacity_t;
float gapwidth_t;
float offset_t;
float width_t;
float pad1, pad2, pad3;
};
// interpolated packed pattern
float4 patternFor(device const Attribute& attrib,
device const float4& constValue,
thread const ushort4& vertexValue,
device const float& ,
device const ExpressionInputsUBO&) {
switch (attrib.source) {
case AttributeSource::PerVertex: return float4(vertexValue);
case AttributeSource::Computed: // TODO
default:
case AttributeSource::Constant: return constValue;
}
}
// unpack pattern position
inline float2 get_pattern_pos(const float2 pixel_coord_upper, const float2 pixel_coord_lower,
const float2 pattern_size, const float tile_units_to_pixels, const float2 pos) {
float2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size);
return (tile_units_to_pixels * pos + offset) / pattern_size;
}
)";
}
} // namespace mbgl

View File

@@ -0,0 +1,476 @@
#pragma once
#include <mbgl/shaders/fill_layer_ubo.hpp>
#include <mbgl/shaders/shader_source.hpp>
#include <mbgl/shaders/mtl/common.hpp>
#include <mbgl/shaders/mtl/shader_program.hpp>
namespace mbgl {
namespace shaders {
template <>
struct ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "FillShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr AttributeInfo attributes[] = {
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
{1, gfx::AttributeDataType::Float2, 1, "a_color"},
{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
};
static constexpr UniformBlockInfo uniforms[] = {
MLN_MTL_UNIFORM_BLOCK(3, true, false, FillDrawableUBO),
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillEvaluatedPropsUBO),
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillInterpolateUBO),
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillPermutationUBO),
MLN_MTL_UNIFORM_BLOCK(7, true, false, ExpressionInputsUBO),
};
static constexpr TextureInfo textures[] = {};
static constexpr auto source = R"(
struct VertexStage {
short2 position [[attribute(0)]];
float2 color [[attribute(1)]];
float2 opacity [[attribute(2)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
float4 color;
half opacity;
};
struct alignas(16) FillDrawableUBO {
float4x4 matrix;
};
struct alignas(16) FillEvaluatedPropsUBO {
float4 color;
float opacity;
};
struct alignas(16) FillInterpolateUBO {
float color_t;
float opacity_t;
};
struct alignas(16) FillPermutationUBO {
Attribute color;
Attribute opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillDrawableUBO& drawable [[buffer(3)]],
device const FillEvaluatedPropsUBO& props [[buffer(4)]],
device const FillInterpolateUBO& interp [[buffer(5)]],
device const FillPermutationUBO& permutation [[buffer(6)]],
device const ExpressionInputsUBO& expr [[buffer(7)]]) {
const auto color = colorFor(permutation.color, props.color, vertx.color, expr);
const auto opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr);
float4 position = drawable.matrix * float4(float2(vertx.position), 0.0f, 1.0f);
return {
.position = position,
.color = color,
.opacity = half(opacity),
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const FillEvaluatedPropsUBO& props [[buffer(4)]],
device const FillPermutationUBO& permutation [[buffer(6)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
return half4(in.color * in.opacity);
}
)";
};
template <>
struct ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "FillOutlineShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr AttributeInfo attributes[] = {
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
{1, gfx::AttributeDataType::Float2, 1, "a_outline_color"},
{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
};
static constexpr UniformBlockInfo uniforms[] = {
MLN_MTL_UNIFORM_BLOCK(3, true, false, FillOutlineDrawableUBO),
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillOutlineEvaluatedPropsUBO),
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillOutlineInterpolateUBO),
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillOutlinePermutationUBO),
MLN_MTL_UNIFORM_BLOCK(7, true, false, ExpressionInputsUBO),
};
static constexpr TextureInfo textures[] = {};
static constexpr auto source = R"(
struct VertexStage {
short2 position [[attribute(0)]];
float2 outline_color [[attribute(1)]];
float2 opacity [[attribute(2)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
float4 outline_color;
float2 pos;
half opacity;
};
struct alignas(16) FillOutlineDrawableUBO {
float4x4 matrix;
float2 world;
};
struct alignas(16) FillOutlineEvaluatedPropsUBO {
float4 outline_color;
float opacity;
};
struct alignas(16) FillOutlineInterpolateUBO {
float outline_color_t;
float opacity_t;
};
struct alignas(16) FillOutlinePermutationUBO {
Attribute outline_color;
Attribute opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillOutlineDrawableUBO& drawable [[buffer(3)]],
device const FillOutlineEvaluatedPropsUBO& props [[buffer(4)]],
device const FillOutlineInterpolateUBO& interp [[buffer(5)]],
device const FillOutlinePermutationUBO& permutation [[buffer(6)]],
device const ExpressionInputsUBO& expr [[buffer(7)]]) {
const auto outline_color = colorFor(permutation.outline_color, props.outline_color, vertx.outline_color, expr);
const auto opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr);
float4 position = drawable.matrix * float4(float2(vertx.position), 0.0f, 1.0f);
float2 v_pos = (position.xy / position.w + 1.0) / 2.0 * drawable.world;
return {
.position = position,
.outline_color = outline_color,
.pos = v_pos,
.opacity = half(opacity),
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const FillOutlineEvaluatedPropsUBO& props [[buffer(4)]],
device const FillOutlinePermutationUBO& permutation [[buffer(6)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
// TODO: Cause metal line primitive only support draw 1 pixel width line
// use alpha to provide edge antialiased is no point
// Should triangate the lines into triangles to support thick line and edge antialiased.
// float dist = length(in.pos - in.position.xy);
// float alpha = 1.0 - smoothstep(0.0, 1.0, dist);
return half4(in.outline_color * in.opacity);
}
)";
};
template <>
struct ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "FillPatternShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr AttributeInfo attributes[] = {
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
};
static constexpr UniformBlockInfo uniforms[] = {
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillPatternDrawableUBO),
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillPatternTilePropsUBO),
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillPatternEvaluatedPropsUBO),
MLN_MTL_UNIFORM_BLOCK(7, true, false, FillPatternInterpolateUBO),
MLN_MTL_UNIFORM_BLOCK(8, true, true, FillPatternPermutationUBO),
MLN_MTL_UNIFORM_BLOCK(9, true, false, ExpressionInputsUBO),
};
static constexpr TextureInfo textures[] = {
{0, "u_image"},
};
static constexpr auto source = R"(
struct VertexStage {
short2 position [[attribute(0)]];
ushort4 pattern_from [[attribute(1)]];
ushort4 pattern_to [[attribute(2)]];
float2 opacity [[attribute(3)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
float4 pattern_from;
float4 pattern_to;
float2 v_pos_a;
float2 v_pos_b;
half opacity;
};
struct alignas(16) FillPatternDrawableUBO {
float4x4 matrix;
float4 scale;
float2 pixel_coord_upper;
float2 pixel_coord_lower;
float2 texsize;
};
struct alignas(16) FillPatternEvaluatedPropsUBO {
float opacity;
float fade;
};
struct alignas(16) FillPatternTilePropsUBO {
float4 pattern_from;
float4 pattern_to;
};
struct alignas(16) FillPatternInterpolateUBO {
float pattern_from_t;
float pattern_to_t;
float opacity_t;
};
struct alignas(16) FillPatternPermutationUBO {
Attribute pattern_from;
Attribute pattern_to;
Attribute opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillPatternDrawableUBO& drawable [[buffer(4)]],
device const FillPatternTilePropsUBO& tileProps [[buffer(5)]],
device const FillPatternEvaluatedPropsUBO& props [[buffer(6)]],
device const FillPatternInterpolateUBO& interp [[buffer(7)]],
device const FillPatternPermutationUBO& permutation [[buffer(8)]],
device const ExpressionInputsUBO& expr [[buffer(9)]]) {
const auto pattern_from = patternFor(permutation.pattern_from, tileProps.pattern_from, vertx.pattern_from, interp.pattern_from_t, expr);
const auto pattern_to = patternFor(permutation.pattern_to, tileProps.pattern_to, vertx.pattern_to, interp.pattern_to_t, expr);
const auto opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr);
float2 pattern_tl_a = pattern_from.xy;
float2 pattern_br_a = pattern_from.zw;
float2 pattern_tl_b = pattern_to.xy;
float2 pattern_br_b = pattern_to.zw;
float pixelRatio = drawable.scale.x;
float tileZoomRatio = drawable.scale.y;
float fromScale = drawable.scale.z;
float toScale = drawable.scale.w;
float2 display_size_a = float2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio);
float2 display_size_b = float2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio);
float2 postion = float2(vertx.position);
return {
.position = drawable.matrix * float4(postion, 0, 1),
.pattern_from = pattern_from,
.pattern_to = pattern_to,
.v_pos_a = get_pattern_pos(drawable.pixel_coord_upper, drawable.pixel_coord_lower, fromScale * display_size_a, tileZoomRatio, postion),
.v_pos_b = get_pattern_pos(drawable.pixel_coord_upper, drawable.pixel_coord_lower, toScale * display_size_b, tileZoomRatio, postion),
.opacity = half(opacity),
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const FillPatternDrawableUBO& drawable [[buffer(4)]],
device const FillPatternEvaluatedPropsUBO& props [[buffer(6)]],
device const FillPatternPermutationUBO& permutation [[buffer(8)]],
texture2d<float, access::sample> image0 [[texture(0)]],
sampler image0_sampler [[sampler(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
float2 pattern_tl_a = in.pattern_from.xy;
float2 pattern_br_a = in.pattern_from.zw;
float2 pattern_tl_b = in.pattern_to.xy;
float2 pattern_br_b = in.pattern_to.zw;
float2 imagecoord = mod(in.v_pos_a, 1.0);
float2 pos = mix(pattern_tl_a / drawable.texsize, pattern_br_a / drawable.texsize, imagecoord);
float4 color1 = image0.sample(image0_sampler, pos);
float2 imagecoord_b = mod(in.v_pos_b, 1.0);
float2 pos2 = mix(pattern_tl_b / drawable.texsize, pattern_br_b / drawable.texsize, imagecoord_b);
float4 color2 = image0.sample(image0_sampler, pos2);
return half4(mix(color1, color2, props.fade) * in.opacity);
}
)";
};
template <>
struct ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "FillOutlinePatternShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr AttributeInfo attributes[] = {
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
};
static constexpr UniformBlockInfo uniforms[] = {
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillOutlinePatternDrawableUBO),
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillOutlinePatternTilePropsUBO),
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillOutlinePatternEvaluatedPropsUBO),
MLN_MTL_UNIFORM_BLOCK(7, true, false, FillOutlinePatternInterpolateUBO),
MLN_MTL_UNIFORM_BLOCK(8, true, true, FillOutlinePatternPermutationUBO),
MLN_MTL_UNIFORM_BLOCK(9, true, false, ExpressionInputsUBO),
};
static constexpr TextureInfo textures[] = {
{0, "u_image"},
};
static constexpr auto source = R"(
struct VertexStage {
short2 position [[attribute(0)]];
ushort4 pattern_from [[attribute(1)]];
ushort4 pattern_to [[attribute(2)]];
float2 opacity [[attribute(3)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
float2 v_pos_a;
float2 v_pos_b;
float4 pattern_from;
float4 pattern_to;
float2 v_pos;
half opacity;
};
struct alignas(16) FillOutlinePatternDrawableUBO {
float4x4 matrix;
float4 scale;
float2 world;
float2 pixel_coord_upper;
float2 pixel_coord_lower;
float2 texsize;
};
struct alignas(16) FillOutlinePatternEvaluatedPropsUBO {
float opacity;
float fade;
};
struct alignas(16) FillOutlinePatternTilePropsUBO {
float4 pattern_from;
float4 pattern_to;
};
struct alignas(16) FillOutlinePatternInterpolateUBO {
float pattern_from_t;
float pattern_to_t;
float opacity_t;
};
struct alignas(16) FillOutlinePatternPermutationUBO {
Attribute pattern_from;
Attribute pattern_to;
Attribute opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillOutlinePatternDrawableUBO& drawable [[buffer(4)]],
device const FillOutlinePatternTilePropsUBO& tileProps [[buffer(5)]],
device const FillOutlinePatternEvaluatedPropsUBO& props [[buffer(6)]],
device const FillOutlinePatternInterpolateUBO& interp [[buffer(7)]],
device const FillOutlinePatternPermutationUBO& permutation [[buffer(8)]],
device const ExpressionInputsUBO& expr [[buffer(9)]]) {
const auto pattern_from = patternFor(permutation.pattern_from, tileProps.pattern_from, vertx.pattern_from, interp.pattern_from_t, expr);
const auto pattern_to = patternFor(permutation.pattern_to, tileProps.pattern_to, vertx.pattern_to, interp.pattern_to_t, expr);
const auto opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr);
float2 pattern_tl_a = pattern_from.xy;
float2 pattern_br_a = pattern_from.zw;
float2 pattern_tl_b = pattern_to.xy;
float2 pattern_br_b = pattern_to.zw;
float pixelRatio = drawable.scale.x;
float tileZoomRatio = drawable.scale.y;
float fromScale = drawable.scale.z;
float toScale = drawable.scale.w;
float2 display_size_a = float2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio);
float2 display_size_b = float2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio);
float2 pos2 = float2(vertx.position);
float4 position = drawable.matrix * float4(pos2, 0, 1);
return {
.position = position,
.pattern_from = pattern_from,
.pattern_to = pattern_to,
.v_pos_a = get_pattern_pos(drawable.pixel_coord_upper, drawable.pixel_coord_lower, fromScale * display_size_a, tileZoomRatio, pos2),
.v_pos_b = get_pattern_pos(drawable.pixel_coord_upper, drawable.pixel_coord_lower, toScale * display_size_b, tileZoomRatio, pos2),
.v_pos = (position.xy / position.w + 1.0) / 2.0 * drawable.world,
.opacity = half(opacity),
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const FillOutlinePatternDrawableUBO& drawable [[buffer(4)]],
device const FillOutlinePatternEvaluatedPropsUBO& props [[buffer(6)]],
device const FillOutlinePatternPermutationUBO& permutation [[buffer(8)]],
texture2d<float, access::sample> image0 [[texture(0)]],
sampler image0_sampler [[sampler(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
float2 pattern_tl_a = in.pattern_from.xy;
float2 pattern_br_a = in.pattern_from.zw;
float2 pattern_tl_b = in.pattern_to.xy;
float2 pattern_br_b = in.pattern_to.zw;
float2 imagecoord = mod(in.v_pos_a, 1.0);
float2 pos = mix(pattern_tl_a / drawable.texsize, pattern_br_a / drawable.texsize, imagecoord);
float4 color1 = image0.sample(image0_sampler, pos);
float2 imagecoord_b = mod(in.v_pos_b, 1.0);
float2 pos2 = mix(pattern_tl_b / drawable.texsize, pattern_br_b / drawable.texsize, imagecoord_b);
float4 color2 = image0.sample(image0_sampler, pos2);
// TODO: Should triangate the lines into triangles to support thick line and edge antialiased.
//float dist = length(in.v_pos - in.position.xy);
//float alpha = 1.0 - smoothstep(0.0, 1.0, dist);
return half4(mix(color1, color2, props.fade) * in.opacity);
}
)";
};
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,141 @@
#pragma once
#include <mbgl/shaders/line_layer_ubo.hpp>
#include <mbgl/shaders/shader_source.hpp>
#include <mbgl/shaders/mtl/common.hpp>
#include <mbgl/shaders/mtl/shader_program.hpp>
namespace mbgl {
namespace shaders {
template <>
struct ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "LineShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr AttributeInfo attributes[] = {
{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
{2, gfx::AttributeDataType::Float4, 1, "a_color"},
{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
{5, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
{6, gfx::AttributeDataType::Float2, 1, "a_offset"},
{7, gfx::AttributeDataType::Float2, 1, "a_width"},
};
static constexpr UniformBlockInfo uniforms[] = {
MLN_MTL_UNIFORM_BLOCK(8, true, true, LineUBO),
MLN_MTL_UNIFORM_BLOCK(9, true, false, LinePropertiesUBO),
MLN_MTL_UNIFORM_BLOCK(10, true, false, LineInterpolationUBO),
MLN_MTL_UNIFORM_BLOCK(11, true, true, LinePermutationUBO),
MLN_MTL_UNIFORM_BLOCK(12, true, false, ExpressionInputsUBO),
};
static constexpr TextureInfo textures[] = {};
static constexpr auto source = R"(
struct VertexStage {
short2 pos_normal [[attribute(0)]];
uchar4 data [[attribute(1)]];
float4 color [[attribute(2)]];
float2 blur [[attribute(3)]];
float2 opacity [[attribute(4)]];
float2 gapwidth [[attribute(5)]];
float2 offset [[attribute(6)]];
float2 width [[attribute(7)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
float2 width2;
float2 normal;
float gamma_scale;
float4 color;
float blur;
float opacity;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const LineUBO& line [[buffer(8)]],
device const LinePropertiesUBO& props [[buffer(9)]],
device const LineInterpolationUBO& interp [[buffer(10)]],
device const LinePermutationUBO& permutation [[buffer(11)]],
device const ExpressionInputsUBO& expr [[buffer(12)]]) {
const auto color = colorFor(permutation.color, props.color, vertx.color, interp.color_t, expr);
const auto blur = valueFor(permutation.blur, props.blur, vertx.blur, interp.blur_t, expr);
const auto opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr);
const auto gapwidth = valueFor(permutation.gapwidth, props.gapwidth, vertx.gapwidth, interp.gapwidth_t, expr) / 2;
const auto offset = valueFor(permutation.offset, props.offset, vertx.offset, interp.offset_t, expr) * -1;
const auto width = valueFor(permutation.width, props.width, vertx.width, interp.width_t, expr);
// the distance over which the line edge fades out.
// Retina devices need a smaller distance to avoid aliasing.
const float ANTIALIASING = 1.0 / line.device_pixel_ratio / 2.0;
const float2 a_extrude = float2(vertx.data.xy) - 128.0;
const float a_direction = fmod(float(vertx.data.z), 4.0) - 1.0;
const float2 pos = floor(float2(vertx.pos_normal) * 0.5);
// x is 1 if it's a round cap, 0 otherwise
// y is 1 if the normal points up, and -1 if it points down
// We store these in the least significant bit of a_pos_normal
const float2 normal = float2(vertx.pos_normal) - 2.0 * pos;
const float2 v_normal = float2(normal.x, normal.y * 2.0 - 1.0);
const float halfwidth = width / 2.0;
const float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
const float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + (halfwidth == 0.0 ? 0.0 : ANTIALIASING);
// Scale the extrusion vector down to a normal and then up by the line width of this vertex.
const float2 dist = outset * a_extrude * LINE_NORMAL_SCALE;
// Calculate the offset when drawing a line that is to the side of the actual line.
// We do this by creating a vector that points towards the extrude, but rotate
// it when we're drawing round end points (a_direction = -1 or 1) since their
// extrude vector points in another direction.
const float u = 0.5 * a_direction;
const float t = 1.0 - abs(u);
const float2 offset2 = offset * a_extrude * LINE_NORMAL_SCALE * v_normal.y * float2x2(t, -u, u, t);
const float4 projected_extrude = line.matrix * float4(dist / line.ratio, 0.0, 0.0);
const float4 position = line.matrix * float4(pos + offset2 / line.ratio, 0.0, 1.0) + projected_extrude;
// calculate how much the perspective view squishes or stretches the extrude
const float extrude_length_without_perspective = length(dist);
const float extrude_length_with_perspective = length(projected_extrude.xy / position.w * line.units_to_pixels);
return {
.position = position,
.width2 = float2(outset, inset),
.normal = v_normal,
.gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective,
.color = color,
.blur = blur,
.opacity = opacity,
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const LineUBO& line [[buffer(8)]],
device const LinePermutationUBO& permutation [[buffer(11)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
// Calculate the distance of the pixel from the line in pixels.
const float dist = length(in.normal) * in.width2.x;
// Calculate the antialiasing fade factor. This is either when fading in the
// line in case of an offset line (v_width2.y) or when fading out (v_width2.x)
const float blur2 = (in.blur + 1.0 / line.device_pixel_ratio) * in.gamma_scale;
const float alpha = clamp(min(dist - (in.width2.y - blur2), in.width2.x - dist) / blur2, 0.0, 1.0);
return half4(in.color * (alpha * in.opacity));
}
)";
};
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,148 @@
#pragma once
#include <mbgl/shaders/line_layer_ubo.hpp>
#include <mbgl/shaders/shader_source.hpp>
#include <mbgl/shaders/mtl/common.hpp>
#include <mbgl/shaders/mtl/shader_program.hpp>
namespace mbgl {
namespace shaders {
template <>
struct ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "LineGradientShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr AttributeInfo attributes[] = {
{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
{2, gfx::AttributeDataType::Float2, 1, "a_blur"},
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
{4, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
{5, gfx::AttributeDataType::Float2, 1, "a_offset"},
{6, gfx::AttributeDataType::Float2, 1, "a_width"},
};
static constexpr UniformBlockInfo uniforms[] = {
MLN_MTL_UNIFORM_BLOCK(7, true, true, LineGradientUBO),
MLN_MTL_UNIFORM_BLOCK(8, true, false, LineGradientPropertiesUBO),
MLN_MTL_UNIFORM_BLOCK(9, true, false, LineGradientInterpolationUBO),
MLN_MTL_UNIFORM_BLOCK(10, true, true, LinePermutationUBO),
MLN_MTL_UNIFORM_BLOCK(11, true, false, ExpressionInputsUBO),
};
static constexpr TextureInfo textures[] = {
{0, "u_image"},
};
static constexpr auto source = R"(
struct VertexStage {
short2 pos_normal [[attribute(0)]];
uchar4 data [[attribute(1)]];
float2 blur [[attribute(3)]];
float2 opacity [[attribute(4)]];
float2 gapwidth [[attribute(5)]];
float2 offset [[attribute(6)]];
float2 width [[attribute(7)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
float2 width2;
float2 gapwidth;
float2 normal;
float gamma_scale;
float blur;
float opacity;
float lineprogress;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const LineGradientUBO& line [[buffer(7)]],
device const LineGradientPropertiesUBO& props [[buffer(8)]],
device const LineGradientInterpolationUBO& interp [[buffer(9)]],
device const LinePermutationUBO& permutation [[buffer(10)]],
device const ExpressionInputsUBO& expr [[buffer(11)]]) {
const auto blur = valueFor(permutation.blur, props.blur, vertx.blur, interp.blur_t, expr);
const auto opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr);
const auto gapwidth = valueFor(permutation.gapwidth, props.gapwidth, vertx.gapwidth, interp.gapwidth_t, expr) / 2;
const auto offset = valueFor(permutation.offset, props.offset, vertx.offset, interp.offset_t, expr) * -1;
const auto width = valueFor(permutation.width, props.width, vertx.width, interp.width_t, expr);
// the distance over which the line edge fades out.
// Retina devices need a smaller distance to avoid aliasing.
const float ANTIALIASING = 1.0 / line.device_pixel_ratio / 2.0;
const float2 a_extrude = float2(vertx.data.xy) - 128.0;
const float a_direction = fmod(float(vertx.data.z), 4.0) - 1.0;
const v_lineprogress = (floor(float(a_data.z) / 4.0) + a_data.w * 64.0) * 2.0 / MAX_LINE_DISTANCE;
const float2 pos = floor(float2(vertx.pos_normal) * 0.5);
// x is 1 if it's a round cap, 0 otherwise
// y is 1 if the normal points up, and -1 if it points down
// We store these in the least significant bit of a_pos_normal
const float2 normal = float2(vertx.pos_normal) - 2.0 * pos;
const float2 v_normal = float2(normal.x, normal.y * 2.0 - 1.0);
const float halfwidth = width / 2.0;
const float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
const float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + (halfwidth == 0.0 ? 0.0 : ANTIALIASING);
// Scale the extrusion vector down to a normal and then up by the line width of this vertex.
const float2 dist = outset * a_extrude * scale;
// Calculate the offset when drawing a line that is to the side of the actual line.
// We do this by creating a vector that points towards the extrude, but rotate
// it when we're drawing round end points (a_direction = -1 or 1) since their
// extrude vector points in another direction.
const float u = 0.5 * a_direction;
const float t = 1.0 - abs(u);
const float2 offset2 = offset * a_extrude * scale * v_normal.y * float2x2(t, -u, u, t);
const float4 projected_extrude = line.matrix * float4(dist / line.ratio, 0.0, 0.0);
const float4 position = line.matrix * float4(pos + offset2 / line.ratio, 0.0, 1.0) + projected_extrude;
// calculate how much the perspective view squishes or stretches the extrude
const float extrude_length_without_perspective = length(dist);
const float extrude_length_with_perspective = length(projected_extrude.xy / position.w * line.units_to_pixels);
return {
.position = position,
.width2 = float2(outset, inset),
.gapwidth = gapwidth,
.normal = v_normal,
.gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective,
.blur = blur,
.opacity = opacity,
.lineprogress = v_lineprogress,
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const LineGradientUBO& line [[buffer(7)]],
device const LineGradientPermutationUBO& permutation [[buffer(10)]],
metal::texture2d<float, metal::access::sample>* gradientTexture [[texture(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
// Calculate the distance of the pixel from the line in pixels.
const float dist = length(in.normal) * in.width2.x;
// Calculate the antialiasing fade factor. This is either when fading in the
// line in case of an offset line (v_width2.y) or when fading out (v_width2.x)
const float blur2 = (in.blur + 1.0 / line.device_pixel_ratio) * in.gamma_scale;
const float alpha = clamp(min(dist - (in.width2.y - blur2), in.width2.x - dist) / blur2, 0.0, 1.0);
// For gradient lines, v_lineprogress is the ratio along the entire line,
// scaled to [0, 2^15), and the gradient ramp is stored in a texture.
constexpr sampler sampler2d(coord::normalized, filter::linear);
const vec4 color = gradientTexture ? gradientTexture->sample(sampler, vec2(in.lineprogress, 0.5)) : vec4(1,0,1,1);
return half4(color * (alpha * in.opacity));
}
)";
};
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,125 @@
#pragma once
#include <mbgl/shaders/raster_layer_ubo.hpp>
#include <mbgl/shaders/shader_source.hpp>
#include <mbgl/shaders/mtl/common.hpp>
#include <mbgl/shaders/mtl/shader_program.hpp>
namespace mbgl {
namespace shaders {
template <>
struct ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "RasterShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr AttributeInfo attributes[] = {
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
};
static constexpr UniformBlockInfo uniforms[] = {
MLN_MTL_UNIFORM_BLOCK(2, true, true, RasterDrawableUBO),
};
static constexpr TextureInfo textures[] = {
{0, "u_image0"},
{1, "u_image1"},
};
static constexpr auto source = R"(
struct VertexStage {
short2 pos [[attribute(0)]];
short2 texture_pos [[attribute(1)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
float2 pos0;
float2 pos1;
};
struct alignas(16) RasterDrawableUBO {
float4x4 matrix;
float3 spin_weights;
float2 tl_parent;
float scale_parent;
float buffer_scale;
float fade_t;
float opacity;
float brightness_low;
float brightness_high;
float saturation_factor;
float contrast_factor;
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const RasterDrawableUBO& drawable [[buffer(2)]]) {
const float4 position = drawable.matrix * float4(float2(vertx.pos), 0, 1);
// We are using Int16 for texture position coordinates to give us enough precision for
// fractional coordinates. We use 8192 to scale the texture coordinates in the buffer
// as an arbitrarily high number to preserve adequate precision when rendering.
// This is also the same value as the EXTENT we are using for our tile buffer pos coordinates,
// so math for modifying either is consistent.
const float2 pos0 = (((float2(vertx.texture_pos) / 8192.0) - 0.5) / drawable.buffer_scale ) + 0.5;
const float2 pos1 = (pos0 * drawable.scale_parent) + drawable.tl_parent;
return {
.position = position,
.pos0 = pos0,
.pos1 = pos1,
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const RasterDrawableUBO& drawable [[buffer(2)]],
texture2d<float, access::sample> image0 [[texture(0)]],
texture2d<float, access::sample> image1 [[texture(1)]],
sampler image0_sampler [[sampler(0)]],
sampler image1_sampler [[sampler(1)]]) {
if (drawable.overdrawInspector) {
return half4(1.0);
}
// read and cross-fade colors from the main and parent tiles
float4 color0 = image0.sample(image0_sampler, in.pos0);
float4 color1 = image1.sample(image1_sampler, in.pos1);
if (color0.a > 0.0) {
color0.rgb = color0.rgb / color0.a;
}
if (color1.a > 0.0) {
color1.rgb = color1.rgb / color1.a;
}
float4 color = mix(color0, color1, drawable.fade_t);
color.a *= drawable.opacity;
float3 rgb = color.rgb;
// spin
rgb = float3(
dot(rgb, drawable.spin_weights.xyz),
dot(rgb, drawable.spin_weights.zxy),
dot(rgb, drawable.spin_weights.yzx));
// saturation
float average = (color.r + color.g + color.b) / 3.0;
rgb += (average - rgb) * drawable.saturation_factor;
// contrast
rgb = (rgb - 0.5) * drawable.contrast_factor + 0.5;
// brightness
float3 high_vec = float3(drawable.brightness_low, drawable.brightness_low, drawable.brightness_low);
float3 low_vec = float3(drawable.brightness_high, drawable.brightness_high, drawable.brightness_high);
return half4(half3(mix(high_vec, low_vec, rgb) * color.a), color.a);
}
)";
};
} // namespace shaders
} // namespace mbgl

View File

@@ -0,0 +1,76 @@
#pragma once
#include <mbgl/gfx/shader_group.hpp>
#include <mbgl/programs/program_parameters.hpp>
#include <mbgl/shaders/mtl/background.hpp>
#include <mbgl/shaders/mtl/shader_program.hpp>
#include <mbgl/shaders/shader_source.hpp>
#include <numeric>
#include <string>
#include <unordered_map>
namespace mbgl {
namespace mtl {
template <shaders::BuiltIn ShaderID>
class ShaderGroup final : public gfx::ShaderGroup {
public:
ShaderGroup(const ProgramParameters& programParameters_)
: gfx::ShaderGroup(),
programParameters(programParameters_) {}
~ShaderGroup() noexcept override = default;
gfx::ShaderPtr getOrCreateShader(gfx::Context& gfxContext,
const std::vector<std::string>& propertiesAsUniforms,
std::string_view /*firstAttribName*/) override {
constexpr auto& name = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::name;
constexpr auto& source = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::source;
constexpr auto& vertMain = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::vertexMainFunction;
constexpr auto& fragMain = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::fragmentMainFunction;
uint32_t key = 0;
assert(propertiesAsUniforms.size() < 32);
std::unordered_map<std::string, std::string> additionalDefines(propertiesAsUniforms.size());
for (unsigned int i = 0; i < propertiesAsUniforms.size(); i++) {
if (!propertiesAsUniforms[i].empty()) {
key |= 1U << i;
auto name = std::string("HAS_UNIFORM_u_") + propertiesAsUniforms[i];
additionalDefines.insert(std::make_pair(std::move(name), "1"));
}
}
const std::string shaderName = std::string(name); // + "#" + std::to_string(key);
const auto shaderSource = std::string(shaders::prelude) + source;
auto shader = get<mtl::ShaderProgram>(shaderName);
if (!shader) {
auto& context = static_cast<Context&>(gfxContext);
shader = context.createProgram(
shaderName, shaderSource, vertMain, fragMain, programParameters, additionalDefines);
assert(shader);
if (!shader || !registerShader(shader, shaderName)) {
assert(false);
throw std::runtime_error("Failed to register " + shaderName + " with shader group!");
}
using ShaderClass = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>;
for (const auto& attrib : ShaderClass::attributes) {
shader->initAttribute(attrib);
}
for (const auto& uniform : ShaderClass::uniforms) {
shader->initUniformBlock(uniform);
}
for (const auto& texture : ShaderClass::textures) {
shader->initTexture(texture);
}
}
return shader;
}
private:
ProgramParameters programParameters;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,79 @@
#pragma once
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/mtl/mtl_fwd.hpp>
#include <mbgl/mtl/uniform_block.hpp>
#include <mbgl/mtl/vertex_attribute.hpp>
#include <Foundation/NSSharedPtr.hpp>
#include <Metal/MTLLibrary.hpp>
#include <optional>
#include <string>
#include <vector>
namespace mbgl {
namespace shaders {
struct AttributeInfo {
std::size_t index;
gfx::AttributeDataType dataType;
std::size_t count;
std::string_view name;
};
struct UniformBlockInfo {
std::size_t index;
bool vertex;
bool fragment;
std::size_t size;
std::string_view name;
};
struct TextureInfo {
std::size_t index;
std::string_view name;
};
} // namespace shaders
namespace mtl {
class RenderableResource;
class RendererBackend;
class ShaderProgram;
using UniqueShaderProgram = std::unique_ptr<ShaderProgram>;
class ShaderProgram final : public gfx::ShaderProgramBase {
public:
ShaderProgram(std::string name,
RendererBackend& backend,
MTLFunctionPtr vertexFunction,
MTLFunctionPtr fragmentFunction);
~ShaderProgram() noexcept override = default;
static constexpr std::string_view Name{"GenericMTLShader"};
const std::string_view typeName() const noexcept override { return Name; }
MTLRenderPipelineStatePtr getRenderPipelineState(const gfx::RenderPassDescriptor&,
const MTLVertexDescriptorPtr&,
const gfx::ColorMode& colorMode) const;
std::optional<uint32_t> getSamplerLocation(std::string_view name) const override;
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }
gfx::VertexAttributeArray& mutableVertexAttributes() override { return vertexAttributes; }
const gfx::UniformBlockArray& getUniformBlocks() const override { return uniformBlocks; }
gfx::UniformBlockArray& mutableUniformBlocks() override { return uniformBlocks; }
void initAttribute(const shaders::AttributeInfo&);
void initUniformBlock(const shaders::UniformBlockInfo&);
void initTexture(const shaders::TextureInfo&);
protected:
std::string shaderName;
RendererBackend& backend;
MTLFunctionPtr vertexFunction;
MTLFunctionPtr fragmentFunction;
UniformBlockArray uniformBlocks;
VertexAttributeArray vertexAttributes;
std::vector<std::string> textureBindings;
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,28 @@
#pragma once
#include <mbgl/shaders/layer_ubo.hpp>
namespace mbgl {
namespace shaders {
struct alignas(16) RasterDrawableUBO {
std::array<float, 4 * 4> matrix;
std::array<float, 4> spin_weights;
std::array<float, 2> tl_parent;
float scale_parent;
float buffer_scale;
float fade_t;
float opacity;
float brightness_low;
float brightness_high;
float saturation_factor;
float contrast_factor;
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4;
};
static_assert(sizeof(RasterDrawableUBO) == 128);
static_assert(sizeof(RasterDrawableUBO) % 16 == 0);
} // namespace shaders
} // namespace mbgl

View File

@@ -2,7 +2,7 @@
#pragma once
#include <mbgl/shaders/shader_source.hpp>
#ifdef MBGL_RENDER_BACKEND_OPENGL
#if !MLN_RENDER_BACKEND_METAL
#include <mbgl/shaders/gl/drawable_background.hpp>
#include <mbgl/shaders/gl/drawable_background_pattern.hpp>
#include <mbgl/shaders/gl/drawable_circle.hpp>

View File

@@ -1,3 +1,5 @@
#pragma once
#include <mbgl/util/util.hpp>
#include <algorithm>

View File

@@ -10,7 +10,12 @@ objc_library(
"//platform/ios:ios_private_hdrs",
"//platform/ios:ios_public_hdrs",
"//platform/ios:ios_sdk_hdrs",
],
] + select({
"//:metal_renderer": [],
"//conditions:default": [
"//platform/darwin:darwin_objcpp_opengl_srcs",
],
}),
copts = CPP_FLAGS + MAPLIBRE_FLAGS + [
"-fcxx-modules",
"-fmodules",
@@ -28,10 +33,16 @@ objc_library(
"CoreImage",
"CoreGraphics",
"CoreLocation",
"GLKit",
"OpenGLES",
"QuartzCore",
],
] + select({
"//:metal_renderer": [
"MetalKit"
],
"//conditions:default": [
"OpenGLES",
"GLKit"
],
}),
deps = [
":objc-headers",
"//:mbgl-core",
@@ -110,7 +121,12 @@ objc_library(
"//platform/darwin:darwin_objc_hdrs",
"//platform/darwin:generated_style_public_hdrs",
"//platform/ios:ios_sdk_hdrs",
],
] + select({
"//:metal_renderer": [],
"//conditions:default": [
"//platform/darwin:darwin_objc_opengl_hdrs",
],
}),
data = ["//platform/ios:resources"],
module_name = "MapLibre",
sdk_dylibs = [
@@ -154,10 +170,14 @@ objc_library(
objc_library(
name = "iosapp",
srcs = [
"//platform/darwin:app/LimeGreenStyleLayer.h",
"//platform/darwin:app/LimeGreenStyleLayer.m",
"//platform/ios:ios_app_srcs",
],
] + select({
"//:metal_renderer": [],
"//conditions:default": [
"//platform/darwin:app/LimeGreenStyleLayer.h",
"//platform/darwin:app/LimeGreenStyleLayer.m",
],
}),
data = glob([
"app/Assets.xcassets/**",
]),
@@ -168,8 +188,13 @@ objc_library(
"ios/src",
],
sdk_frameworks = [
"GLKit", # needed for LimeGreenStyleLayer
],
] + select({
"//:metal_renderer": [
"MetalKit"
],
"//conditions:default": [
"GLKit", # needed for LimeGreenStyleLayer
]}),
visibility = ["//visibility:public"],
deps = [
":ios-sdk",
@@ -214,7 +239,14 @@ sh_binary(
"//platform/macos:macos_objcpp_srcs",
"//platform/macos:macos_private_hdrs",
"//platform/macos:macos_public_hdrs",
],
] + select({
"//:metal_renderer": [],
"//conditions:default": [
"//platform/darwin:darwin_private_opengl_hdrs",
"//platform/darwin:darwin_objc_opengl_hdrs",
"//platform/darwin:darwin_objcpp_opengl_srcs",
],
}),
deps = [
"//platform/darwin:generated_code",
],

View File

@@ -61,7 +61,7 @@ android {
externalNativeBuild {
cmake {
arguments "-DMLN_LEGACY_RENDERER=ON", "-DMLN_DRAWABLE_RENDERER=OFF", "-DMLN_RENDERER_SPLIT_VIEW=OFF"
arguments "-DMLN_LEGACY_RENDERER=ON", "-DMLN_DRAWABLE_RENDERER=OFF"
}
}
}
@@ -72,7 +72,7 @@ android {
dimension = "renderer"
externalNativeBuild {
cmake {
arguments "-DMLN_LEGACY_RENDERER=ON", "-DMLN_DRAWABLE_RENDERER=OFF", "-DMLN_RENDERER_SPLIT_VIEW=OFF"
arguments "-DMLN_LEGACY_RENDERER=ON", "-DMLN_DRAWABLE_RENDERER=OFF"
}
}
}
@@ -80,7 +80,7 @@ android {
dimension = "renderer"
externalNativeBuild {
cmake {
arguments "-DMLN_LEGACY_RENDERER=OFF", "-DMLN_DRAWABLE_RENDERER=ON", "-DMLN_RENDERER_SPLIT_VIEW=OFF"
arguments "-DMLN_LEGACY_RENDERER=OFF", "-DMLN_DRAWABLE_RENDERER=ON"
}
}
}
@@ -156,4 +156,4 @@ apply from: "${rootDir}/gradle/gradle-update-vendor-modules.gradle"
apply from: "${rootDir}/gradle/android-nitpick.gradle"
apply from: "${rootDir}/gradle/gradle-publish.gradle"
// intentionally disabled
// apply from: "${rootDir}/gradle/jacoco-report.gradle"
// apply from: "${rootDir}/gradle/jacoco-report.gradle"

View File

@@ -110,4 +110,4 @@ apply from: "${rootDir}/gradle/gradle-lint.gradle"
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android'

View File

@@ -3,8 +3,11 @@ load(
"bazel/files.bzl",
"MLN_DARWIN_OBJCPP_HEADERS",
"MLN_DARWIN_OBJC_HEADERS",
"MLN_DARWIN_OBJC_OPENGL_HEADERS",
"MLN_DARWIN_PRIVATE_HEADERS",
"MLN_DARWIN_PRIVATE_OPENGL_HEADERS",
"MLN_DARWIN_PUBLIC_OBJCPP_SOURCE",
"MLN_DARWIN_PUBLIC_OBJCPP_OPENGL_SOURCE",
"MLN_DARWIN_PUBLIC_OBJC_SOURCE",
"MLN_GENERATED_DARWIN_STYLE_HEADERS",
"MLN_GENERATED_DARWIN_STYLE_PUBLIC_HEADERS",
@@ -21,12 +24,22 @@ filegroup(
srcs = MLN_DARWIN_PRIVATE_HEADERS,
visibility = ["//visibility:public"],
)
filegroup(
name = "darwin_private_opengl_hdrs",
srcs = MLN_DARWIN_PRIVATE_OPENGL_HEADERS,
visibility = ["//visibility:public"],
)
filegroup(
name = "darwin_objc_hdrs",
srcs = MLN_DARWIN_OBJC_HEADERS,
visibility = ["//visibility:public"],
)
filegroup(
name = "darwin_objc_opengl_hdrs",
srcs = MLN_DARWIN_OBJC_OPENGL_HEADERS,
visibility = ["//visibility:public"],
)
filegroup(
name = "darwin_objcpp_hdrs",
@@ -39,6 +52,11 @@ filegroup(
srcs = MLN_DARWIN_PUBLIC_OBJCPP_SOURCE,
visibility = ["//visibility:public"],
)
filegroup(
name = "darwin_objcpp_opengl_srcs",
srcs = MLN_DARWIN_PUBLIC_OBJCPP_OPENGL_SOURCE,
visibility = ["//visibility:public"],
)
filegroup(
name = "darwin_objc_srcs",
@@ -247,7 +265,6 @@ objc_library(
srcs = [
"src/CFHandle.hpp",
"src/collator.mm",
"src/headless_backend_eagl.mm",
"src/http_file_source.mm",
"src/image.mm",
"src/local_glyph_rasterizer.mm",
@@ -255,7 +272,10 @@ objc_library(
"src/nsthread.mm",
"src/number_format.mm",
"src/string_nsstring.mm",
],
] + select({
"//:metal_renderer": [],
"//conditions:default": ["src/headless_backend_eagl.mm"],
}),
hdrs = [
"include/mbgl/interface/native_apple_interface.h",
"include/mbgl/storage/reachability.h",
@@ -286,19 +306,23 @@ objc_library(
name = "darwin-loop",
srcs = [
"src/async_task.cpp",
"src/gl_functions.cpp",
"src/run_loop.cpp",
"src/timer.cpp",
],
] + select({
"//:metal_renderer": [],
"//conditions:default": ["src/gl_functions.cpp"],
}),
copts = CPP_FLAGS + MAPLIBRE_FLAGS,
defines = [
"GLES_SILENCE_DEPRECATION=1",
"GL_SILENCE_DEPRECATION=1",
],
sdk_frameworks = [
"OpenGLES",
"SystemConfiguration",
],
] + select({
"//:metal_renderer": ["Metal"],
"//conditions:default": ["OpenGLES"],
}),
visibility = ["//visibility:public"],
deps = [
"//:mbgl-core",
@@ -316,7 +340,10 @@ exports_files(
"scripts/check-public-symbols.sh",
] + MLN_DARWIN_PUBLIC_OBJC_SOURCE +
MLN_DARWIN_PUBLIC_OBJCPP_SOURCE +
MLN_DARWIN_PUBLIC_OBJCPP_OPENGL_SOURCE +
MLN_DARWIN_PRIVATE_HEADERS +
MLN_DARWIN_PRIVATE_OPENGL_HEADERS +
MLN_DARWIN_OBJC_HEADERS +
MLN_DARWIN_OBJC_OPENGL_HEADERS +
MLN_DARWIN_OBJCPP_HEADERS,
)

View File

@@ -74,7 +74,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",
@@ -101,6 +100,8 @@ MLN_DARWIN_OBJC_HEADERS = [
"src/NSPredicate+MLNAdditions.h",
"src/NSValue+MLNAdditions.h",
]
MLN_DARWIN_OBJC_OPENGL_HEADERS = [
]
MLN_DARWIN_OBJCPP_HEADERS = [
"src/MLNConversion.h",
@@ -137,7 +138,6 @@ MLN_DARWIN_PRIVATE_HEADERS = [
"src/MLNOfflinePack_Private.h",
"src/MLNOfflineRegion_Private.h",
"src/MLNOfflineStorage_Private.h",
"src/MLNOpenGLStyleLayer_Private.h",
"src/MLNPointCollection_Private.h",
"src/MLNPolygon_Private.h",
"src/MLNPolyline_Private.h",
@@ -156,6 +156,8 @@ MLN_DARWIN_PRIVATE_HEADERS = [
"src/NSExpression+MLNPrivateAdditions.h",
"src/NSPredicate+MLNPrivateAdditions.h",
]
MLN_DARWIN_PRIVATE_OPENGL_HEADERS = [
]
MLN_DARWIN_PUBLIC_OBJCPP_SOURCE = [
"src/MLNAttributionInfo.mm",
@@ -173,7 +175,6 @@ MLN_DARWIN_PUBLIC_OBJCPP_SOURCE = [
"src/MLNNetworkConfiguration.mm",
"src/MLNOfflinePack.mm",
"src/MLNOfflineStorage.mm",
"src/MLNOpenGLStyleLayer.mm",
"src/MLNPointAnnotation.mm",
"src/MLNPointCollection.mm",
"src/MLNPolygon.mm",
@@ -206,6 +207,11 @@ 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_OBJC_SOURCE = [
"src/MLNAttributedExpression.m",

View File

@@ -12,7 +12,6 @@
#import "MLNHillshadeStyleLayer.h"
#import "MLNRasterStyleLayer.h"
#import "MLNBackgroundStyleLayer.h"
#import "MLNOpenGLStyleLayer.h"
#import "MLNStyleLayerManager.h"
#import "MLNSource.h"
@@ -40,6 +39,10 @@
#import "NSDate+MLNAdditions.h"
#if !MLN_RENDER_BACKEND_METAL
#import "MLNOpenGLStyleLayer.h"
#endif
#if TARGET_OS_IPHONE
#import "UIImage+MLNAdditions.h"
#else

View File

@@ -9,7 +9,10 @@
#import "MLNLineStyleLayer_Private.h"
#import "MLNRasterStyleLayer_Private.h"
#import "MLNSymbolStyleLayer_Private.h"
#if !MLN_RENDER_BACKEND_METAL
#import "MLNOpenGLStyleLayer_Private.h"
#endif
#include <vector>
@@ -63,7 +66,7 @@ LayerManagerDarwin::LayerManagerDarwin() {
#endif
#if defined(MBGL_LAYER_CUSTOM_DISABLE_RUNTIME)
addLayerTypeCoreOnly(std::make_unique<CustomLayerFactory>());
#elif !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
#elif !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL) && !MLN_RENDER_BACKEND_METAL
addLayerType(std::make_unique<OpenGLStyleLayerPeerFactory>());
#endif
}

View File

@@ -232,7 +232,9 @@
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
}
- (void)testRemovingLayerBeforeAddingSameLayer {

View File

@@ -32,7 +32,6 @@ cc_library(
srcs = [
"src/mbgl/gfx/headless_backend.cpp",
"src/mbgl/gfx/headless_frontend.cpp",
"src/mbgl/gl/headless_backend.cpp",
"src/mbgl/map/map_snapshotter.cpp",
"src/mbgl/platform/time.cpp",
"src/mbgl/storage/asset_file_source.cpp",
@@ -56,6 +55,9 @@ cc_library(
"src/mbgl/util/thread_local.cpp",
"src/mbgl/util/utf.cpp",
] + select({
"//:metal_renderer": [],
"//conditions:default": ["src/mbgl/gl/headless_backend.cpp"],
}) + select({
"//:linux": [
"src/mbgl/i18n/number_format.cpp",
"src/mbgl/layermanager/layer_manager.cpp",
@@ -77,7 +79,6 @@ cc_library(
hdrs = [
"include/mbgl/gfx/headless_backend.hpp",
"include/mbgl/gfx/headless_frontend.hpp",
"include/mbgl/gl/headless_backend.hpp",
"include/mbgl/map/map_snapshotter.hpp",
"include/mbgl/storage/file_source_request.hpp",
"include/mbgl/storage/local_file_request.hpp",
@@ -87,7 +88,10 @@ cc_library(
"include/mbgl/storage/offline_schema.hpp",
"include/mbgl/storage/sqlite3.hpp",
"include/mbgl/text/unaccent.hpp",
],
] + select({
"//:metal_renderer": [],
"//conditions:default": ["include/mbgl/gl/headless_backend.hpp"],
}),
copts = CPP_FLAGS + MAPLIBRE_FLAGS,
includes = [
"include",

View File

@@ -24,7 +24,11 @@ public:
static std::unique_ptr<HeadlessBackend> Create(const Size size = {256, 256},
SwapBehaviour swapBehavior = SwapBehaviour::NoFlush,
const gfx::ContextMode contextMode = gfx::ContextMode::Unique) {
#if MLN_RENDER_BACKEND_METAL
return nullptr;
#else // MLN_RENDER_BACKEND_OPENGL
return Backend::Create<HeadlessBackend, Size, SwapBehaviour, gfx::ContextMode>(size, swapBehavior, contextMode);
#endif
}
virtual PremultipliedImage readStillImage() = 0;

View File

@@ -61,7 +61,7 @@ LayerManagerDefault::LayerManagerDefault() {
#if !defined(MBGL_LAYER_HEATMAP_DISABLE_ALL)
addLayerType(std::make_unique<HeatmapLayerFactory>());
#endif
#ifdef MBGL_RENDER_BACKEND_OPENGL
#ifdef MLN_RENDER_BACKEND_OPENGL
#if !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
addLayerType(std::make_unique<CustomLayerFactory>());
#endif

View File

@@ -36,7 +36,7 @@ if(MLN_WITH_OPENGL)
)
target_compile_definitions(
mbgl-glfw
PRIVATE MBGL_RENDER_BACKEND_OPENGL=1
PRIVATE MLN_RENDER_BACKEND_OPENGL=1
)
endif()

View File

@@ -55,7 +55,7 @@
#include <utility>
#include <sstream>
#if defined(MBGL_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_LOCATION_INDICATOR_DISABLE_ALL)
#if defined(MLN_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_LOCATION_INDICATOR_DISABLE_ALL)
#include <mbgl/style/layers/location_indicator_layer.hpp>
namespace {
@@ -824,7 +824,7 @@ void GLFWView::onScroll(GLFWwindow *window, double /*xOffset*/, double yOffset)
}
view->map->scaleBy(scale, mbgl::ScreenCoordinate{view->lastX, view->lastY});
#if defined(MBGL_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
#if defined(MLN_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
if (view->puck && view->puckFollowsCameraCenter) {
mbgl::LatLng mapCenter = view->map->getCameraOptions().center.value();
view->puck->setLocation(toArray(mapCenter));
@@ -899,7 +899,7 @@ void GLFWView::onMouseMove(GLFWwindow *window, double x, double y) {
}
view->lastX = x;
view->lastY = y;
#if defined(MBGL_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
#if defined(MLN_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
if (view->puck && view->puckFollowsCameraCenter) {
mbgl::LatLng mapCenter = view->map->getCameraOptions().center.value();
view->puck->setLocation(toArray(mapCenter));
@@ -1034,7 +1034,7 @@ void GLFWView::setWindowTitle(const std::string &title) {
}
void GLFWView::onDidFinishLoadingStyle() {
#if defined(MBGL_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
#if defined(MLN_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
puck = nullptr;
#endif
@@ -1099,7 +1099,7 @@ void GLFWView::toggleCustomSource() {
}
void GLFWView::toggleLocationIndicatorLayer() {
#if defined(MBGL_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_LOCATION_INDICATOR_DISABLE_ALL)
#if defined(MLN_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_LOCATION_INDICATOR_DISABLE_ALL)
puck = static_cast<mbgl::style::LocationIndicatorLayer *>(map->getStyle().getLayer("puck"));
static const mbgl::LatLng puckLocation{35.683389, 139.76525}; // A location on the crossing of 4 tiles
if (puck == nullptr) {
@@ -1162,7 +1162,7 @@ void GLFWView::toggleLocationIndicatorLayer() {
using Nanoseconds = std::chrono::nanoseconds;
void GLFWView::onWillStartRenderingFrame() {
#if defined(MBGL_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_LOCATION_INDICATOR_DISABLE_ALL)
#if defined(MLN_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_LOCATION_INDICATOR_DISABLE_ALL)
puck = static_cast<mbgl::style::LocationIndicatorLayer *>(map->getStyle().getLayer("puck"));
if (puck) {
uint64_t ns = mbgl::Clock::now().time_since_epoch().count();

View File

@@ -5,7 +5,7 @@
#include <mbgl/util/geometry.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/timer.hpp>
#if defined(MBGL_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
#if defined(MLN_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
#include <mbgl/style/layers/location_indicator_layer.hpp>
#endif
@@ -160,7 +160,7 @@ private:
mbgl::ResourceOptions mapResourceOptions;
mbgl::ClientOptions mapClientOptions;
#if defined(MBGL_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
#if defined(MLN_RENDER_BACKEND_OPENGL) && !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL)
bool puckFollowsCameraCenter = false;
mbgl::style::LocationIndicatorLayer *puck = nullptr;
#endif

View File

@@ -14,6 +14,8 @@ load(
"MLN_IOS_PRIVATE_HEADERS",
"MLN_IOS_PUBLIC_HEADERS",
"MLN_IOS_PUBLIC_OBJCPP_SOURCE",
"MLN_IOS_PUBLIC_OBJCPP_OPENGL_SOURCE",
"MLN_IOS_PUBLIC_OBJCPP_METAL_SOURCE",
"MLN_IOS_PUBLIC_OBJC_SOURCE",
"MLN_IOS_SDK_HEADERS",
"MLN_PUBLIC_IOS_APP_SOPURCE",
@@ -42,7 +44,10 @@ filegroup(
filegroup(
name = "ios_objcpp_srcs",
srcs = MLN_IOS_PUBLIC_OBJCPP_SOURCE,
srcs = MLN_IOS_PUBLIC_OBJCPP_SOURCE + select({
"//:metal_renderer": MLN_IOS_PUBLIC_OBJCPP_METAL_SOURCE,
"//conditions:default": MLN_IOS_PUBLIC_OBJCPP_OPENGL_SOURCE,
}),
visibility = ["//visibility:public"],
)
@@ -74,7 +79,13 @@ apple_static_xcframework(
":ios_sdk_hdrs",
"//platform/darwin:darwin_objc_hdrs",
"//platform/darwin:darwin_objcpp_hdrs",
],
] + select({
"//:metal_renderer": [],
"//conditions:default": [
"//platform/darwin:darwin_objc_opengl_hdrs",
"//platform/darwin:darwin_objcpp_opengl_hdrs"
],
}),
umbrella_header = "src/Mapbox.h",
visibility = ["//visibility:public"],
deps = ["//platform:ios-sdk"],
@@ -114,7 +125,13 @@ apple_xcframework(
":ios_sdk_hdrs",
"//platform/darwin:darwin_objc_hdrs",
"//platform/darwin:darwin_objcpp_hdrs",
],
] + select({
"//:metal_renderer": [],
"//conditions:default": [
"//platform/darwin:darwin_objc_opengl_hdrs",
"//platform/darwin:darwin_objcpp_opengl_hdrs"
],
}),
umbrella_header = "src/Mapbox.h",
visibility = ["//visibility:public"],
deps = ["//platform:ios-sdk-dynamic"],
@@ -307,6 +324,8 @@ exports_files(
MLN_IOS_PUBLIC_HEADERS +
MLN_IOS_PRIVATE_HEADERS +
MLN_IOS_PUBLIC_OBJCPP_SOURCE +
MLN_IOS_PUBLIC_OBJCPP_METAL_SOURCE +
MLN_IOS_PUBLIC_OBJCPP_OPENGL_SOURCE +
MLN_IOS_PUBLIC_OBJC_SOURCE +
MLN_PUBLIC_IOS_APP_SOPURCE,
MLN_PUBLIC_IOS_APP_SOPURCE
)

View File

@@ -7,13 +7,16 @@
#import "MBXOfflinePacksTableViewController.h"
#import "MBXAnnotationView.h"
#import "MBXUserLocationAnnotationView.h"
#import "LimeGreenStyleLayer.h"
#import "MBXEmbeddedMapViewController.h"
#import "MBXOrnamentsViewController.h"
#import "MBXStateManager.h"
#import "MBXState.h"
#import "MLNSettings.h"
#if !MLN_RENDER_BACKEND_METAL
#import "LimeGreenStyleLayer.h"
#endif
#import "MBXFrameTimeGraphView.h"
#import "MLNMapView_Experimental.h"
#import <objc/runtime.h>
@@ -98,7 +101,9 @@ typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
MBXSettingsRuntimeStylingRasterTileSource,
MBXSettingsRuntimeStylingImageSource,
MBXSettingsRuntimeStylingRouteLine,
#if !MLN_RENDER_BACKEND_METAL
MBXSettingsRuntimeStylingAddLimeGreenTriangleLayer,
#endif
MBXSettingsRuntimeStylingDDSPolygon,
MBXSettingsRuntimeStylingCustomLatLonGrid,
MBXSettingsRuntimeStylingLineGradient,
@@ -640,9 +645,11 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
case MBXSettingsRuntimeStylingRouteLine:
[self styleRouteLine];
break;
#if !MLN_RENDER_BACKEND_METAL
case MBXSettingsRuntimeStylingAddLimeGreenTriangleLayer:
[self styleAddLimeGreenTriangleLayer];
break;
#endif
case MBXSettingsRuntimeStylingDDSPolygon:
[self stylePolygonWithDDS];
break;
@@ -1583,11 +1590,13 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
[self.mapView.style addLayer:routeLayer];
}
#if !MLN_RENDER_BACKEND_METAL
- (void)styleAddLimeGreenTriangleLayer
{
LimeGreenStyleLayer *layer = [[LimeGreenStyleLayer alloc] initWithIdentifier:@"mbx-custom"];
[self.mapView.style addLayer:layer];
}
#endif
- (void)stylePolygonWithDDS {
CLLocationCoordinate2D leftCoords[] = {

View File

@@ -19,6 +19,7 @@ MLN_IOS_PUBLIC_HEADERS = [
"src/MLNFaux3DUserLocationAnnotationView.h",
"src/MLNMapAccessibilityElement.h",
"src/MLNMapView+Impl.h",
"src/MLNMapView+Metal.h",
"src/MLNMapView+OpenGL.h",
"src/MLNScaleBar.h",
"src/MLNUserLocationHeadingArrowLayer.h",
@@ -66,11 +67,16 @@ MLN_IOS_PUBLIC_OBJCPP_SOURCE = [
"src/MLNMapProjection.mm",
"src/MLNMapView.mm",
"src/MLNMapView+Impl.mm",
"src/MLNMapView+OpenGL.mm",
"src/MLNScaleBar.mm",
"src/UIColor+MLNAdditions.mm",
"src/UIImage+MLNAdditions.mm",
]
MLN_IOS_PUBLIC_OBJCPP_OPENGL_SOURCE = [
"src/MLNMapView+OpenGL.mm",
]
MLN_IOS_PUBLIC_OBJCPP_METAL_SOURCE = [
"src/MLNMapView+Metal.mm",
]
MLN_PUBLIC_IOS_APP_SOPURCE = [
"app/MBXAnnotationView.m",

View File

@@ -82,4 +82,5 @@ cat > platform/ios/bazel/config.bzl <<EOF
APPLE_MOBILE_PROVISIONING_PROFILE_TEAM_ID = "$teamid"
APPLE_MOBILE_PROVISIONING_PROFILE_NAME = "iOS Team Provisioning Profile: *"
BUNDLE_ID_PREFIX = "$bundleidprefix"
BUILD_MODE = "bazel"
EOF

View File

@@ -35,7 +35,7 @@ while [[ $# -gt 0 ]]; do
;;
--apikey)
shift
args+=("--token" "$1")
token="$1"
shift
;;
-*|--*)
@@ -45,6 +45,10 @@ while [[ $# -gt 0 ]]; do
esac
done
if [ ! -z "$token" ]; then
args+=("--token" "$token")
fi
bash "platform/ios/scripts/bazel-generate-plists.sh" "${args[@]}"
echo "------ Building Maplibre version: $sem_version hash: $hash ------"

View File

@@ -1,10 +1,20 @@
#import "MLNMapView+Impl.h"
#import "MLNMapView+OpenGL.h"
#import "MLNMapView_Private.h"
#import "MLNStyle_Private.h"
#import "NSBundle+MLNAdditions.h"
#if MLN_RENDER_BACKEND_METAL
#import "MLNMapView+Metal.h"
#else // MLN_RENDER_BACKEND_OPENGL
#import "MLNMapView+OpenGL.h"
#endif
std::unique_ptr<MLNMapViewImpl> MLNMapViewImpl::Create(MLNMapView* nativeView) {
#if MLN_RENDER_BACKEND_METAL
return std::make_unique<MLNMapViewMetalImpl>(nativeView);
#else // MLN_RENDER_BACKEND_OPENGL
return std::make_unique<MLNMapViewOpenGLImpl>(nativeView);
#endif
}
MLNMapViewImpl::MLNMapViewImpl(MLNMapView* nativeView_) : mapView(nativeView_) {

View File

@@ -0,0 +1,54 @@
#import "MLNMapView+Impl.h"
#import "MLNMapView_Private.h"
#include <mbgl/gfx/renderable.hpp>
#include <mbgl/mtl/renderer_backend.hpp>
@class MLNMapViewImplDelegate;
/// Adapter responsible for bridging calls from mbgl to MLNMapView and Cocoa.
class MLNMapViewMetalImpl final : public MLNMapViewImpl,
public mbgl::mtl::RendererBackend,
public mbgl::gfx::Renderable {
public:
MLNMapViewMetalImpl(MLNMapView*);
~MLNMapViewMetalImpl() override;
public:
void restoreFramebufferBinding();
// Implementation of mbgl::gfx::RendererBackend
public:
mbgl::gfx::Renderable& getDefaultRenderable() override {
return *this;
}
private:
void activate() override;
void deactivate() override;
// End implementation of mbgl::gfx::RendererBackend
// Implementation of mbgl::gl::RendererBackend
public:
void updateAssumedState() override;
// End implementation of mbgl::gl::Rendererbackend
// Implementation of MLNMapViewImpl
public:
mbgl::gfx::RendererBackend& getRendererBackend() override {
return *this;
}
void setOpaque(bool) override;
void display() override;
void setPresentsWithTransaction(bool) override;
void createView() override;
UIView* getView() override;
void deleteView() override;
UIImage* snapshot() override;
void layoutChanged() override;
// End implementation of MLNMapViewImpl
private:
bool presentsWithTransaction = false;
};

View File

@@ -0,0 +1,212 @@
#import "MLNFoundation_Private.h"
#import "MLNLoggingConfiguration_Private.h"
#import "MLNMapView+Metal.h"
#import <mbgl/mtl/renderable_resource.hpp>
#import <MetalKit/MetalKit.h>
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#import <Metal/Metal.hpp>
@interface MLNMapViewImplDelegate : NSObject <MTKViewDelegate>
@end
@implementation MLNMapViewImplDelegate {
MLNMapViewMetalImpl* _impl;
}
- (instancetype)initWithImpl:(MLNMapViewMetalImpl*)impl {
if (self = [super init]) {
_impl = impl;
}
return self;
}
- (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size {}
- (void)drawInMTKView:(MTKView *)view {
_impl->render();
}
@end
namespace {
CGFloat contentScaleFactor() {
return [UIScreen instancesRespondToSelector:@selector(nativeScale)]
? [[UIScreen mainScreen] nativeScale]
: [[UIScreen mainScreen] scale];
}
} // namespace
class MLNMapViewMetalRenderableResource final : public mbgl::mtl::RenderableResource {
public:
MLNMapViewMetalRenderableResource(MLNMapViewMetalImpl& backend_)
: backend(backend_),
delegate([[MLNMapViewImplDelegate alloc] initWithImpl:&backend]) {
}
void bind() override {
if (!commandQueue) {
commandQueue = [mtlView.device newCommandQueue];
}
commandBuffer = [commandQueue commandBuffer];
commandBufferPtr = NS::RetainPtr((__bridge MTL::CommandBuffer*)commandBuffer);
currentDrawable = [mtlView currentDrawable];
}
const mbgl::mtl::RendererBackend& getBackend() const override { return backend; }
const mbgl::mtl::MTLCommandBufferPtr& getCommandBuffer() const override {
return commandBufferPtr;
}
virtual mbgl::mtl::MTLBlitPassDescriptorPtr getUploadPassDescriptor() const override {
// Create from render pass descriptor?
return NS::TransferPtr(MTL::BlitPassDescriptor::alloc()->init());
}
mbgl::mtl::MTLRenderPassDescriptorPtr getRenderPassDescriptor() const override {
return NS::RetainPtr((__bridge MTL::RenderPassDescriptor*)mtlView.currentRenderPassDescriptor);
}
void swap() override {
[commandBuffer presentDrawable:currentDrawable];
[commandBuffer commit];
commandBuffer = nil;
commandBufferPtr.reset();
}
mbgl::Size framebufferSize() {
assert(mtlView);
return { static_cast<uint32_t>(mtlView.drawableSize.width),
static_cast<uint32_t>(mtlView.drawableSize.height) };
}
private:
MLNMapViewMetalImpl& backend;
mbgl::mtl::MTLCommandBufferPtr commandBufferPtr;
public:
MLNMapViewImplDelegate* delegate = nil;
MTKView *mtlView = nil;
id<CAMetalDrawable> currentDrawable;
id <MTLCommandBuffer> commandBuffer;
id <MTLCommandQueue> commandQueue;
// We count how often the context was activated/deactivated so that we can truly deactivate it
// after the activation count drops to 0.
NSUInteger activationCount = 0;
};
MLNMapViewMetalImpl::MLNMapViewMetalImpl(MLNMapView* nativeView_)
: MLNMapViewImpl(nativeView_),
mbgl::mtl::RendererBackend(mbgl::gfx::ContextMode::Unique),
mbgl::gfx::Renderable({ 0, 0 }, std::make_unique<MLNMapViewMetalRenderableResource>(*this)) {
}
MLNMapViewMetalImpl::~MLNMapViewMetalImpl() = default;
void MLNMapViewMetalImpl::setOpaque(const bool opaque) {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
resource.mtlView.opaque = opaque;
resource.mtlView.layer.opaque = opaque;
}
void MLNMapViewMetalImpl::setPresentsWithTransaction(const bool value) {
presentsWithTransaction = value;
if (@available(iOS 13.0, *)) {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
if (CAMetalLayer* metalLayer = MLN_OBJC_DYNAMIC_CAST(resource.mtlView.layer, CAMetalLayer)) {
metalLayer.presentsWithTransaction = value;
}
}
}
void MLNMapViewMetalImpl::display() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
// Calling `display` here directly causes the stuttering bug (if
// `presentsWithTransaction` is `YES` - see above)
// as reported in https://github.com/mapbox/mapbox-gl-native-ios/issues/350
//
// Since we use `presentsWithTransaction` to synchronize with UIView
// annotations, we now let the system handle when the view is rendered. This
// has the potential to increase latency
[resource.mtlView setNeedsDisplay];
}
void MLNMapViewMetalImpl::createView() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
if (resource.mtlView) {
return;
}
id<MTLDevice> device = (__bridge id<MTLDevice>)resource.getBackend().getDevice().get();
resource.mtlView = [[MTKView alloc] initWithFrame:mapView.bounds device:device];
resource.mtlView.delegate = resource.delegate;
resource.mtlView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
resource.mtlView.contentScaleFactor = contentScaleFactor();
resource.mtlView.contentMode = UIViewContentModeCenter;
resource.mtlView.colorPixelFormat = MTLPixelFormatBGRA8Unorm;
resource.mtlView.depthStencilPixelFormat = MTLPixelFormatDepth32Float_Stencil8;
resource.mtlView.opaque = mapView.opaque;
resource.mtlView.layer.opaque = mapView.opaque;
resource.mtlView.enableSetNeedsDisplay = YES;
if (@available(iOS 13.0, *)) {
CAMetalLayer* metalLayer = MLN_OBJC_DYNAMIC_CAST(resource.mtlView.layer, CAMetalLayer);
metalLayer.presentsWithTransaction = presentsWithTransaction;
}
[mapView insertSubview:resource.mtlView atIndex:0];
}
UIView* MLNMapViewMetalImpl::getView() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
return resource.mtlView;
}
void MLNMapViewMetalImpl::deleteView() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
[resource.mtlView releaseDrawables];
}
void MLNMapViewMetalImpl::activate() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
if (resource.activationCount++) {
return;
}
}
void MLNMapViewMetalImpl::deactivate() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
if (--resource.activationCount) {
return;
}
}
/// This function is called before we start rendering, when iOS invokes our rendering method.
/// iOS already sets the correct framebuffer and viewport for us, so we need to update the
/// context state with the anticipated values.
void MLNMapViewMetalImpl::updateAssumedState() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
assumeFramebufferBinding(ImplicitFramebufferBinding);
assumeViewport(0, 0, resource.framebufferSize());
}
UIImage* MLNMapViewMetalImpl::snapshot() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
return nil; //TODO: resource.mtlView.snapshot;
}
void MLNMapViewMetalImpl::layoutChanged() {
const auto scaleFactor = contentScaleFactor();
size = { static_cast<uint32_t>(mapView.bounds.size.width * scaleFactor),
static_cast<uint32_t>(mapView.bounds.size.height * scaleFactor) };
}

View File

@@ -46,7 +46,9 @@ FOUNDATION_EXPORT MLN_EXPORT const unsigned char MapboxVersionString[];
#import "MLNOfflinePack.h"
#import "MLNOfflineRegion.h"
#import "MLNOfflineStorage.h"
#if !MLN_RENDER_BACKEND_METAL
#import "MLNOpenGLStyleLayer.h"
#endif
#import "MLNOverlay.h"
#import "MLNPointAnnotation.h"
#import "MLNPointCollection.h"
@@ -74,4 +76,4 @@ FOUNDATION_EXPORT MLN_EXPORT const unsigned char MapboxVersionString[];
#import "NSExpression+MLNAdditions.h"
#import "NSPredicate+MLNAdditions.h"
#import "NSValue+MLNAdditions.h"
#import "MLNUserLocationAnnotationViewStyle.h"
#import "MLNUserLocationAnnotationViewStyle.h"

View File

@@ -66,6 +66,9 @@ ios_unit_test(
"//platform/darwin:shared_tests_objc_srcs",
"//platform/darwin:shared_tests_objcpp_srcs",
"//platform/darwin:shared_tests_swift_srcs",
"//platform/darwin:darwin_objc_hdrs",
"//platform/darwin:darwin_objcpp_hdrs",
"//platform/darwin:darwin_objc_opengl_hdrs",
],
)

View File

@@ -3,6 +3,8 @@ load(
"MLN_MACOS_PRIVATE_HEADERS",
"MLN_MACOS_PUBLIC_HEADERS",
"MLN_MACOS_PUBLIC_OBJCPP_SOURCE",
"MLN_MACOS_PUBLIC_OBJCPP_OPENGL_SOURCE",
"MLN_MACOS_PUBLIC_OBJCPP_METAL_SOURCE",
"MLN_MACOS_PUBLIC_OBJC_SOURCE",
)
@@ -20,7 +22,10 @@ filegroup(
filegroup(
name = "macos_objcpp_srcs",
srcs = MLN_MACOS_PUBLIC_OBJCPP_SOURCE,
srcs = MLN_MACOS_PUBLIC_OBJCPP_SOURCE + select({
"//:metal_renderer": MLN_MACOS_PUBLIC_OBJCPP_METAL_SOURCE,
"//conditions:default": MLN_MACOS_PUBLIC_OBJCPP_OPENGL_SOURCE,
}),
visibility = ["//visibility:public"],
)
@@ -34,5 +39,6 @@ exports_files(
MLN_MACOS_PRIVATE_HEADERS +
MLN_MACOS_PUBLIC_HEADERS +
MLN_MACOS_PUBLIC_OBJCPP_SOURCE +
MLN_MACOS_PUBLIC_OBJC_SOURCE,
MLN_MACOS_PUBLIC_OBJCPP_METAL_SOURCE +
MLN_MACOS_PUBLIC_OBJC_SOURCE
)

View File

@@ -1,13 +1,18 @@
MLN_MACOS_PUBLIC_OBJCPP_SOURCE = [
"src/MLNAttributionButton.mm",
"src/MLNMapView+IBAdditions.mm",
"src/MLNMapView+OpenGL.mm",
"src/MLNMapView+Impl.mm",
"src/MLNMapView.mm",
"src/MLNOpenGLLayer.mm",
"src/NSColor+MLNAdditions.mm",
"src/NSImage+MLNAdditions.mm",
]
MLN_MACOS_PUBLIC_OBJCPP_OPENGL_SOURCE = [
"src/MLNMapView+OpenGL.mm",
]
MLN_MACOS_PUBLIC_OBJCPP_METAL_SOURCE = [
"src/MLNMapView+OpenGL.mm",
]
MLN_MACOS_PUBLIC_OBJC_SOURCE = [
"src/MLNAnnotationImage.m",

View File

@@ -1,8 +1,13 @@
#import "MLNMapView+Impl.h"
#import "MLNMapView+OpenGL.h"
#import "MLNStyle_Private.h"
#import "NSBundle+MLNAdditions.h"
#if MLN_RENDER_BACKEND_METAL
#import "MLNMapView+Metal.h"
#else // MLN_RENDER_BACKEND_OPENGL
#import "MLNMapView+OpenGL.h"
#endif
#include <mbgl/map/map.hpp>
#include <mbgl/style/style.hpp>

View File

@@ -66,3 +66,7 @@ target_link_libraries(
)
set_property(TARGET mbgl-render-test PROPERTY FOLDER Core)
if(MLN_WITH_OPENGL)
target_compile_definitions(mbgl-render-test PRIVATE "MLN_RENDER_BACKEND_OPENGL=1")
endif()

View File

@@ -1,32 +1,14 @@
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
layout (std140) uniform FillEvaluatedPropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
highp float u_opacity;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float pad_interp_1, pad_interp_2;
};
#pragma mapbox: define highp vec4 color

View File

@@ -1,32 +1,17 @@
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
layout (std140) uniform FillEvaluatedPropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
highp float u_opacity;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float pad_interp_1, pad_interp_2;
};
layout (location = 0) in vec2 a_pos;

View File

@@ -1,32 +1,15 @@
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
layout (std140) uniform FillOutlineEvaluatedPropsUBO {
highp vec4 u_outline_color;
highp float u_opacity;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
layout (std140) uniform FillOutlineInterpolateUBO {
highp float u_outline_color_t;
highp float u_opacity_t;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
in vec2 v_pos;

View File

@@ -1,32 +1,19 @@
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
layout (std140) uniform FillOutlineDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
layout (std140) uniform FillOutlineEvaluatedPropsUBO {
highp vec4 u_outline_color;
highp float u_opacity;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
layout (std140) uniform FillOutlineInterpolateUBO {
highp float u_outline_color_t;
highp float u_opacity_t;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (location = 0) in vec2 a_pos;

View File

@@ -1,14 +1,4 @@
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
layout (std140) uniform FillOutlinePatternDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
@@ -16,15 +6,19 @@ layout (std140) uniform FillDrawableUBO {
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
layout (std140) uniform FillOutlinePatternEvaluatedPropsUBO {
highp float u_opacity;
highp float u_fade;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
layout (std140) uniform FillOutlinePatternInterpolateUBO {
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_opacity_t;
highp float pad1;
};
layout (std140) uniform FillOutlinePatternTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
};

View File

@@ -1,14 +1,4 @@
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
layout (std140) uniform FillOutlinePatternDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
@@ -16,15 +6,19 @@ layout (std140) uniform FillDrawableUBO {
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
layout (std140) uniform FillOutlinePatternEvaluatedPropsUBO {
highp float u_opacity;
highp float u_fade;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
layout (std140) uniform FillOutlinePatternInterpolateUBO {
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_opacity_t;
highp float pad1;
};
layout (std140) uniform FillOutlinePatternTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
};

View File

@@ -1,30 +1,23 @@
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
layout (std140) uniform FillPatternDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
layout (std140) uniform FillPatternEvaluatedPropsUBO {
highp float u_opacity;
highp float u_fade;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
layout (std140) uniform FillPatternInterpolateUBO {
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_opacity_t;
highp float u_padding_interp1;
};
layout (std140) uniform FillPatternTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
};

View File

@@ -1,30 +1,23 @@
layout (std140) uniform FillInterpolateUBO {
highp float u_color_t;
highp float u_opacity_t;
highp float u_outline_color_t;
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_fade;
highp float u_padding_interp1;
highp float u_padding_interp2;
};
layout (std140) uniform FillDrawableUBO {
layout (std140) uniform FillPatternDrawableUBO {
highp mat4 u_matrix;
highp vec4 u_scale;
highp vec2 u_world;
highp vec2 u_pixel_coord_upper;
highp vec2 u_pixel_coord_lower;
highp vec2 u_texsize;
};
layout (std140) uniform FillDrawablePropsUBO {
highp vec4 u_color;
highp vec4 u_outline_color;
layout (std140) uniform FillPatternEvaluatedPropsUBO {
highp float u_opacity;
highp float u_fade;
highp float padding_props1;
highp float padding_props2;
highp float padding_props3;
};
layout (std140) uniform FillDrawableTilePropsUBO {
layout (std140) uniform FillPatternInterpolateUBO {
highp float u_pattern_from_t;
highp float u_pattern_to_t;
highp float u_opacity_t;
highp float u_padding_interp1;
};
layout (std140) uniform FillPatternTilePropsUBO {
highp vec4 u_pattern_from;
highp vec4 u_pattern_to;
};

View File

@@ -32,6 +32,7 @@ layout (std140) uniform LineSDFInterpolationUBO {
lowp float u_offset_t;
lowp float u_width_t;
lowp float u_floorwidth_t;
highp float pad2;
};

View File

@@ -46,6 +46,7 @@ layout (std140) uniform LineSDFInterpolationUBO {
lowp float u_offset_t;
lowp float u_width_t;
lowp float u_floorwidth_t;
highp float pad2;
};

View File

@@ -278,7 +278,7 @@ fs.writeFileSync(path.join(outputRoot, "shader_manifest.hpp"),
#pragma once
#include <mbgl/shaders/shader_source.hpp>
#ifdef MBGL_RENDER_BACKEND_OPENGL
#if !MLN_RENDER_BACKEND_METAL
${generatedHeaders.join('\n')}
#endif
`);

Some files were not shown because too many files have changed in this diff Show More