From 49f80e95f3fbe01af2935ecd2c9c7797f2f6eef1 Mon Sep 17 00:00:00 2001 From: Steve Gifford <101820560+sjg-wdw@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:23:35 -0700 Subject: [PATCH] Changes to the custom Metal layer to allow more flexible rendering (#4446) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: louwers <649392+louwers@users.noreply.github.com> Co-authored-by: Bart Louwers --- cmake/metal.cmake | 5 +-- include/mbgl/mtl/render_pass.hpp | 2 + .../mbgl/style/layers/custom_layer_host.hpp | 6 +++ .../mtl/custom_layer_render_parameters.hpp | 6 ++- platform/darwin/app/CustomStyleLayerExample.m | 9 ++++ platform/darwin/src/MLNCustomStyleLayer.h | 25 +++++++++++ platform/darwin/src/MLNCustomStyleLayer.mm | 41 +++++++++++++++++++ src/mbgl/mtl/render_pass.cpp | 13 +++--- src/mbgl/plugin/plugin_layer_render.cpp | 1 + src/mbgl/plugin/plugin_layer_render.hpp | 1 + .../layers/render_background_layer.cpp | 1 + .../layers/render_background_layer.hpp | 19 +++++---- .../renderer/layers/render_circle_layer.cpp | 1 + .../renderer/layers/render_circle_layer.hpp | 27 ++++++------ .../layers/render_color_relief_layer.cpp | 1 + .../layers/render_color_relief_layer.hpp | 29 ++++++------- .../layers/render_custom_drawable_layer.cpp | 1 + .../layers/render_custom_drawable_layer.hpp | 19 +++++---- .../renderer/layers/render_custom_layer.cpp | 25 ++++++++++- .../renderer/layers/render_custom_layer.hpp | 19 +++++---- .../layers/render_fill_extrusion_layer.cpp | 1 + .../layers/render_fill_extrusion_layer.hpp | 27 ++++++------ .../renderer/layers/render_fill_layer.cpp | 1 + .../renderer/layers/render_fill_layer.hpp | 27 ++++++------ .../renderer/layers/render_heatmap_layer.cpp | 1 + .../renderer/layers/render_heatmap_layer.hpp | 1 + .../layers/render_hillshade_layer.cpp | 1 + .../layers/render_hillshade_layer.hpp | 1 + .../renderer/layers/render_line_layer.cpp | 1 + .../renderer/layers/render_line_layer.hpp | 31 +++++++------- .../render_location_indicator_layer.cpp | 1 + .../render_location_indicator_layer.hpp | 1 + .../renderer/layers/render_raster_layer.cpp | 1 + .../renderer/layers/render_raster_layer.hpp | 1 + .../renderer/layers/render_symbol_layer.cpp | 1 + .../renderer/layers/render_symbol_layer.hpp | 31 +++++++------- src/mbgl/renderer/render_layer.hpp | 1 + src/mbgl/renderer/render_orchestrator.cpp | 3 +- src/mbgl/renderer/render_orchestrator.hpp | 1 + src/mbgl/renderer/renderer_impl.cpp | 8 +++- .../mtl/custom_layer_render_parameters.cpp | 17 ++++++-- 41 files changed, 281 insertions(+), 128 deletions(-) diff --git a/cmake/metal.cmake b/cmake/metal.cmake index 1a36178d2..b5c06b2b3 100644 --- a/cmake/metal.cmake +++ b/cmake/metal.cmake @@ -96,7 +96,4 @@ list(APPEND ${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp ) -find_library(METAL_FRAMEWORK Metal) -if (METAL_FRAMEWORK) - target_link_libraries(mbgl-core PRIVATE ${METAL_FRAMEWORK}) -endif() +target_link_libraries(mbgl-core PRIVATE "-framework Metal") diff --git a/include/mbgl/mtl/render_pass.hpp b/include/mbgl/mtl/render_pass.hpp index 49ffbf10b..744969b9b 100644 --- a/include/mbgl/mtl/render_pass.hpp +++ b/include/mbgl/mtl/render_pass.hpp @@ -25,6 +25,7 @@ public: mtl::CommandEncoder& getCommandEncoder() { return commandEncoder; } const mtl::CommandEncoder& getCommandEncoder() const { return commandEncoder; } + const MTLCommandBufferPtr& getCommandBuffer() const { return commandBuffer; } const MTLRenderCommandEncoderPtr& getMetalEncoder() const { return encoder; } const gfx::RenderPassDescriptor& getDescriptor() const { return descriptor; } @@ -71,6 +72,7 @@ private: private: gfx::RenderPassDescriptor descriptor; mtl::CommandEncoder& commandEncoder; + MTLCommandBufferPtr commandBuffer; MTLRenderCommandEncoderPtr encoder; MTLDepthStencilStatePtr currentDepthStencilState; MTLRenderPipelineStatePtr currentPipelineState; diff --git a/include/mbgl/style/layers/custom_layer_host.hpp b/include/mbgl/style/layers/custom_layer_host.hpp index 32e32f5f8..6561be1aa 100644 --- a/include/mbgl/style/layers/custom_layer_host.hpp +++ b/include/mbgl/style/layers/custom_layer_host.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -24,6 +25,11 @@ public: */ virtual void initialize(const CustomLayerInitParameters&) = 0; + /** + * Called right before the layers start rendering. + */ + virtual void preRender(const mbgl::gfx::Context&, const mbgl::style::CustomLayerRenderParameters&) {}; + /** * Render the layer. This method is called once per frame. The * implementation should not make any assumptions about the GL/Metal state (other diff --git a/include/mbgl/style/layers/mtl/custom_layer_render_parameters.hpp b/include/mbgl/style/layers/mtl/custom_layer_render_parameters.hpp index 572f26970..ebb5226d7 100644 --- a/include/mbgl/style/layers/mtl/custom_layer_render_parameters.hpp +++ b/include/mbgl/style/layers/mtl/custom_layer_render_parameters.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -20,9 +21,12 @@ namespace mtl { * Metal subclass of CustomLayerRenderParameters */ struct CustomLayerRenderParameters : mbgl::style::CustomLayerRenderParameters { + const std::unique_ptr &renderPass; mbgl::mtl::MTLRenderCommandEncoderPtr encoder; + mbgl::mtl::MTLCommandBufferPtr commandBuffer; + mbgl::mtl::MTLRenderPassDescriptorPtr renderPassDesc; - CustomLayerRenderParameters(const PaintParameters&); + CustomLayerRenderParameters(const PaintParameters &); }; } // namespace mtl diff --git a/platform/darwin/app/CustomStyleLayerExample.m b/platform/darwin/app/CustomStyleLayerExample.m index f82ec73fe..a561ce7ae 100644 --- a/platform/darwin/app/CustomStyleLayerExample.m +++ b/platform/darwin/app/CustomStyleLayerExample.m @@ -135,9 +135,18 @@ } +- (void)preDrawInMapView:(MLNMapView *)mapView withContext:(MLNStyleLayerDrawingContext)context { + id commandBuffer = self.commandBuffer; + + id blitEncoder = [commandBuffer blitCommandEncoder]; + [blitEncoder endEncoding]; +} + - (void)drawInMapView:(MLNMapView *)mapView withContext:(MLNStyleLayerDrawingContext)context { // Use the supplied render command encoder to encode commands + id commandBuffer = self.commandBuffer; id renderEncoder = self.renderEncoder; + MTLRenderPassDescriptor *renderPassDesc = self.renderPassDesc; if(renderEncoder != nil) { MLNBackendResource* resource = [mapView backendResource]; diff --git a/platform/darwin/src/MLNCustomStyleLayer.h b/platform/darwin/src/MLNCustomStyleLayer.h index 4958157f6..e26782c73 100644 --- a/platform/darwin/src/MLNCustomStyleLayer.h +++ b/platform/darwin/src/MLNCustomStyleLayer.h @@ -83,6 +83,18 @@ MLN_EXPORT #pragma clang diagnostic pop #if MLN_RENDER_BACKEND_METAL +/// The Metal command buffer is used to generate render and other encoders.. +/// +/// This property is only valid when using the Metal-based rendering backend. +/// If the OpenGL backend is in use, this property will be `nil`. +@property (nonatomic, weak) id commandBuffer; + +/// The Metal render pass descriptor Metal draw commands. +/// +/// This property is only valid when using the Metal-based rendering backend. +/// If the OpenGL backend is in use, this property will be `nil`. +@property (nonatomic, weak) MTLRenderPassDescriptor *renderPassDesc; + /// The Metal render command encoder used for issuing Metal draw commands. /// /// This property is only valid when using the Metal-based rendering backend. @@ -124,6 +136,19 @@ MLN_EXPORT /// - Parameter mapView: The map view from whose style the layer is about to be removed. - (void)willMoveFromMapView:(MLNMapView *)mapView; +/// Called right before the layer needs to draw a new frame in a map view. +/// +/// Override this method in a subclass to do any pre-drawing of the layer’s content. The default +/// implementation of this method does nothing. +/// +/// This call exists to do things with the rendering context before MapLibre Native adds its +/// own rendering commands. +/// +/// - Parameters: +/// - mapView: The map view to which the layer draws. +/// - context: A context structure with information defining the frame to draw. +- (void)preDrawInMapView:(MLNMapView *)mapView withContext:(MLNStyleLayerDrawingContext)context; + /// Called each time the layer needs to draw a new frame in a map view. /// /// Override this method in a subclass to draw the layer’s content. The default diff --git a/platform/darwin/src/MLNCustomStyleLayer.mm b/platform/darwin/src/MLNCustomStyleLayer.mm index 28d63e1d3..1727ef786 100644 --- a/platform/darwin/src/MLNCustomStyleLayer.mm +++ b/platform/darwin/src/MLNCustomStyleLayer.mm @@ -10,6 +10,7 @@ #import #endif +#include #include #include @@ -72,6 +73,9 @@ class MLNCustomLayerHost; - (void)willMoveFromMapView:(MLNMapView *)mapView { } +- (void)preDrawInMapView:(MLNMapView *)mapView withContext:(MLNStyleLayerDrawingContext)context { +} + - (void)drawInMapView:(MLNMapView *)mapView withContext:(MLNStyleLayerDrawingContext)context { } @@ -99,10 +103,47 @@ public: } } + void preRender(const mbgl::gfx::Context &context, + const mbgl::style::CustomLayerRenderParameters ¶meters) override { + if (!layer) return; + +#if MLN_RENDER_BACKEND_METAL + auto renderPassDesc = + static_cast(parameters) + .renderPassDesc.get(); + MTL::CommandBuffer *cmdPtr = + static_cast(parameters) + .commandBuffer.get(); + id commandBuffer = (__bridge id)cmdPtr; + layer.commandBuffer = commandBuffer; + layer.renderPassDesc = (__bridge MTLRenderPassDescriptor *)renderPassDesc; + +#endif + + MLNStyleLayerDrawingContext drawingContext = { + .size = CGSizeMake(parameters.width, parameters.height), + .centerCoordinate = CLLocationCoordinate2DMake(parameters.latitude, parameters.longitude), + .zoomLevel = parameters.zoom, + .direction = mbgl::util::wrap(parameters.bearing, 0., 360.), + .pitch = static_cast(parameters.pitch), + .fieldOfView = static_cast(parameters.fieldOfView), + .projectionMatrix = MLNMatrix4Make(parameters.projectionMatrix), + .nearClippedProjectionMatrix = MLNMatrix4Make(parameters.nearClippedProjectionMatrix)}; + + if (layer.mapView) { + [layer preDrawInMapView:layer.mapView withContext:drawingContext]; + } + } + void render(const mbgl::style::CustomLayerRenderParameters ¶meters) override { if (!layer) return; #if MLN_RENDER_BACKEND_METAL + MTL::CommandBuffer *cmdPtr = + static_cast(parameters) + .commandBuffer.get(); + id commandBuffer = (__bridge id)cmdPtr; + layer.commandBuffer = commandBuffer; MTL::RenderCommandEncoder *ptr = static_cast(parameters) .encoder.get(); diff --git a/src/mbgl/mtl/render_pass.cpp b/src/mbgl/mtl/render_pass.cpp index cd9b1e818..cff9ac707 100644 --- a/src/mbgl/mtl/render_pass.cpp +++ b/src/mbgl/mtl/render_pass.cpp @@ -17,7 +17,8 @@ RenderPass::RenderPass(CommandEncoder& commandEncoder_, const char* name, const resource.bind(); - if (const auto& buffer = resource.getCommandBuffer()) { + if (const auto& cmdBuff = resource.getCommandBuffer()) { + commandBuffer = cmdBuff; if (auto rpd = resource.getRenderPassDescriptor()) { if (descriptor.clearColor) { if (auto copy = NS::TransferPtr(rpd->copy())) { @@ -29,7 +30,7 @@ RenderPass::RenderPass(CommandEncoder& commandEncoder_, const char* name, const } } } - encoder = NS::RetainPtr(buffer->renderCommandEncoder(rpd.get())); + encoder = NS::RetainPtr(cmdBuff->renderCommandEncoder(rpd.get())); const auto& texture = rpd->colorAttachments()->object(0)->texture(); width = texture->width(); @@ -92,10 +93,10 @@ NS::String* toNSString(const char* str) { } } // namespace -void RenderPass::pushDebugGroup(const char* name) { +void RenderPass::pushDebugGroup(const char* theName) { assert(encoder); if (encoder) { - encoder->pushDebugGroup(toNSString(name)); + encoder->pushDebugGroup(toNSString(theName)); } } @@ -106,10 +107,10 @@ void RenderPass::popDebugGroup() { } } -void RenderPass::addDebugSignpost(const char* name) { +void RenderPass::addDebugSignpost(const char* theName) { assert(encoder); if (encoder) { - encoder->insertDebugSignpost(toNSString(name)); + encoder->insertDebugSignpost(toNSString(theName)); } } diff --git a/src/mbgl/plugin/plugin_layer_render.cpp b/src/mbgl/plugin/plugin_layer_render.cpp index 4881529aa..886e754b0 100644 --- a/src/mbgl/plugin/plugin_layer_render.cpp +++ b/src/mbgl/plugin/plugin_layer_render.cpp @@ -80,6 +80,7 @@ void RenderPluginLayer::update([[maybe_unused]] gfx::ShaderRegistry& shaderRegis [[maybe_unused]] gfx::Context& context, [[maybe_unused]] const TransformState& transformState, [[maybe_unused]] const std::shared_ptr& updateParameters, + [[maybe_unused]] const PaintParameters& paintParameters, [[maybe_unused]] const RenderTree& renderTree, [[maybe_unused]] UniqueChangeRequestVec& changes) { // create layer group diff --git a/src/mbgl/plugin/plugin_layer_render.hpp b/src/mbgl/plugin/plugin_layer_render.hpp index cc2ea2db7..cd89d988a 100644 --- a/src/mbgl/plugin/plugin_layer_render.hpp +++ b/src/mbgl/plugin/plugin_layer_render.hpp @@ -21,6 +21,7 @@ public: gfx::Context&, const TransformState&, const std::shared_ptr&, + const PaintParameters&, const RenderTree&, UniqueChangeRequestVec&) override; diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp index cbed3fd7e..0520f2d74 100644 --- a/src/mbgl/renderer/layers/render_background_layer.cpp +++ b/src/mbgl/renderer/layers/render_background_layer.cpp @@ -116,6 +116,7 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState& state, const std::shared_ptr& updateParameters, + [[maybe_unused]] const PaintParameters& paintParameters, [[maybe_unused]] const RenderTree& renderTree, [[maybe_unused]] UniqueChangeRequestVec& changes) { assert(updateParameters); diff --git a/src/mbgl/renderer/layers/render_background_layer.hpp b/src/mbgl/renderer/layers/render_background_layer.hpp index 89cf6a88c..a2afb6168 100644 --- a/src/mbgl/renderer/layers/render_background_layer.hpp +++ b/src/mbgl/renderer/layers/render_background_layer.hpp @@ -24,21 +24,22 @@ public: ~RenderBackgroundLayer() override; /// Generate any changes needed by the layer - void update(gfx::ShaderRegistry&, - gfx::Context&, - const TransformState&, - const std::shared_ptr&, - const RenderTree&, - UniqueChangeRequestVec&) override; + void update(gfx::ShaderRegistry &, + gfx::Context &, + const TransformState &, + const std::shared_ptr &, + const PaintParameters &, + const RenderTree &, + UniqueChangeRequestVec &) override; private: - void transition(const TransitionParameters&) override; - void evaluate(const PropertyEvaluationParameters&) override; + void transition(const TransitionParameters &) override; + void evaluate(const PropertyEvaluationParameters &) override; bool hasTransition() const override; bool hasCrossfade() const override; std::optional getSolidBackground() const override; - void prepare(const LayerPrepareParameters&) override; + void prepare(const LayerPrepareParameters &) override; // Paint properties style::BackgroundPaintProperties::Unevaluated unevaluated; diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index 90b21c12f..65deb1036 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -165,6 +165,7 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState&, const std::shared_ptr&, + const PaintParameters&, const RenderTree&, UniqueChangeRequestVec& changes) { if (!renderTiles || renderTiles->empty()) { diff --git a/src/mbgl/renderer/layers/render_circle_layer.hpp b/src/mbgl/renderer/layers/render_circle_layer.hpp index ecf2a42f7..a07856e07 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.hpp +++ b/src/mbgl/renderer/layers/render_circle_layer.hpp @@ -15,26 +15,27 @@ public: ~RenderCircleLayer() final = default; /// Generate any changes needed by the layer - void update(gfx::ShaderRegistry&, - gfx::Context&, - const TransformState&, - const std::shared_ptr&, - const RenderTree&, - UniqueChangeRequestVec&) override; + void update(gfx::ShaderRegistry &, + gfx::Context &, + const TransformState &, + const std::shared_ptr &, + const PaintParameters &, + const RenderTree &, + UniqueChangeRequestVec &) override; private: - void transition(const TransitionParameters&) override; - void evaluate(const PropertyEvaluationParameters&) override; + void transition(const TransitionParameters &) override; + void evaluate(const PropertyEvaluationParameters &) override; bool hasTransition() const override; bool hasCrossfade() const override; - bool queryIntersectsFeature(const GeometryCoordinates&, - const GeometryTileFeature&, + bool queryIntersectsFeature(const GeometryCoordinates &, + const GeometryTileFeature &, float, - const TransformState&, + const TransformState &, float, - const mat4&, - const FeatureState&) const override; + const mat4 &, + const FeatureState &) const override; private: // Paint properties diff --git a/src/mbgl/renderer/layers/render_color_relief_layer.cpp b/src/mbgl/renderer/layers/render_color_relief_layer.cpp index c5d70adce..e56ea8469 100644 --- a/src/mbgl/renderer/layers/render_color_relief_layer.cpp +++ b/src/mbgl/renderer/layers/render_color_relief_layer.cpp @@ -197,6 +197,7 @@ void RenderColorReliefLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState&, const std::shared_ptr&, + const PaintParameters&, const RenderTree&, UniqueChangeRequestVec& changes) { if (!renderTiles || renderTiles->empty()) { diff --git a/src/mbgl/renderer/layers/render_color_relief_layer.hpp b/src/mbgl/renderer/layers/render_color_relief_layer.hpp index 473811eff..e61d5604d 100644 --- a/src/mbgl/renderer/layers/render_color_relief_layer.hpp +++ b/src/mbgl/renderer/layers/render_color_relief_layer.hpp @@ -23,26 +23,27 @@ public: ~RenderColorReliefLayer() override; /// Generate any changes needed by the layer - void update(gfx::ShaderRegistry&, - gfx::Context&, - const TransformState&, - const std::shared_ptr&, - const RenderTree&, - UniqueChangeRequestVec&) override; + void update(gfx::ShaderRegistry &, + gfx::Context &, + const TransformState &, + const std::shared_ptr &, + const PaintParameters &, + const RenderTree &, + UniqueChangeRequestVec &) override; private: - void transition(const TransitionParameters&) override; - void evaluate(const PropertyEvaluationParameters&) override; + void transition(const TransitionParameters &) override; + void evaluate(const PropertyEvaluationParameters &) override; bool hasTransition() const override; bool hasCrossfade() const override; - void prepare(const LayerPrepareParameters&) override; - bool queryIntersectsFeature(const GeometryCoordinates&, - const GeometryTileFeature&, + void prepare(const LayerPrepareParameters &) override; + bool queryIntersectsFeature(const GeometryCoordinates &, + const GeometryTileFeature &, float, - const TransformState&, + const TransformState &, float, - const mat4&, - const FeatureState&) const override; + const mat4 &, + const FeatureState &) const override; void updateColorRamp(); // Paint properties diff --git a/src/mbgl/renderer/layers/render_custom_drawable_layer.cpp b/src/mbgl/renderer/layers/render_custom_drawable_layer.cpp index a01870f29..b29c099ce 100644 --- a/src/mbgl/renderer/layers/render_custom_drawable_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_drawable_layer.cpp @@ -56,6 +56,7 @@ void RenderCustomDrawableLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState& state, const std::shared_ptr& updateParameters, + const PaintParameters&, const RenderTree& renderTree, UniqueChangeRequestVec& changes) { // check if host changed and update diff --git a/src/mbgl/renderer/layers/render_custom_drawable_layer.hpp b/src/mbgl/renderer/layers/render_custom_drawable_layer.hpp index 2b5a611fc..deb610f48 100644 --- a/src/mbgl/renderer/layers/render_custom_drawable_layer.hpp +++ b/src/mbgl/renderer/layers/render_custom_drawable_layer.hpp @@ -11,19 +11,20 @@ public: ~RenderCustomDrawableLayer() override; /// Generate any changes needed by the layer - void update(gfx::ShaderRegistry&, - gfx::Context&, - const TransformState&, - const std::shared_ptr&, - const RenderTree&, - UniqueChangeRequestVec&) override; + void update(gfx::ShaderRegistry &, + gfx::Context &, + const TransformState &, + const std::shared_ptr &, + const PaintParameters &, + const RenderTree &, + UniqueChangeRequestVec &) override; private: - void transition(const TransitionParameters&) override {} - void evaluate(const PropertyEvaluationParameters&) override; + void transition(const TransitionParameters &) override {} + void evaluate(const PropertyEvaluationParameters &) override; bool hasTransition() const override; bool hasCrossfade() const override; - void prepare(const LayerPrepareParameters&) override; + void prepare(const LayerPrepareParameters &) override; std::shared_ptr host; }; diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp index b9571259b..7f8ae2f4c 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_layer.cpp @@ -13,10 +13,15 @@ #include #include -#if MLN_RENDER_BACKEND_VULKAN +#if MLN_RENDER_BACKEND_METAL +#include +#include +#elif MLN_RENDER_BACKEND_VULKAN #include #include #include +#include +#include #endif // TODO: platform agnostic error checks @@ -48,6 +53,20 @@ void initializeHost(const std::shared_ptr& host, [[maybe } #endif } + +void callPreRender(const std::shared_ptr& host, + gfx::Context& context, + const PaintParameters& paintParameters) { +#if MLN_RENDER_BACKEND_METAL + style::mtl::CustomLayerRenderParameters parameters(paintParameters); +#elif MLN_RENDER_BACKEND_VULKAN + style::vulkan::CustomLayerRenderParameters parameters(paintParameters); +#else + style::CustomLayerRenderParameters parameters(paintParameters); +#endif + host->preRender(context, parameters); +} + } // namespace RenderCustomLayer::RenderCustomLayer(Immutable _impl) @@ -87,6 +106,7 @@ void RenderCustomLayer::update([[maybe_unused]] gfx::ShaderRegistry& shaders, gfx::Context& context, [[maybe_unused]] const TransformState& state, const std::shared_ptr&, + [[maybe_unused]] const PaintParameters& paintParameters, [[maybe_unused]] const RenderTree& renderTree, [[maybe_unused]] UniqueChangeRequestVec& changes) { // create layer group @@ -114,6 +134,9 @@ void RenderCustomLayer::update([[maybe_unused]] gfx::ShaderRegistry& shaders, needsInitialize = false; } + // call the pre-render + MBGL_CHECK_ERROR(callPreRender(host, context, paintParameters)); + // create drawable if (localLayerGroup->getDrawableCount() == 0 || hostChanged) { localLayerGroup->clearDrawables(); diff --git a/src/mbgl/renderer/layers/render_custom_layer.hpp b/src/mbgl/renderer/layers/render_custom_layer.hpp index 684572c1b..b066be73f 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.hpp +++ b/src/mbgl/renderer/layers/render_custom_layer.hpp @@ -11,20 +11,21 @@ public: ~RenderCustomLayer() override; /// Generate any changes needed by the layer - void update(gfx::ShaderRegistry&, - gfx::Context&, - const TransformState&, - const std::shared_ptr&, - const RenderTree&, - UniqueChangeRequestVec&) override; + void update(gfx::ShaderRegistry &, + gfx::Context &, + const TransformState &, + const std::shared_ptr &, + const PaintParameters &, + const RenderTree &, + UniqueChangeRequestVec &) override; private: - void transition(const TransitionParameters&) override {} - void evaluate(const PropertyEvaluationParameters&) override; + void transition(const TransitionParameters &) override {} + void evaluate(const PropertyEvaluationParameters &) override; bool hasTransition() const override; bool hasCrossfade() const override; void markContextDestroyed() override; - void prepare(const LayerPrepareParameters&) override; + void prepare(const LayerPrepareParameters &) override; bool contextDestroyed = false; bool needsInitialize = true; diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index f941af8cc..57b49b92f 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -105,6 +105,7 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState&, const std::shared_ptr&, + [[maybe_unused]] const PaintParameters& paintParameters, const RenderTree&, UniqueChangeRequestVec& changes) { if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) { diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp index 354d9af8c..fd668cc86 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp @@ -13,27 +13,28 @@ public: ~RenderFillExtrusionLayer() override; private: - void transition(const TransitionParameters&) override; - void evaluate(const PropertyEvaluationParameters&) override; + void transition(const TransitionParameters &) override; + void evaluate(const PropertyEvaluationParameters &) override; bool hasTransition() const override; bool hasCrossfade() const override; bool is3D() const override; /// Generate any changes needed by the layer - void update(gfx::ShaderRegistry&, - gfx::Context&, - const TransformState&, - const std::shared_ptr&, - const RenderTree&, - UniqueChangeRequestVec&) override; + void update(gfx::ShaderRegistry &, + gfx::Context &, + const TransformState &, + const std::shared_ptr &, + const PaintParameters &, + const RenderTree &, + UniqueChangeRequestVec &) override; - bool queryIntersectsFeature(const GeometryCoordinates&, - const GeometryTileFeature&, + bool queryIntersectsFeature(const GeometryCoordinates &, + const GeometryTileFeature &, float, - const TransformState&, + const TransformState &, float, - const mat4&, - const FeatureState&) const override; + const mat4 &, + const FeatureState &) const override; // Paint properties style::FillExtrusionPaintProperties::Unevaluated unevaluated; diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index c70190698..74bce2692 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -121,6 +121,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState&, const std::shared_ptr&, + [[maybe_unused]] const PaintParameters& paintParameters, const RenderTree&, UniqueChangeRequestVec& changes) { if (!renderTiles || renderTiles->empty()) { diff --git a/src/mbgl/renderer/layers/render_fill_layer.hpp b/src/mbgl/renderer/layers/render_fill_layer.hpp index f68cf6924..209c03934 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_layer.hpp @@ -29,26 +29,27 @@ public: ~RenderFillLayer() override; /// Generate any changes needed by the layer - void update(gfx::ShaderRegistry&, - gfx::Context&, - const TransformState&, - const std::shared_ptr&, - const RenderTree&, - UniqueChangeRequestVec&) override; + void update(gfx::ShaderRegistry &, + gfx::Context &, + const TransformState &, + const std::shared_ptr &, + const PaintParameters &, + const RenderTree &, + UniqueChangeRequestVec &) override; private: - void transition(const TransitionParameters&) override; - void evaluate(const PropertyEvaluationParameters&) override; + void transition(const TransitionParameters &) override; + void evaluate(const PropertyEvaluationParameters &) override; bool hasTransition() const override; bool hasCrossfade() const override; - bool queryIntersectsFeature(const GeometryCoordinates&, - const GeometryTileFeature&, + bool queryIntersectsFeature(const GeometryCoordinates &, + const GeometryTileFeature &, float, - const TransformState&, + const TransformState &, float, - const mat4&, - const FeatureState&) const override; + const mat4 &, + const FeatureState &) const override; // Paint properties style::FillPaintProperties::Unevaluated unevaluated; diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index 280f9151b..509a887a2 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -162,6 +162,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState& state, const std::shared_ptr&, + [[maybe_unused]] const PaintParameters& paintParameters, [[maybe_unused]] const RenderTree& renderTree, UniqueChangeRequestVec& changes) { if (!renderTiles || renderTiles->empty()) { diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.hpp b/src/mbgl/renderer/layers/render_heatmap_layer.hpp index c5fd6eac7..0812af47c 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.hpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.hpp @@ -27,6 +27,7 @@ public: gfx::Context&, const TransformState&, const std::shared_ptr&, + const PaintParameters&, const RenderTree&, UniqueChangeRequestVec&) override; diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index c33f41d1e..04784a475 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -155,6 +155,7 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, [[maybe_unused]] const TransformState& state, const std::shared_ptr&, + [[maybe_unused]] const PaintParameters& paintParameters, [[maybe_unused]] const RenderTree& renderTree, UniqueChangeRequestVec& changes) { if (!renderTiles || renderTiles->empty()) { diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.hpp b/src/mbgl/renderer/layers/render_hillshade_layer.hpp index 3490788bc..dce7104df 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.hpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.hpp @@ -25,6 +25,7 @@ public: gfx::Context&, const TransformState&, const std::shared_ptr&, + const PaintParameters&, const RenderTree&, UniqueChangeRequestVec&) override; diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index 12fbbca99..21d514199 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -226,6 +226,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState&, [[maybe_unused]] const std::shared_ptr& parameters, + [[maybe_unused]] const PaintParameters& paintParameters, const RenderTree&, UniqueChangeRequestVec& changes) { if (!renderTiles || renderTiles->empty()) { diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp index a994c28dd..e647a6b89 100644 --- a/src/mbgl/renderer/layers/render_line_layer.hpp +++ b/src/mbgl/renderer/layers/render_line_layer.hpp @@ -28,32 +28,33 @@ public: ~RenderLineLayer() override; /// Generate any changes needed by the layer - void update(gfx::ShaderRegistry&, - gfx::Context&, - const TransformState&, - const std::shared_ptr&, - const RenderTree&, - UniqueChangeRequestVec&) override; + void update(gfx::ShaderRegistry &, + gfx::Context &, + const TransformState &, + const std::shared_ptr &, + const PaintParameters &, + const RenderTree &, + UniqueChangeRequestVec &) override; private: - void transition(const TransitionParameters&) override; - void evaluate(const PropertyEvaluationParameters&) override; + void transition(const TransitionParameters &) override; + void evaluate(const PropertyEvaluationParameters &) override; bool hasTransition() const override; bool hasCrossfade() const override; - void prepare(const LayerPrepareParameters&) override; + void prepare(const LayerPrepareParameters &) override; - bool queryIntersectsFeature(const GeometryCoordinates&, - const GeometryTileFeature&, + bool queryIntersectsFeature(const GeometryCoordinates &, + const GeometryTileFeature &, float, - const TransformState&, + const TransformState &, float, - const mat4&, - const FeatureState&) const override; + const mat4 &, + const FeatureState &) const override; // Paint properties style::LinePaintProperties::Unevaluated unevaluated; - float getLineWidth(const GeometryTileFeature&, float, const FeatureState&) const; + float getLineWidth(const GeometryTileFeature &, float, const FeatureState &) const; void updateColorRamp(); std::shared_ptr colorRamp; diff --git a/src/mbgl/renderer/layers/render_location_indicator_layer.cpp b/src/mbgl/renderer/layers/render_location_indicator_layer.cpp index 05c23403c..cc5be175f 100644 --- a/src/mbgl/renderer/layers/render_location_indicator_layer.cpp +++ b/src/mbgl/renderer/layers/render_location_indicator_layer.cpp @@ -1041,6 +1041,7 @@ void RenderLocationIndicatorLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState&, const std::shared_ptr&, + [[maybe_unused]] const PaintParameters& paintParameters, const RenderTree&, UniqueChangeRequestVec& changes) { const auto drawPasses = RenderPass::Translucent; diff --git a/src/mbgl/renderer/layers/render_location_indicator_layer.hpp b/src/mbgl/renderer/layers/render_location_indicator_layer.hpp index 35eab9591..2581be13b 100644 --- a/src/mbgl/renderer/layers/render_location_indicator_layer.hpp +++ b/src/mbgl/renderer/layers/render_location_indicator_layer.hpp @@ -30,6 +30,7 @@ public: gfx::Context &, const TransformState &, const std::shared_ptr &, + const PaintParameters &, const RenderTree &, UniqueChangeRequestVec &) override; #endif diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp index 15cd975a1..03d92e815 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.cpp +++ b/src/mbgl/renderer/layers/render_raster_layer.cpp @@ -102,6 +102,7 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState& /*state*/, const std::shared_ptr&, + [[maybe_unused]] const PaintParameters& paintParameters, [[maybe_unused]] const RenderTree& renderTree, [[maybe_unused]] UniqueChangeRequestVec& changes) { if ((!renderTiles || renderTiles->empty()) && !imageData) { diff --git a/src/mbgl/renderer/layers/render_raster_layer.hpp b/src/mbgl/renderer/layers/render_raster_layer.hpp index ac397bdd5..92888ab26 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.hpp +++ b/src/mbgl/renderer/layers/render_raster_layer.hpp @@ -20,6 +20,7 @@ public: gfx::Context&, const TransformState&, const std::shared_ptr&, + const PaintParameters&, const RenderTree&, UniqueChangeRequestVec&) override; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 2b5389610..e3d248990 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -441,6 +441,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState& state, const std::shared_ptr&, + const PaintParameters&, const RenderTree&, UniqueChangeRequestVec& changes) { if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) { diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index 1091f7e08..1e7ead426 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -65,17 +65,18 @@ public: ~RenderSymbolLayer() override; static style::IconPaintProperties::PossiblyEvaluated iconPaintProperties( - const style::SymbolPaintProperties::PossiblyEvaluated&); + const style::SymbolPaintProperties::PossiblyEvaluated &); static style::TextPaintProperties::PossiblyEvaluated textPaintProperties( - const style::SymbolPaintProperties::PossiblyEvaluated&); + const style::SymbolPaintProperties::PossiblyEvaluated &); /// Generate any changes needed by the layer - void update(gfx::ShaderRegistry&, - gfx::Context&, - const TransformState&, - const std::shared_ptr&, - const RenderTree&, - UniqueChangeRequestVec&) override; + void update(gfx::ShaderRegistry &, + gfx::Context &, + const TransformState &, + const std::shared_ptr &, + const PaintParameters &, + const RenderTree &, + UniqueChangeRequestVec &) override; /// Remove all the drawables for tiles std::size_t removeAllDrawables() override; @@ -85,27 +86,27 @@ protected: /// This event is run to indicate if the layer should render or not for the current frame. /// @param willRender Indicates if this layer should render or not /// @param changes The collection of current pending change requests - void markLayerRenderable(bool willRender, UniqueChangeRequestVec&) override; + void markLayerRenderable(bool willRender, UniqueChangeRequestVec &) override; /// @brief Called when the layer index changes /// This event is run when a layer is added or removed from the style. /// @param newLayerIndex The new layer index for this layer /// @param changes The collection of current pending change requests - void layerIndexChanged(int32_t newLayerIndex, UniqueChangeRequestVec&) override; + void layerIndexChanged(int32_t newLayerIndex, UniqueChangeRequestVec &) override; /// Called when the style layer is removed - void layerRemoved(UniqueChangeRequestVec&) override; + void layerRemoved(UniqueChangeRequestVec &) override; /// Remove all drawables for the tile from the layer group - std::size_t removeTile(RenderPass, const OverscaledTileID&) override; + std::size_t removeTile(RenderPass, const OverscaledTileID &) override; private: - void transition(const TransitionParameters&) override; - void evaluate(const PropertyEvaluationParameters&) override; + void transition(const TransitionParameters &) override; + void evaluate(const PropertyEvaluationParameters &) override; bool hasTransition() const override; bool hasCrossfade() const override; - void prepare(const LayerPrepareParameters&) override; + void prepare(const LayerPrepareParameters &) override; private: // Paint properties diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 361837254..35bd5ea84 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -160,6 +160,7 @@ public: gfx::Context&, const TransformState&, const std::shared_ptr&, + const PaintParameters&, const RenderTree&, UniqueChangeRequestVec&) {} diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index 3368043b8..850398be0 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -951,6 +951,7 @@ void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState& state, const std::shared_ptr& updateParameters, + const PaintParameters& paintParameters, const RenderTree& renderTree) { MLN_TRACE_FUNC(); @@ -979,7 +980,7 @@ void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders, } #endif try { - renderLayer.update(shaders, context, state, updateParameters, renderTree, changes); + renderLayer.update(shaders, context, state, updateParameters, paintParameters, renderTree, changes); } catch (...) { observer->onRenderError(std::current_exception()); } diff --git a/src/mbgl/renderer/render_orchestrator.hpp b/src/mbgl/renderer/render_orchestrator.hpp index 8b0263972..ac2a5ada6 100644 --- a/src/mbgl/renderer/render_orchestrator.hpp +++ b/src/mbgl/renderer/render_orchestrator.hpp @@ -138,6 +138,7 @@ public: gfx::Context&, const TransformState&, const std::shared_ptr&, + const PaintParameters& paintParameters, const RenderTree&); void processChanges(); diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 500773570..4fc6d2913 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -253,8 +253,12 @@ void Renderer::Impl::render(const RenderTree& renderTree, const std::shared_ptr< // - LAYER GROUP UPDATE ------------------------------------------------------------------------ // Updates all layer groups and process changes if (staticData && staticData->shaders) { - orchestrator.updateLayers( - *staticData->shaders, context, renderTreeParameters.transformParams.state, updateParameters, renderTree); + orchestrator.updateLayers(*staticData->shaders, + context, + renderTreeParameters.transformParams.state, + updateParameters, + parameters, + renderTree); } orchestrator.processChanges(); diff --git a/src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp b/src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp index 660234e64..79025b592 100644 --- a/src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp +++ b/src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include @@ -10,9 +12,18 @@ namespace style { namespace mtl { CustomLayerRenderParameters::CustomLayerRenderParameters(const mbgl::PaintParameters& paintParameters) - : mbgl::style::CustomLayerRenderParameters(paintParameters) { - const mbgl::mtl::RenderPass& renderPass = static_cast(*paintParameters.renderPass); - encoder = renderPass.getMetalEncoder(); + : mbgl::style::CustomLayerRenderParameters(paintParameters), + renderPass(paintParameters.renderPass) { + const mbgl::gfx::Renderable& renderable = paintParameters.backend.getDefaultRenderable(); + const mbgl::mtl::RenderableResource& resource = renderable.getResource(); + renderPassDesc = renderable.getResource().getRenderPassDescriptor(); + if (const auto& buffer_ = resource.getCommandBuffer()) { + commandBuffer = buffer_; + } + if (paintParameters.renderPass) { + const mbgl::mtl::RenderPass& metalRenderPass = static_cast(*paintParameters.renderPass); + encoder = metalRenderPass.getMetalEncoder(); + } } } // namespace mtl