Metal render target (#1484)
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Tim Sylvester <tim@wetdogweather.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: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: mwilsnd <53413200+mwilsnd@users.noreply.github.com> 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> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
@@ -159,7 +159,6 @@ if(MLN_DRAWABLE_RENDERER)
|
||||
${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
|
||||
@@ -180,7 +179,6 @@ if(MLN_DRAWABLE_RENDERER)
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/vertex_attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/render_target.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/render_target_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/change_request.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/tile_layer_group.cpp
|
||||
@@ -1115,6 +1113,8 @@ if(MLN_WITH_OPENGL)
|
||||
${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/fill_extrusion_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/heatmap_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/heatmap_texture_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
|
||||
@@ -1122,14 +1122,12 @@ if(MLN_WITH_OPENGL)
|
||||
${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
|
||||
@@ -1154,12 +1152,15 @@ if(MBGL_WITH_METAL)
|
||||
${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/layer_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/mtl_fwd.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/offscreen_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/render_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/renderable_resource.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
|
||||
@@ -1167,14 +1168,21 @@ if(MBGL_WITH_METAL)
|
||||
${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/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/common.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill_extrusion_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/line.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/line_gradient.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/raster.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_program.hpp
|
||||
)
|
||||
list(APPEND
|
||||
SRC_FILES
|
||||
@@ -1182,18 +1190,21 @@ if(MBGL_WITH_METAL)
|
||||
${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_impl.hpp
|
||||
${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/offscreen_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/render_pass.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()
|
||||
|
||||
|
||||
@@ -964,6 +964,8 @@ MLN_DRAWABLES_HEADERS = [
|
||||
"include/mbgl/shaders/circle_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/fill_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/fill_extrusion_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/heatmap_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/heatmap_texture_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/layer_ubo.hpp",
|
||||
"include/mbgl/shaders/line_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/raster_layer_ubo.hpp",
|
||||
@@ -976,7 +978,6 @@ MLN_DRAWABLES_GL_SOURCE = [
|
||||
"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",
|
||||
@@ -988,7 +989,6 @@ MLN_DRAWABLES_GL_HEADERS = [
|
||||
"include/mbgl/gl/drawable_gl.hpp",
|
||||
"include/mbgl/gl/drawable_gl_builder.hpp",
|
||||
"include/mbgl/gl/layer_group_gl.hpp",
|
||||
"include/mbgl/gl/render_target_gl.hpp",
|
||||
"include/mbgl/gl/uniform_block_gl.hpp",
|
||||
"include/mbgl/gl/uniform_buffer_gl.hpp",
|
||||
"include/mbgl/gl/vertex_attribute_gl.hpp",
|
||||
@@ -1006,6 +1006,7 @@ MLN_DRAWABLES_MTL_SOURCE = [
|
||||
"src/mbgl/mtl/drawable_builder.cpp",
|
||||
"src/mbgl/mtl/layer_group.cpp",
|
||||
"src/mbgl/mtl/mtl.cpp",
|
||||
"src/mbgl/mtl/offscreen_texture.cpp",
|
||||
"src/mbgl/mtl/renderer_backend.cpp",
|
||||
"src/mbgl/mtl/texture2d.cpp",
|
||||
"src/mbgl/mtl/render_pass.cpp",
|
||||
@@ -1026,6 +1027,7 @@ MLN_DRAWABLES_MTL_HEADERS = [
|
||||
"include/mbgl/mtl/index_buffer_resource.hpp",
|
||||
"include/mbgl/mtl/layer_group.hpp",
|
||||
"include/mbgl/mtl/mtl_fwd.hpp",
|
||||
"include/mbgl/mtl/offscreen_texture.hpp",
|
||||
"include/mbgl/mtl/render_pass.hpp",
|
||||
"include/mbgl/mtl/renderer_backend.hpp",
|
||||
"include/mbgl/mtl/renderable_resource.hpp",
|
||||
@@ -1041,10 +1043,12 @@ MLN_DRAWABLES_MTL_HEADERS = [
|
||||
"include/mbgl/shaders/mtl/circle.hpp",
|
||||
"include/mbgl/shaders/mtl/clipping_mask.hpp",
|
||||
"include/mbgl/shaders/mtl/common.hpp",
|
||||
"include/mbgl/shaders/mtl/fill.hpp",
|
||||
"include/mbgl/shaders/mtl/fill_extrusion.hpp",
|
||||
"include/mbgl/shaders/mtl/fill_extrusion_pattern.hpp",
|
||||
"include/mbgl/shaders/mtl/heatmap.hpp",
|
||||
"include/mbgl/shaders/mtl/heatmap_texture.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",
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/renderer/render_target.hpp>
|
||||
#include <mbgl/gfx/types.hpp>
|
||||
#include <mbgl/gl/object.hpp>
|
||||
#include <mbgl/gl/types.hpp>
|
||||
#include <mbgl/util/size.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
class Context;
|
||||
using UniqueFramebufferPtr = std::shared_ptr<UniqueFramebuffer>;
|
||||
|
||||
class RenderTargetGL final : public RenderTarget {
|
||||
public:
|
||||
RenderTargetGL(Context& context, const Size size, const gfx::TextureChannelDataType type);
|
||||
~RenderTargetGL() override;
|
||||
|
||||
void upload(gfx::UploadPass& uploadPass) override;
|
||||
void render(RenderOrchestrator&, const RenderTree&, PaintParameters&) override;
|
||||
|
||||
private:
|
||||
Context& glContext;
|
||||
UniqueFramebufferPtr framebuffer;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -54,24 +54,6 @@ public:
|
||||
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 {}
|
||||
|
||||
|
||||
23
include/mbgl/mtl/offscreen_texture.hpp
Normal file
23
include/mbgl/mtl/offscreen_texture.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/offscreen_texture.hpp>
|
||||
#include <mbgl/gfx/types.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace mtl {
|
||||
|
||||
class Context;
|
||||
class Texture2D;
|
||||
|
||||
class OffscreenTexture final : public gfx::OffscreenTexture {
|
||||
public:
|
||||
OffscreenTexture(Context&, Size size, gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte);
|
||||
|
||||
bool isRenderable() override;
|
||||
|
||||
PremultipliedImage readStillImage() override;
|
||||
const gfx::Texture2DPtr& getTexture() override;
|
||||
};
|
||||
|
||||
} // namespace mtl
|
||||
} // namespace mbgl
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <Foundation/NSSharedPtr.hpp>
|
||||
#include <Metal/MTLPixelFormat.hpp>
|
||||
#include <Metal/MTLTexture.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -44,6 +45,11 @@ public:
|
||||
|
||||
bool needsUpload() const noexcept override { return !!image; };
|
||||
|
||||
public:
|
||||
gfx::Texture2D& setUsage(MTL::TextureUsage usage_) noexcept;
|
||||
|
||||
MTL::Texture* getMetalTexture() const noexcept;
|
||||
|
||||
void updateSamplerConfiguration() noexcept;
|
||||
|
||||
/// @brief Bind this texture to the specified location
|
||||
@@ -67,6 +73,7 @@ private:
|
||||
Size size{0, 0};
|
||||
gfx::TexturePixelType pixelFormat{gfx::TexturePixelType::RGBA};
|
||||
gfx::TextureChannelDataType channelType{gfx::TextureChannelDataType::UnsignedByte};
|
||||
MTL::TextureUsage usage{MTL::TextureUsageShaderRead};
|
||||
SamplerState samplerState{};
|
||||
|
||||
std::shared_ptr<PremultipliedImage> image{nullptr};
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/types.hpp>
|
||||
#include <mbgl/util/size.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -8,7 +11,9 @@
|
||||
namespace mbgl {
|
||||
|
||||
namespace gfx {
|
||||
class Context;
|
||||
class Texture2D;
|
||||
class OffscreenTexture;
|
||||
class UploadPass;
|
||||
using Texture2DPtr = std::shared_ptr<Texture2D>;
|
||||
} // namespace gfx
|
||||
@@ -23,13 +28,11 @@ using LayerGroupBasePtr = std::shared_ptr<LayerGroupBase>;
|
||||
/// Render target class
|
||||
class RenderTarget {
|
||||
public:
|
||||
virtual ~RenderTarget() = default;
|
||||
|
||||
/// Set the render target texture
|
||||
void setTexture(const gfx::Texture2DPtr& texture_) { texture = std::move(texture_); };
|
||||
RenderTarget(gfx::Context& context, const Size size, const gfx::TextureChannelDataType type);
|
||||
~RenderTarget();
|
||||
|
||||
/// Get the render target texture
|
||||
const gfx::Texture2DPtr& getTexture() const { return texture; };
|
||||
const gfx::Texture2DPtr& getTexture();
|
||||
|
||||
/// @brief Add a layer group to the render target
|
||||
/// @param replace Flag to replace if exists
|
||||
@@ -54,13 +57,14 @@ public:
|
||||
void visitLayerGroups(std::function<void(const LayerGroupBase&)>) const;
|
||||
|
||||
/// Upload the layer groups
|
||||
virtual void upload(gfx::UploadPass& uploadPass) = 0;
|
||||
void upload(gfx::UploadPass& uploadPass);
|
||||
|
||||
/// Render the layer groups
|
||||
virtual void render(RenderOrchestrator&, const RenderTree&, PaintParameters&) = 0;
|
||||
void render(RenderOrchestrator&, const RenderTree&, PaintParameters&);
|
||||
|
||||
protected:
|
||||
gfx::Texture2DPtr texture;
|
||||
gfx::Context& context;
|
||||
std::unique_ptr<gfx::OffscreenTexture> offscreenTexture;
|
||||
using LayerGroupMap = std::map<int32_t, LayerGroupBasePtr>;
|
||||
LayerGroupMap layerGroupsByLayerIndex;
|
||||
};
|
||||
|
||||
41
include/mbgl/shaders/heatmap_layer_ubo.hpp
Normal file
41
include/mbgl/shaders/heatmap_layer_ubo.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/shaders/layer_ubo.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
struct alignas(16) HeatmapDrawableUBO {
|
||||
std::array<float, 4 * 4> matrix;
|
||||
float extrude_scale;
|
||||
std::array<float, 3> padding;
|
||||
};
|
||||
static_assert(sizeof(HeatmapDrawableUBO) % 16 == 0);
|
||||
|
||||
struct alignas(16) HeatmapEvaluatedPropsUBO {
|
||||
float weight;
|
||||
float radius;
|
||||
float intensity;
|
||||
float padding;
|
||||
};
|
||||
static_assert(sizeof(HeatmapEvaluatedPropsUBO) % 16 == 0);
|
||||
|
||||
struct alignas(16) HeatmapInterpolateUBO {
|
||||
float weight_t;
|
||||
float radius_t;
|
||||
std::array<float, 2> padding;
|
||||
};
|
||||
static_assert(sizeof(HeatmapInterpolateUBO) % 16 == 0);
|
||||
|
||||
struct alignas(16) HeatmapPermutationUBO {
|
||||
/* 0 */ Attribute weight;
|
||||
/* 8 */ Attribute radius;
|
||||
/* 16 */ bool overdrawInspector;
|
||||
/* 17 */ uint8_t pad1, pad2, pad3;
|
||||
/* 20 */ float pad4, pad5, pad6;
|
||||
/* 32 */
|
||||
};
|
||||
static_assert(sizeof(HeatmapPermutationUBO) == 2 * 16);
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
19
include/mbgl/shaders/heatmap_texture_layer_ubo.hpp
Normal file
19
include/mbgl/shaders/heatmap_texture_layer_ubo.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/shaders/layer_ubo.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
struct alignas(16) HeatmapTextureDrawableUBO {
|
||||
std::array<float, 4 * 4> matrix;
|
||||
std::array<float, 2> world;
|
||||
float opacity;
|
||||
// overdrawInspector is used only in Metal, while in GL this is a 4 bytes empty padding.
|
||||
bool overdrawInspector;
|
||||
uint8_t pad1, pad2, pad3;
|
||||
};
|
||||
static_assert(sizeof(HeatmapTextureDrawableUBO) % 16 == 0);
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
145
include/mbgl/shaders/mtl/heatmap.hpp
Normal file
145
include/mbgl/shaders/mtl/heatmap.hpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/shaders/heatmap_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::HeatmapShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto name = "HeatmapShader";
|
||||
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_weight"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(3, true, false, HeatmapDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, HeatmapEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, HeatmapInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, HeatmapPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
short2 pos [[attribute(0)]];
|
||||
float2 weight [[attribute(1)]];
|
||||
float2 radius [[attribute(2)]];
|
||||
};
|
||||
|
||||
struct FragmentStage {
|
||||
float4 position [[position, invariant]];
|
||||
float weight;
|
||||
float2 extrude;
|
||||
};
|
||||
|
||||
struct alignas(16) HeatmapDrawableUBO {
|
||||
float4x4 matrix;
|
||||
float extrude_scale;
|
||||
float pad1;
|
||||
float2 pad2;
|
||||
};
|
||||
|
||||
struct alignas(16) HeatmapEvaluatedPropsUBO {
|
||||
float weight;
|
||||
float radius;
|
||||
float intensity;
|
||||
float pad1;
|
||||
};
|
||||
|
||||
struct alignas(16) HeatmapInterpolateUBO {
|
||||
float weight_t;
|
||||
float radius_t;
|
||||
float2 pad1;
|
||||
};
|
||||
|
||||
struct alignas(16) HeatmapPermutationUBO {
|
||||
Attribute weight;
|
||||
Attribute radius;
|
||||
bool overdrawInspector;
|
||||
uint8_t pad1, pad2, pad3;
|
||||
float pad4, pad5, pad6;
|
||||
};
|
||||
|
||||
// Effective "0" in the kernel density texture to adjust the kernel size to;
|
||||
// this empirically chosen number minimizes artifacts on overlapping kernels
|
||||
// for typical heatmap cases (assuming clustered source)
|
||||
constant const float ZERO = 1.0 / 255.0 / 16.0;
|
||||
|
||||
// Gaussian kernel coefficient: 1 / sqrt(2 * PI)
|
||||
#define GAUSS_COEF 0.3989422804014327
|
||||
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const HeatmapDrawableUBO& drawable [[buffer(3)]],
|
||||
device const HeatmapEvaluatedPropsUBO& props [[buffer(4)]],
|
||||
device const HeatmapInterpolateUBO& interp [[buffer(5)]],
|
||||
device const HeatmapPermutationUBO& permutation [[buffer(6)]],
|
||||
device const ExpressionInputsUBO& expr [[buffer(7)]]) {
|
||||
|
||||
const auto weight = valueFor(permutation.weight, props.weight, vertx.weight, interp.weight_t, expr);
|
||||
const auto radius = valueFor(permutation.radius, props.radius, vertx.radius, interp.radius_t, expr);
|
||||
|
||||
// unencode the extrusion vector that we snuck into the a_pos vector
|
||||
float2 unscaled_extrude = float2(glMod(float2(vertx.pos), 2.0) * 2.0 - 1.0);
|
||||
|
||||
// This 'extrude' comes in ranging from [-1, -1], to [1, 1]. We'll use
|
||||
// it to produce the vertices of a square mesh framing the point feature
|
||||
// we're adding to the kernel density texture. We'll also pass it as
|
||||
// a varying, so that the fragment shader can determine the distance of
|
||||
// each fragment from the point feature.
|
||||
// Before we do so, we need to scale it up sufficiently so that the
|
||||
// kernel falls effectively to zero at the edge of the mesh.
|
||||
// That is, we want to know S such that
|
||||
// weight * u_intensity * GAUSS_COEF * exp(-0.5 * 3.0^2 * S^2) == ZERO
|
||||
// Which solves to:
|
||||
// S = sqrt(-2.0 * log(ZERO / (weight * u_intensity * GAUSS_COEF))) / 3.0
|
||||
float S = sqrt(-2.0 * log(ZERO / weight / props.intensity / GAUSS_COEF)) / 3.0;
|
||||
|
||||
// Pass the varying in units of radius
|
||||
float2 extrude = S * unscaled_extrude;
|
||||
|
||||
// Scale by radius and the zoom-based scale factor to produce actual
|
||||
// mesh position
|
||||
float2 scaled_extrude = extrude * radius * drawable.extrude_scale;
|
||||
|
||||
// multiply a_pos by 0.5, since we had it * 2 in order to sneak
|
||||
// in extrusion data
|
||||
float4 pos = float4(floor(float2(vertx.pos) * 0.5) + scaled_extrude, 0, 1);
|
||||
|
||||
float4 position = drawable.matrix * pos;
|
||||
|
||||
return {
|
||||
.position = position,
|
||||
.weight = weight,
|
||||
.extrude = extrude,
|
||||
};
|
||||
}
|
||||
|
||||
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
device const HeatmapEvaluatedPropsUBO& props [[buffer(4)]],
|
||||
device const HeatmapPermutationUBO& permutation [[buffer(6)]]) {
|
||||
|
||||
if (permutation.overdrawInspector) {
|
||||
return half4(1.0);
|
||||
}
|
||||
|
||||
// Kernel density estimation with a Gaussian kernel of size 5x5
|
||||
float d = -0.5 * 3.0 * 3.0 * dot(in.extrude, in.extrude);
|
||||
float val = in.weight * props.intensity * GAUSS_COEF * exp(d);
|
||||
|
||||
return half4(val, 1.0, 1.0, 1.0);
|
||||
}
|
||||
)";
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
77
include/mbgl/shaders/mtl/heatmap_texture.hpp
Normal file
77
include/mbgl/shaders/mtl/heatmap_texture.hpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/shaders/heatmap_texture_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::HeatmapTextureShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto name = "HeatmapTextureShader";
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(1, true, true, HeatmapTextureDrawableUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
{1, "u_color_ramp"},
|
||||
};
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
short2 pos [[attribute(0)]];
|
||||
};
|
||||
|
||||
struct FragmentStage {
|
||||
float4 position [[position, invariant]];
|
||||
float2 pos;
|
||||
};
|
||||
|
||||
struct alignas(16) HeatmapTextureDrawableUBO {
|
||||
float4x4 matrix;
|
||||
float2 world;
|
||||
float opacity;
|
||||
bool overdrawInspector;
|
||||
uint8_t pad1, pad2, pad3;
|
||||
};
|
||||
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const HeatmapTextureDrawableUBO& drawable [[buffer(1)]]) {
|
||||
|
||||
const float2 pos = float2(vertx.pos);
|
||||
const float4 position = drawable.matrix * float4(pos * drawable.world, 0, 1);
|
||||
|
||||
return {
|
||||
.position = position,
|
||||
.pos = pos,
|
||||
};
|
||||
}
|
||||
|
||||
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
device const HeatmapTextureDrawableUBO& drawable [[buffer(1)]],
|
||||
texture2d<float, access::sample> image [[texture(0)]],
|
||||
texture2d<float, access::sample> color_ramp [[texture(1)]],
|
||||
sampler image_sampler [[sampler(0)]],
|
||||
sampler color_ramp_sampler [[sampler(1)]]) {
|
||||
|
||||
if (drawable.overdrawInspector) {
|
||||
return half4(0.0);
|
||||
}
|
||||
|
||||
float t = image.sample(image_sampler, in.pos).r;
|
||||
float4 color = color_ramp.sample(color_ramp_sampler, float2(t, 0.5));
|
||||
return half4(color * drawable.opacity);
|
||||
}
|
||||
)";
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
@@ -7,6 +7,8 @@ namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class Texture;
|
||||
class Texture2D;
|
||||
using Texture2DPtr = std::shared_ptr<Texture2D>;
|
||||
|
||||
class OffscreenTexture : public gfx::Renderable {
|
||||
protected:
|
||||
@@ -19,7 +21,12 @@ public:
|
||||
virtual bool isRenderable() = 0;
|
||||
|
||||
virtual PremultipliedImage readStillImage() = 0;
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
virtual gfx::Texture& getTexture() = 0;
|
||||
#else
|
||||
virtual const gfx::Texture2DPtr& getTexture() = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#include <mbgl/gl/drawable_gl.hpp>
|
||||
#include <mbgl/gl/drawable_gl_builder.hpp>
|
||||
#include <mbgl/gl/layer_group_gl.hpp>
|
||||
#include <mbgl/gl/render_target_gl.hpp>
|
||||
#include <mbgl/gl/uniform_buffer_gl.hpp>
|
||||
#include <mbgl/gl/texture2d.hpp>
|
||||
#include <mbgl/renderer/render_target.hpp>
|
||||
#include <mbgl/shaders/gl/shader_program_gl.hpp>
|
||||
#endif
|
||||
|
||||
@@ -510,10 +510,10 @@ gfx::Texture2DPtr Context::createTexture2D() {
|
||||
}
|
||||
|
||||
RenderTargetPtr Context::createRenderTarget(const Size size, const gfx::TextureChannelDataType type) {
|
||||
return std::make_shared<gl::RenderTargetGL>(*this, size, type);
|
||||
return std::make_shared<RenderTarget>(*this, size, type);
|
||||
}
|
||||
|
||||
UniqueFramebuffer Context::createFramebuffer(const gfx::Texture2D& color) {
|
||||
Framebuffer Context::createFramebuffer(const gfx::Texture2D& color) {
|
||||
auto fbo = createFramebuffer();
|
||||
bindFramebuffer = fbo;
|
||||
MBGL_CHECK_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER,
|
||||
@@ -522,7 +522,7 @@ UniqueFramebuffer Context::createFramebuffer(const gfx::Texture2D& color) {
|
||||
static_cast<const gl::Texture2D&>(color).getTextureID(),
|
||||
0));
|
||||
checkFramebuffer();
|
||||
return fbo;
|
||||
return {color.getSize(), std::move(fbo)};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
|
||||
RenderTargetPtr createRenderTarget(const Size size, const gfx::TextureChannelDataType type) override;
|
||||
|
||||
UniqueFramebuffer createFramebuffer(const gfx::Texture2D& color);
|
||||
Framebuffer createFramebuffer(const gfx::Texture2D& color);
|
||||
|
||||
void resetState(gfx::DepthMode depthMode, gfx::ColorMode colorMode) override;
|
||||
|
||||
@@ -172,9 +172,8 @@ private:
|
||||
State<value::CullFaceSide> cullFaceSide;
|
||||
State<value::CullFaceWinding> cullFaceWinding;
|
||||
|
||||
std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(Size, gfx::TextureChannelDataType) override;
|
||||
|
||||
public:
|
||||
std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(Size, gfx::TextureChannelDataType) override;
|
||||
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,
|
||||
gfx::TexturePixelType,
|
||||
gfx::TextureChannelDataType) override;
|
||||
|
||||
@@ -13,15 +13,28 @@ public:
|
||||
size(size_),
|
||||
type(type_) {
|
||||
assert(!size.isEmpty());
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
texture = context.createTexture2D();
|
||||
texture->setSize(size);
|
||||
texture->setFormat(gfx::TexturePixelType::RGBA, type);
|
||||
texture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Nearest, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
#endif
|
||||
}
|
||||
|
||||
~OffscreenTextureResource() noexcept override = default;
|
||||
|
||||
void bind() override {
|
||||
if (!framebuffer) {
|
||||
#if MLN_LEGACY_RENDERER
|
||||
assert(!texture);
|
||||
texture = context.createTexture(size, gfx::TexturePixelType::RGBA, type);
|
||||
framebuffer = context.createFramebuffer(*texture);
|
||||
#else
|
||||
assert(texture);
|
||||
texture->create();
|
||||
framebuffer = context.createFramebuffer(*texture);
|
||||
#endif
|
||||
} else {
|
||||
context.bindFramebuffer = framebuffer->framebuffer;
|
||||
}
|
||||
@@ -37,15 +50,26 @@ public:
|
||||
return context.readFramebuffer<PremultipliedImage>(size);
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
gfx::Texture& getTexture() {
|
||||
assert(texture);
|
||||
return *texture;
|
||||
}
|
||||
#else
|
||||
gfx::Texture2DPtr& getTexture() {
|
||||
assert(texture);
|
||||
return texture;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
gl::Context& context;
|
||||
const Size size;
|
||||
#if MLN_LEGACY_RENDERER
|
||||
std::optional<gfx::Texture> texture;
|
||||
#else
|
||||
gfx::Texture2DPtr texture;
|
||||
#endif
|
||||
const gfx::TextureChannelDataType type;
|
||||
std::optional<gl::Framebuffer> framebuffer;
|
||||
};
|
||||
@@ -66,9 +90,15 @@ PremultipliedImage OffscreenTexture::readStillImage() {
|
||||
return getResource<OffscreenTextureResource>().readStillImage();
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
gfx::Texture& OffscreenTexture::getTexture() {
|
||||
return getResource<OffscreenTextureResource>().getTexture();
|
||||
}
|
||||
#else
|
||||
const gfx::Texture2DPtr& OffscreenTexture::getTexture() {
|
||||
return getResource<OffscreenTextureResource>().getTexture();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -17,7 +17,12 @@ public:
|
||||
bool isRenderable() override;
|
||||
|
||||
PremultipliedImage readStillImage() override;
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
gfx::Texture& getTexture() override;
|
||||
#else
|
||||
const gfx::Texture2DPtr& getTexture() override;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
#include <mbgl/gl/render_target_gl.hpp>
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/gl/framebuffer.hpp>
|
||||
#include <mbgl/platform/gl_functions.hpp>
|
||||
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_orchestrator.hpp>
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/renderer/render_tree.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
using namespace platform;
|
||||
|
||||
RenderTargetGL::RenderTargetGL(Context& context, const Size size, const gfx::TextureChannelDataType type)
|
||||
: glContext(context) {
|
||||
texture = glContext.createTexture2D();
|
||||
texture->setSize(size);
|
||||
texture->setFormat(gfx::TexturePixelType::RGBA, type);
|
||||
texture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
}
|
||||
|
||||
RenderTargetGL::~RenderTargetGL() {
|
||||
if (framebuffer) {
|
||||
MBGL_CHECK_ERROR(glDeleteFramebuffers(1, &framebuffer->get()));
|
||||
framebuffer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTargetGL::upload(gfx::UploadPass& uploadPass) {
|
||||
visitLayerGroups(([&](LayerGroupBase& layerGroup) { layerGroup.upload(uploadPass); }));
|
||||
}
|
||||
|
||||
void RenderTargetGL::render(RenderOrchestrator& orchestrator,
|
||||
const RenderTree& renderTree,
|
||||
PaintParameters& parameters) {
|
||||
texture->create();
|
||||
if (!framebuffer) {
|
||||
framebuffer = std::make_shared<UniqueFramebuffer>(glContext.createFramebuffer(*texture));
|
||||
}
|
||||
|
||||
glContext.bindFramebuffer = *framebuffer;
|
||||
glContext.activeTextureUnit = 0;
|
||||
glContext.scissorTest = false;
|
||||
glContext.viewport = {0, 0, texture->getSize()};
|
||||
glContext.clear(Color{0.0f, 0.0f, 0.0f, 1.0f}, {}, {});
|
||||
|
||||
// Run layer tweakers to update any dynamic elements
|
||||
visitLayerGroups([&](LayerGroupBase& layerGroup) {
|
||||
if (layerGroup.getLayerTweaker()) {
|
||||
layerGroup.getLayerTweaker()->execute(layerGroup, renderTree, parameters);
|
||||
}
|
||||
});
|
||||
|
||||
// draw layer groups, opaque pass
|
||||
parameters.pass = RenderPass::Opaque;
|
||||
parameters.currentLayer = 0;
|
||||
parameters.depthRangeSize = 1 - (numLayerGroups() + 2) * parameters.numSublayers * PaintParameters::depthEpsilon;
|
||||
|
||||
visitLayerGroups([&](LayerGroupBase& layerGroup) {
|
||||
layerGroup.render(orchestrator, parameters);
|
||||
parameters.currentLayer++;
|
||||
});
|
||||
|
||||
// draw layer groups, translucent pass
|
||||
parameters.pass = RenderPass::Translucent;
|
||||
parameters.currentLayer = static_cast<int32_t>(numLayerGroups()) - 1;
|
||||
parameters.depthRangeSize = 1 - (numLayerGroups() + 2) * parameters.numSublayers * PaintParameters::depthEpsilon;
|
||||
|
||||
visitLayerGroups([&](LayerGroupBase& layerGroup) {
|
||||
layerGroup.render(orchestrator, parameters);
|
||||
if (parameters.currentLayer != 0) {
|
||||
parameters.currentLayer--;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <mbgl/mtl/command_encoder.hpp>
|
||||
#include <mbgl/mtl/drawable_builder.hpp>
|
||||
#include <mbgl/mtl/layer_group.hpp>
|
||||
#include <mbgl/mtl/offscreen_texture.hpp>
|
||||
#include <mbgl/mtl/renderer_backend.hpp>
|
||||
#include <mbgl/mtl/renderable_resource.hpp>
|
||||
#include <mbgl/mtl/texture2d.hpp>
|
||||
@@ -13,6 +14,7 @@
|
||||
#include <mbgl/mtl/upload_pass.hpp>
|
||||
#include <mbgl/programs/program_parameters.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_target.hpp>
|
||||
#include <mbgl/shaders/mtl/shader_program.hpp>
|
||||
#include <mbgl/util/traits.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
@@ -170,8 +172,7 @@ gfx::Texture2DPtr Context::createTexture2D() {
|
||||
}
|
||||
|
||||
RenderTargetPtr Context::createRenderTarget(const Size size, const gfx::TextureChannelDataType type) {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
return std::make_shared<RenderTarget>(*this, size, type);
|
||||
}
|
||||
|
||||
void Context::resetState(gfx::DepthMode depthMode, gfx::ColorMode colorMode) {}
|
||||
@@ -188,9 +189,8 @@ bool Context::emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr& buffer, const
|
||||
|
||||
void Context::setDirtyState() {}
|
||||
|
||||
std::unique_ptr<gfx::OffscreenTexture> Context::createOffscreenTexture(Size, gfx::TextureChannelDataType) {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
std::unique_ptr<gfx::OffscreenTexture> Context::createOffscreenTexture(Size size, gfx::TextureChannelDataType type) {
|
||||
return std::make_unique<OffscreenTexture>(*this, size, type);
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::TextureResource> Context::createTextureResource(Size,
|
||||
|
||||
95
src/mbgl/mtl/offscreen_texture.cpp
Normal file
95
src/mbgl/mtl/offscreen_texture.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include <mbgl/mtl/offscreen_texture.hpp>
|
||||
#include <mbgl/mtl/context.hpp>
|
||||
#include <mbgl/mtl/renderable_resource.hpp>
|
||||
#include <mbgl/mtl/renderer_backend.hpp>
|
||||
#include <mbgl/mtl/texture2d.hpp>
|
||||
|
||||
#include <Metal/Metal.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace mtl {
|
||||
|
||||
class OffscreenTextureResource final : public RenderableResource {
|
||||
public:
|
||||
OffscreenTextureResource(Context& context_, const Size size_, const gfx::TextureChannelDataType type_)
|
||||
: context(context_),
|
||||
size(size_),
|
||||
type(type_) {
|
||||
assert(!size.isEmpty());
|
||||
texture = context.createTexture2D();
|
||||
texture->setSize(size);
|
||||
texture->setFormat(gfx::TexturePixelType::RGBA, type);
|
||||
texture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Nearest, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
static_cast<Texture2D*>(texture.get())
|
||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||
}
|
||||
|
||||
~OffscreenTextureResource() noexcept override = default;
|
||||
|
||||
void bind() override {
|
||||
assert(context.getBackend().getCommandQueue());
|
||||
commandBuffer = NS::RetainPtr(context.getBackend().getCommandQueue()->commandBuffer());
|
||||
texture->create();
|
||||
}
|
||||
|
||||
void swap() override {
|
||||
assert(commandBuffer);
|
||||
commandBuffer->commit();
|
||||
commandBuffer->waitUntilCompleted();
|
||||
commandBuffer.reset();
|
||||
}
|
||||
|
||||
PremultipliedImage readStillImage() {
|
||||
assert(false);
|
||||
return PremultipliedImage();
|
||||
}
|
||||
|
||||
gfx::Texture2DPtr& getTexture() {
|
||||
assert(texture);
|
||||
return texture;
|
||||
}
|
||||
|
||||
const RendererBackend& getBackend() const override { return context.getBackend(); }
|
||||
|
||||
const MTLCommandBufferPtr& getCommandBuffer() const override { return commandBuffer; }
|
||||
|
||||
MTLBlitPassDescriptorPtr getUploadPassDescriptor() const override {
|
||||
assert(false);
|
||||
return NS::TransferPtr(MTL::BlitPassDescriptor::alloc()->init());
|
||||
}
|
||||
|
||||
MTLRenderPassDescriptorPtr getRenderPassDescriptor() const override {
|
||||
auto renderPassDescriptor = NS::TransferPtr(MTL::RenderPassDescriptor::alloc()->init());
|
||||
if (auto* colorTarget = renderPassDescriptor->colorAttachments()->object(0)) {
|
||||
colorTarget->setTexture(static_cast<Texture2D*>(texture.get())->getMetalTexture());
|
||||
}
|
||||
return renderPassDescriptor;
|
||||
}
|
||||
|
||||
private:
|
||||
Context& context;
|
||||
const Size size;
|
||||
const gfx::TextureChannelDataType type;
|
||||
gfx::Texture2DPtr texture;
|
||||
MTLCommandBufferPtr commandBuffer;
|
||||
};
|
||||
|
||||
OffscreenTexture::OffscreenTexture(Context& context, const Size size_, const gfx::TextureChannelDataType type)
|
||||
: gfx::OffscreenTexture(size, std::make_unique<OffscreenTextureResource>(context, size_, type)) {}
|
||||
|
||||
bool OffscreenTexture::isRenderable() {
|
||||
assert(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
PremultipliedImage OffscreenTexture::readStillImage() {
|
||||
return getResource<OffscreenTextureResource>().readStillImage();
|
||||
}
|
||||
|
||||
const gfx::Texture2DPtr& OffscreenTexture::getTexture() {
|
||||
return getResource<OffscreenTextureResource>().getTexture();
|
||||
}
|
||||
|
||||
} // namespace mtl
|
||||
} // namespace mbgl
|
||||
@@ -15,11 +15,13 @@
|
||||
#include <mbgl/shaders/mtl/background_pattern.hpp>
|
||||
#include <mbgl/shaders/mtl/circle.hpp>
|
||||
#include <mbgl/shaders/mtl/clipping_mask.hpp>
|
||||
#include <mbgl/shaders/mtl/fill.hpp>
|
||||
#include <mbgl/shaders/mtl/fill_extrusion.hpp>
|
||||
#include <mbgl/shaders/mtl/fill_extrusion_pattern.hpp>
|
||||
#include <mbgl/shaders/mtl/heatmap.hpp>
|
||||
#include <mbgl/shaders/mtl/heatmap_texture.hpp>
|
||||
#include <mbgl/shaders/mtl/line.hpp>
|
||||
#include <mbgl/shaders/mtl/line_gradient.hpp>
|
||||
#include <mbgl/shaders/mtl/fill.hpp>
|
||||
#include <mbgl/shaders/mtl/raster.hpp>
|
||||
|
||||
#include <cassert>
|
||||
@@ -116,24 +118,21 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramPar
|
||||
shaders::BuiltIn::BackgroundPatternShader,
|
||||
shaders::BuiltIn::CircleShader,
|
||||
shaders::BuiltIn::ClippingMaskProgram,
|
||||
shaders::BuiltIn::LineShader,
|
||||
shaders::BuiltIn::LineGradientShader,
|
||||
shaders::BuiltIn::RasterShader,
|
||||
shaders::BuiltIn::FillShader,
|
||||
shaders::BuiltIn::FillOutlineShader,
|
||||
shaders::BuiltIn::FillOutlinePatternShader,
|
||||
shaders::BuiltIn::FillPatternShader/*,
|
||||
shaders::BuiltIn::LineSDFShader,
|
||||
shaders::BuiltIn::LinePatternShader,
|
||||
shaders::BuiltIn::LineGradientShader,
|
||||
shaders::BuiltIn::FillPatternShader,
|
||||
shaders::BuiltIn::FillExtrusionShader,
|
||||
shaders::BuiltIn::FillExtrusionPatternShader,
|
||||
shaders::BuiltIn::HeatmapShader,
|
||||
shaders::BuiltIn::HeatmapTextureShader,
|
||||
shaders::BuiltIn::LineShader,
|
||||
shaders::BuiltIn::LineGradientShader,
|
||||
shaders::BuiltIn::RasterShader/*,
|
||||
shaders::BuiltIn::LineSDFShader,
|
||||
shaders::BuiltIn::LinePatternShader,
|
||||
shaders::BuiltIn::HillshadePrepareShader,
|
||||
shaders::BuiltIn::HillshadeShader*/,
|
||||
shaders::BuiltIn::FillExtrusionShader,
|
||||
shaders::BuiltIn::FillExtrusionPatternShader/*,
|
||||
shaders::BuiltIn::HillshadeShader,
|
||||
shaders::BuiltIn::SymbolIconShader,
|
||||
shaders::BuiltIn::SymbolSDFTextShader,
|
||||
shaders::BuiltIn::SymbolSDFIconShader,
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <Metal/MTLDevice.hpp>
|
||||
#include <Metal/MTLRenderCommandEncoder.hpp>
|
||||
#include <Metal/MTLSampler.hpp>
|
||||
#include <Metal/MTLTexture.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace mtl {
|
||||
@@ -113,6 +112,7 @@ void Texture2D::createMetalTexture() noexcept {
|
||||
// Create a new texture object
|
||||
if (auto textureDescriptor = NS::RetainPtr(
|
||||
MTL::TextureDescriptor::texture2DDescriptor(format, size.width, size.height, /*mipmapped=*/false))) {
|
||||
textureDescriptor->setUsage(usage);
|
||||
metalTexture = context.createMetalTexture(std::move(textureDescriptor));
|
||||
}
|
||||
|
||||
@@ -131,6 +131,17 @@ void Texture2D::create() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Texture2D& Texture2D::setUsage(MTL::TextureUsage usage_) noexcept {
|
||||
usage = usage_;
|
||||
textureDirty = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MTL::Texture* Texture2D::getMetalTexture() const noexcept {
|
||||
assert(metalTexture);
|
||||
return metalTexture.get();
|
||||
}
|
||||
|
||||
void Texture2D::updateSamplerConfiguration() noexcept {
|
||||
auto samplerDescriptor = NS::RetainPtr(MTL::SamplerDescriptor::alloc()->init());
|
||||
samplerDescriptor->setMinFilter(samplerState.filter == gfx::TextureFilterType::Nearest
|
||||
|
||||
@@ -6,31 +6,24 @@
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/renderer/render_tree.hpp>
|
||||
#include <mbgl/shaders/heatmap_layer_ubo.hpp>
|
||||
#include <mbgl/style/layers/heatmap_layer_properties.hpp>
|
||||
#include <mbgl/util/convert.hpp>
|
||||
#include <mbgl/util/string_indexer.hpp>
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
#include <mbgl/shaders/mtl/heatmap.hpp>
|
||||
#endif
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
|
||||
struct alignas(16) HeatmapDrawableUBO {
|
||||
std::array<float, 4 * 4> matrix;
|
||||
float extrude_scale;
|
||||
std::array<float, 3> padding;
|
||||
};
|
||||
static_assert(sizeof(HeatmapDrawableUBO) % 16 == 0);
|
||||
|
||||
struct alignas(16) HeatmapEvaluatedPropsUBO {
|
||||
float weight;
|
||||
float radius;
|
||||
float intensity;
|
||||
float padding;
|
||||
};
|
||||
static_assert(sizeof(HeatmapEvaluatedPropsUBO) % 16 == 0);
|
||||
using namespace shaders;
|
||||
|
||||
static const StringIdentity idHeatmapDrawableUBOName = StringIndexer::get("HeatmapDrawableUBO");
|
||||
static const StringIdentity idHeatmapEvaluatedPropsUBOName = StringIndexer::get("HeatmapEvaluatedPropsUBO");
|
||||
static const StringIdentity idHeatmapPermutationUBOName = StringIndexer::get("HeatmapPermutationUBO");
|
||||
static const StringIdentity idExpressionInputsUBOName = StringIndexer::get("ExpressionInputsUBO");
|
||||
|
||||
void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const RenderTree& renderTree,
|
||||
@@ -47,6 +40,40 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
const auto zoom = parameters.state.getZoom();
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
using ShaderClass = shaders::ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal>;
|
||||
if (propertiesChanged) {
|
||||
const auto source = [this](const std::string_view& attrName) {
|
||||
return hasPropertyAsUniform(attrName) ? AttributeSource::Constant : AttributeSource::PerVertex;
|
||||
};
|
||||
|
||||
const HeatmapPermutationUBO permutationUBO = {
|
||||
/* .weight = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
|
||||
/* .radius = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
/* .pad1/2/3 = */ 0,
|
||||
0,
|
||||
0,
|
||||
/* .pad4/5/6 = */ 0,
|
||||
0,
|
||||
0};
|
||||
|
||||
if (permutationUniformBuffer) {
|
||||
permutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
|
||||
} else {
|
||||
permutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
|
||||
}
|
||||
|
||||
propertiesChanged = false;
|
||||
}
|
||||
if (!expressionUniformBuffer) {
|
||||
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
|
||||
expressionUniformBuffer = context.createUniformBuffer(&expressionUBO, sizeof(expressionUBO));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!evaluatedPropsUniformBuffer) {
|
||||
const HeatmapEvaluatedPropsUBO evaluatedPropsUBO = {
|
||||
/* .weight = */ evaluated.get<HeatmapWeight>().constantOr(HeatmapWeight::defaultValue()),
|
||||
@@ -76,10 +103,15 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
inViewportPixelUnits);
|
||||
const HeatmapDrawableUBO drawableUBO = {
|
||||
/* .matrix = */ util::cast<float>(matrix),
|
||||
/* .extrude_scale = */ tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/* .extrude_scale = */ tileID.pixelsToTileUnits(1.0f, static_cast<float>(zoom)),
|
||||
/* .padding = */ {0}};
|
||||
|
||||
uniforms.createOrUpdate(idHeatmapDrawableUBOName, &drawableUBO, context);
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
uniforms.addOrReplace(idHeatmapPermutationUBOName, permutationUniformBuffer);
|
||||
uniforms.addOrReplace(idExpressionInputsUBOName, expressionUniformBuffer);
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,11 @@ public:
|
||||
|
||||
protected:
|
||||
gfx::UniformBufferPtr evaluatedPropsUniformBuffer;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
gfx::UniformBufferPtr permutationUniformBuffer;
|
||||
gfx::UniformBufferPtr expressionUniformBuffer;
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/renderer/render_tree.hpp>
|
||||
#include <mbgl/shaders/heatmap_texture_layer_ubo.hpp>
|
||||
#include <mbgl/style/layers/heatmap_layer_properties.hpp>
|
||||
#include <mbgl/util/convert.hpp>
|
||||
#include <mbgl/util/string_indexer.hpp>
|
||||
@@ -13,14 +14,7 @@
|
||||
namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
|
||||
struct alignas(16) HeatmapTextureDrawableUBO {
|
||||
std::array<float, 4 * 4> matrix;
|
||||
std::array<float, 2> world;
|
||||
float opacity;
|
||||
float padding;
|
||||
};
|
||||
static_assert(sizeof(HeatmapTextureDrawableUBO) % 16 == 0);
|
||||
using namespace shaders;
|
||||
|
||||
static const StringIdentity idHeatmapTextureDrawableUBOName = StringIndexer::get("HeatmapTextureDrawableUBO");
|
||||
|
||||
@@ -41,12 +35,15 @@ void HeatmapTextureLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
|
||||
const auto& size = parameters.staticData.backendSize;
|
||||
mat4 viewportMat;
|
||||
matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
|
||||
matrix::ortho(viewportMat, 0, size.width, size.height, 0, -1, 1);
|
||||
const HeatmapTextureDrawableUBO drawableUBO = {
|
||||
/* .matrix = */ util::cast<float>(viewportMat),
|
||||
/* .world = */ {static_cast<float>(size.width), static_cast<float>(size.height)},
|
||||
/* .opacity = */ evaluated.get<HeatmapOpacity>(),
|
||||
/* .padding = */ 0};
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
/* .pad1 = */ 0,
|
||||
/* .pad2 = */ 0,
|
||||
/* .pad3 = */ 0};
|
||||
|
||||
drawable.mutableUniformBuffers().createOrUpdate(
|
||||
idHeatmapTextureDrawableUBOName, &drawableUBO, parameters.context);
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <mbgl/renderer/layers/heatmap_texture_layer_tweaker.hpp>
|
||||
#include <mbgl/renderer/layer_group.hpp>
|
||||
#include <mbgl/renderer/render_target.hpp>
|
||||
#include <mbgl/shaders/heatmap_layer_ubo.hpp>
|
||||
#include <mbgl/renderer/update_parameters.hpp>
|
||||
#include <mbgl/shaders/shader_program_base.hpp>
|
||||
#include <mbgl/gfx/drawable_builder.hpp>
|
||||
#include <mbgl/gfx/shader_group.hpp>
|
||||
@@ -68,13 +70,8 @@ void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters
|
||||
evaluatedProperties = std::move(properties);
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
if (renderTarget) {
|
||||
renderTarget->getLayerGroup(0)->setLayerTweaker(
|
||||
std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties));
|
||||
}
|
||||
if (layerGroup) {
|
||||
layerGroup->setLayerTweaker(std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties));
|
||||
}
|
||||
updateLayerTweaker();
|
||||
updateLayerTextureTweaker();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -86,13 +83,13 @@ bool RenderHeatmapLayer::hasCrossfade() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
void RenderHeatmapLayer::upload(gfx::UploadPass& uploadPass) {
|
||||
if (!colorRampTexture) {
|
||||
colorRampTexture = uploadPass.createTexture(*colorRamp, gfx::TextureChannelDataType::UnsignedByte);
|
||||
}
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
void RenderHeatmapLayer::render(PaintParameters& parameters) {
|
||||
assert(renderTiles);
|
||||
if (parameters.pass == RenderPass::Opaque) {
|
||||
@@ -265,13 +262,6 @@ void RenderHeatmapLayer::removeAllDrawables() {
|
||||
|
||||
namespace {
|
||||
|
||||
struct alignas(16) HeatmapInterpolateUBO {
|
||||
float weight_t;
|
||||
float radius_t;
|
||||
std::array<float, 2> padding;
|
||||
};
|
||||
static_assert(sizeof(HeatmapInterpolateUBO) % 16 == 0);
|
||||
|
||||
constexpr auto HeatmapShaderGroupName = "HeatmapShader";
|
||||
constexpr auto HeatmapTextureShaderGroupName = "HeatmapTextureShader";
|
||||
static const StringIdentity idHeatmapInterpolateUBOName = StringIndexer::get("HeatmapInterpolateUBO");
|
||||
@@ -281,10 +271,33 @@ static const StringIdentity idTexColorRampName = StringIndexer::get("u_color_ram
|
||||
|
||||
} // namespace
|
||||
|
||||
using namespace shaders;
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
void RenderHeatmapLayer::updateLayerTweaker() {
|
||||
if (renderTarget) {
|
||||
tweaker = std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties);
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
tweaker->enableOverdrawInspector(overdrawInspector);
|
||||
renderTarget->getLayerGroup(0)->setLayerTweaker(tweaker);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderHeatmapLayer::updateLayerTextureTweaker() {
|
||||
if (layerGroup) {
|
||||
textureTweaker = std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties);
|
||||
textureTweaker->enableOverdrawInspector(overdrawInspector);
|
||||
layerGroup->setLayerTweaker(textureTweaker);
|
||||
}
|
||||
}
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
||||
gfx::Context& context,
|
||||
const TransformState& state,
|
||||
const std::shared_ptr<UpdateParameters>&,
|
||||
const std::shared_ptr<UpdateParameters>& updateParameters,
|
||||
[[maybe_unused]] const RenderTree& renderTree,
|
||||
UniqueChangeRequestVec& changes) {
|
||||
std::unique_lock<std::mutex> guard(mutex);
|
||||
@@ -310,8 +323,8 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
||||
if (!tileLayerGroup) {
|
||||
return;
|
||||
}
|
||||
tileLayerGroup->setLayerTweaker(std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties));
|
||||
renderTarget->addLayerGroup(tileLayerGroup, /*replace=*/true);
|
||||
updateLayerTweaker();
|
||||
}
|
||||
|
||||
if (renderTarget->getTexture()->getSize() != size) {
|
||||
@@ -328,6 +341,15 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
||||
return;
|
||||
}
|
||||
|
||||
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
|
||||
if (overdrawInspector != overdraw) {
|
||||
overdrawInspector = overdraw;
|
||||
if (tweaker) {
|
||||
tweaker->enableOverdrawInspector(overdrawInspector);
|
||||
textureTweaker->enableOverdrawInspector(overdrawInspector);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::DrawableBuilder> heatmapBuilder;
|
||||
constexpr auto renderPass = RenderPass::Translucent;
|
||||
|
||||
@@ -376,18 +398,25 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
||||
|
||||
gfx::VertexAttributeArray heatmapVertexAttrs;
|
||||
|
||||
const auto propertiesAsUniforms =
|
||||
const auto propertiesAsUniforms_ =
|
||||
heatmapVertexAttrs.readDataDrivenPaintProperties<HeatmapWeight, HeatmapRadius>(paintPropertyBinders,
|
||||
evaluated);
|
||||
|
||||
if (!heatmapShaderGroup) {
|
||||
continue;
|
||||
}
|
||||
const auto heatmapShader = heatmapShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
|
||||
const auto heatmapShader = heatmapShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
|
||||
if (!heatmapShader) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
propertiesAsUniforms = std::move(propertiesAsUniforms_);
|
||||
if (tweaker) {
|
||||
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
}
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
if (const auto& attr = heatmapVertexAttrs.add(idVertexAttribName)) {
|
||||
attr->setSharedRawData(bucket.sharedVertices,
|
||||
offsetof(HeatmapLayoutVertex, a1),
|
||||
@@ -425,8 +454,8 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
||||
if (!layerGroup_) {
|
||||
return;
|
||||
}
|
||||
layerGroup_->setLayerTweaker(std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties));
|
||||
setLayerGroup(std::move(layerGroup_), changes);
|
||||
updateLayerTextureTweaker();
|
||||
}
|
||||
|
||||
if (!heatmapTextureShader) {
|
||||
|
||||
@@ -11,6 +11,13 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
class HeatmapLayerTweaker;
|
||||
class HeatmapTextureLayerTweaker;
|
||||
using HeatmapLayerTweakerPtr = std::shared_ptr<HeatmapLayerTweaker>;
|
||||
using HeatmapTextureLayerTweakerPtr = std::shared_ptr<HeatmapTextureLayerTweaker>;
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
class RenderHeatmapLayer final : public RenderLayer {
|
||||
public:
|
||||
explicit RenderHeatmapLayer(Immutable<style::HeatmapLayer::Impl>);
|
||||
@@ -34,12 +41,17 @@ private:
|
||||
void evaluate(const PropertyEvaluationParameters&) override;
|
||||
bool hasTransition() const override;
|
||||
bool hasCrossfade() const override;
|
||||
void upload(gfx::UploadPass&) override;
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
void upload(gfx::UploadPass&) override;
|
||||
void render(PaintParameters&) override;
|
||||
#endif
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
void updateLayerTweaker();
|
||||
void updateLayerTextureTweaker();
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
bool queryIntersectsFeature(const GeometryCoordinates&,
|
||||
const GeometryTileFeature&,
|
||||
float,
|
||||
@@ -77,6 +89,14 @@ private:
|
||||
|
||||
using TextureVertexVector = gfx::VertexVector<HeatmapTextureLayoutVertex>;
|
||||
std::shared_ptr<TextureVertexVector> sharedTextureVertices;
|
||||
|
||||
HeatmapLayerTweakerPtr tweaker;
|
||||
HeatmapTextureLayerTweakerPtr textureTweaker;
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
std::vector<std::string> propertiesAsUniforms;
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
bool overdrawInspector = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
#include <mbgl/renderer/render_target.hpp>
|
||||
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/offscreen_texture.hpp>
|
||||
#include <mbgl/gfx/render_pass.hpp>
|
||||
#include <mbgl/renderer/layer_group.hpp>
|
||||
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
RenderTarget::RenderTarget(gfx::Context& context_, const Size size, const gfx::TextureChannelDataType type)
|
||||
: context(context_) {
|
||||
offscreenTexture = context.createOffscreenTexture(size, type);
|
||||
}
|
||||
|
||||
RenderTarget::~RenderTarget() {}
|
||||
|
||||
const gfx::Texture2DPtr& RenderTarget::getTexture() {
|
||||
return offscreenTexture->getTexture();
|
||||
};
|
||||
|
||||
bool RenderTarget::addLayerGroup(LayerGroupBasePtr layerGroup, const bool replace) {
|
||||
const auto index = layerGroup->getLayerIndex();
|
||||
const auto result = layerGroupsByLayerIndex.insert(std::make_pair(index, LayerGroupBasePtr{}));
|
||||
@@ -60,4 +75,45 @@ void RenderTarget::visitLayerGroups(std::function<void(const LayerGroupBase&)> f
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTarget::upload(gfx::UploadPass& uploadPass) {
|
||||
visitLayerGroups(([&](LayerGroupBase& layerGroup) { layerGroup.upload(uploadPass); }));
|
||||
}
|
||||
|
||||
void RenderTarget::render(RenderOrchestrator& orchestrator, const RenderTree& renderTree, PaintParameters& parameters) {
|
||||
parameters.renderPass = parameters.encoder->createRenderPass(
|
||||
"render target", {*offscreenTexture, Color{0.0f, 0.0f, 0.0f, 1.0f}, {}, {}});
|
||||
|
||||
// Run layer tweakers to update any dynamic elements
|
||||
visitLayerGroups([&](LayerGroupBase& layerGroup) {
|
||||
if (layerGroup.getLayerTweaker()) {
|
||||
layerGroup.getLayerTweaker()->execute(layerGroup, renderTree, parameters);
|
||||
}
|
||||
});
|
||||
|
||||
// draw layer groups, opaque pass
|
||||
parameters.pass = RenderPass::Opaque;
|
||||
parameters.currentLayer = 0;
|
||||
parameters.depthRangeSize = 1 - (numLayerGroups() + 2) * parameters.numSublayers * PaintParameters::depthEpsilon;
|
||||
|
||||
visitLayerGroups([&](LayerGroupBase& layerGroup) {
|
||||
layerGroup.render(orchestrator, parameters);
|
||||
parameters.currentLayer++;
|
||||
});
|
||||
|
||||
// draw layer groups, translucent pass
|
||||
parameters.pass = RenderPass::Translucent;
|
||||
parameters.currentLayer = static_cast<int32_t>(numLayerGroups()) - 1;
|
||||
parameters.depthRangeSize = 1 - (numLayerGroups() + 2) * parameters.numSublayers * PaintParameters::depthEpsilon;
|
||||
|
||||
visitLayerGroups([&](LayerGroupBase& layerGroup) {
|
||||
layerGroup.render(orchestrator, parameters);
|
||||
if (parameters.currentLayer != 0) {
|
||||
parameters.currentLayer--;
|
||||
}
|
||||
});
|
||||
|
||||
parameters.renderPass.reset();
|
||||
parameters.encoder->present(*offscreenTexture);
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
Reference in New Issue
Block a user